sord 1.0.0 → 3.0.1

Sign up to get free protection for your applications and to get access to all the features.
File without changes
@@ -37,11 +37,21 @@ module Sord
37
37
  end
38
38
  Sord::Logging.enabled_types = Sord::Logging::AVAILABLE_TYPES - blacklist
39
39
  end
40
+
41
+ if !(options[:rbi] || options[:rbs])
42
+ Sord::Logging.error('No output format given; please specify --rbi or --rbs')
43
+ exit 1
44
+ end
45
+
46
+ if (options[:rbi] && options[:rbs])
47
+ Sord::Logging.error('You cannot specify both --rbi and --rbs; please use only one')
48
+ exit 1
49
+ end
40
50
 
41
51
  if options[:regenerate]
42
52
  begin
43
53
  Sord::Logging.info('Running YARD...')
44
- Bundler.with_clean_env do
54
+ Sord::ParlourPlugin.with_clean_env do
45
55
  system('bundle exec yard')
46
56
  end
47
57
  rescue Errno::ENOENT
@@ -52,12 +62,23 @@ module Sord
52
62
  end
53
63
  end
54
64
 
65
+ options[:mode] = \
66
+ if options[:rbi] then :rbi elsif options[:rbs] then :rbs end
55
67
  options[:parlour] = @parlour
56
68
  options[:root] = root
57
69
 
58
- Sord::RbiGenerator.new(options).run
70
+ Sord::Generator.new(options).run
59
71
 
60
72
  true
61
73
  end
74
+
75
+ def self.with_clean_env &block
76
+ meth = if Bundler.respond_to?(:with_unbundled_env)
77
+ :with_unbundled_env
78
+ else
79
+ :with_clean_env
80
+ end
81
+ Bundler.send meth, &block
82
+ end
62
83
  end
63
84
  end
@@ -39,8 +39,12 @@ module Sord
39
39
  # This prints some deprecation warnings, so suppress them
40
40
  prev_stderr = $stderr
41
41
  $stderr = StringIO.new
42
+
43
+ major = RUBY_VERSION.split('.').first.to_i
44
+ sorted_set_removed = major >= 3
42
45
 
43
46
  Object.constants
47
+ .reject { |x| sorted_set_removed && x == :SortedSet }
44
48
  .select { |x| Object.const_get(x).is_a?(Class) }
45
49
  .map(&:to_s)
46
50
  ensure
@@ -2,11 +2,12 @@
2
2
  require 'yaml'
3
3
  require 'sord/logging'
4
4
  require 'sord/resolver'
5
+ require 'parlour'
5
6
 
6
7
  module Sord
7
- # Contains methods to convert YARD types to Sorbet types.
8
+ # Contains methods to convert YARD types to Parlour types.
8
9
  module TypeConverter
9
- # A regular expression which matches Ruby namespaces and identifiers.
10
+ # A regular expression which matches Ruby namespaces and identifiers.
10
11
  # "Foo", "Foo::Bar", and "::Foo::Bar" are all matches, whereas "Foo.Bar"
11
12
  # or "Foo#bar" are not.
12
13
  SIMPLE_TYPE_REGEX =
@@ -19,27 +20,26 @@ module Sord
19
20
  # "Hash{String => Symbol}", etc.
20
21
  GENERIC_TYPE_REGEX =
21
22
  /(#{SIMPLE_TYPE_REGEX})\s*[<{]\s*(.*)\s*[>}]/
22
-
23
+
23
24
  # Match duck types which require the object implement one or more methods,
24
25
  # like '#foo', '#foo & #bar', '#foo&#bar&#baz', and '#foo&#bar&#baz&#foo_bar'.
25
26
  DUCK_TYPE_REGEX =
26
27
  /^\#[a-zA-Z_][\w]*(?:[a-zA-Z_][\w=]*)*(?:( ?\& ?\#)*[a-zA-Z_][\w=]*)*$/
27
-
28
+
28
29
  # A regular expression which matches ordered lists in the format of
29
30
  # either "Array(String, Symbol)" or "(String, Symbol)".
30
31
  ORDERED_LIST_REGEX = /^(?:Array|)\((.*)\s*\)$/
31
32
 
32
- # A regular expression which matches the shorthand Hash syntax,
33
+ # A regular expression which matches the shorthand Hash syntax,
33
34
  # "{String => Symbol}".
34
35
  SHORTHAND_HASH_SYNTAX = /^{\s*(.*)\s*}$/
35
36
 
36
- # A regular expression which matches the shorthand Array syntax,
37
+ # A regular expression which matches the shorthand Array syntax,
37
38
  # "<String>".
38
39
  SHORTHAND_ARRAY_SYNTAX = /^<\s*(.*)\s*>$/
39
40
 
40
- # An array of built-in generic types supported by Sorbet.
41
- SORBET_SUPPORTED_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range Hash Class}
42
- SORBET_SINGLE_ARG_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range}
41
+ # Built in parlour single arg generics
42
+ SINGLE_ARG_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range}
43
43
 
44
44
  # Given a string of YARD type parameters (without angle brackets), splits
45
45
  # the string into an array of each type parameter.
@@ -50,7 +50,7 @@ module Sord
50
50
  buffer = ""
51
51
  current_bracketing_level = 0
52
52
  character_pointer = 0
53
-
53
+
54
54
  while character_pointer < params.length
55
55
  should_buffer = true
56
56
 
@@ -90,7 +90,7 @@ module Sord
90
90
  result
91
91
  end
92
92
 
93
- # Converts a YARD type into a Sorbet type.
93
+ # Converts a YARD type into a Parlour type.
94
94
  # @param [Boolean, Array, String] yard The YARD type.
95
95
  # @param [YARD::CodeObjects::Base] item The CodeObject which the YARD type
96
96
  # is associated with. This is used for logging and can be nil, but this
@@ -99,30 +99,34 @@ module Sord
99
99
  # instead of SORD_ERROR_ constants for unknown types.
100
100
  # @param [Boolean] replace_unresolved_with_untyped If true, T.untyped is used
101
101
  # when Sord is unable to resolve a constant.
102
- # @return [String]
103
- def self.yard_to_sorbet(yard, item = nil, replace_errors_with_untyped = false, replace_unresolved_with_untyped = false)
102
+ # @return [Parlour::Types::Type]
103
+ def self.yard_to_parlour(yard, item = nil, replace_errors_with_untyped = false, replace_unresolved_with_untyped = false)
104
104
  case yard
105
105
  when nil # Type not specified
106
- "T.untyped"
106
+ Parlour::Types::Untyped.new
107
107
  when "bool", "Bool", "boolean", "Boolean", "true", "false"
108
- "T::Boolean"
108
+ Parlour::Types::Boolean.new
109
109
  when 'self'
110
- 'T.self_type'
110
+ Parlour::Types::Self.new
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
114
114
  types = yard
115
115
  .reject { |x| x == 'nil' }
116
- .map { |x| yard_to_sorbet(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
117
- .uniq
118
- result = types.length == 1 ? types.first : "T.any(#{types.join(', ')})"
119
- result = "T.nilable(#{result})" if yard.include?('nil')
116
+ .map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
117
+ .uniq(&:hash)
118
+ result = types.length == 1 \
119
+ ? types.first
120
+ : Parlour::Types::Union.new(types)
121
+ result = Parlour::Types::Nilable.new(result) if yard.include?('nil')
120
122
  result
121
123
  when /^#{SIMPLE_TYPE_REGEX}$/
122
- if SORBET_SINGLE_ARG_GENERIC_TYPES.include?(yard)
123
- return "T::#{yard}[T.untyped]"
124
+ if SINGLE_ARG_GENERIC_TYPES.include?(yard)
125
+ return Parlour::Types.const_get(yard).new(Parlour::Types::Untyped.new)
124
126
  elsif yard == "Hash"
125
- return "T::Hash[T.untyped, T.untyped]"
127
+ return Parlour::Types::Hash.new(
128
+ Parlour::Types::Untyped.new, Parlour::Types::Untyped.new
129
+ )
126
130
  end
127
131
  # If this doesn't begin with an uppercase letter, warn
128
132
  if /^[_a-z]/ === yard
@@ -136,78 +140,79 @@ module Sord
136
140
  new_path = Resolver.path_for(yard)
137
141
  Logging.infer("#{yard} was resolved to #{new_path}", item) \
138
142
  unless yard == new_path
139
- new_path
143
+ Parlour::Types::Raw.new(new_path)
140
144
  else
141
145
  if replace_unresolved_with_untyped
142
- Logging.warn("#{yard} wasn't able to be resolved to a constant in this project, replaced with T.untyped", item)
143
- 'T.untyped'
146
+ Logging.warn("#{yard} wasn't able to be resolved to a constant in this project, replaced with untyped", item)
147
+ Parlour::Types::Untyped.new
144
148
  else
145
149
  Logging.warn("#{yard} wasn't able to be resolved to a constant in this project", item)
146
- yard
150
+ Parlour::Types::Raw.new(yard)
147
151
  end
148
152
  end
149
153
  else
150
- yard
154
+ Parlour::Types::Raw.new(yard)
151
155
  end
152
156
  when DUCK_TYPE_REGEX
153
- Logging.duck("#{yard} looks like a duck type, replacing with T.untyped", item)
154
- 'T.untyped'
157
+ Logging.duck("#{yard} looks like a duck type, replacing with untyped", item)
158
+ Parlour::Types::Untyped.new
155
159
  when /^#{GENERIC_TYPE_REGEX}$/
156
160
  generic_type = $1
157
161
  type_parameters = $2
158
162
 
159
- if SORBET_SUPPORTED_GENERIC_TYPES.include?(generic_type)
160
- parameters = split_type_parameters(type_parameters)
161
- .map { |x| yard_to_sorbet(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
162
- if SORBET_SINGLE_ARG_GENERIC_TYPES.include?(generic_type) && parameters.length > 1
163
- "T::#{generic_type}[T.any(#{parameters.join(', ')})]"
164
- elsif generic_type == 'Class' && parameters.length == 1
165
- "T.class_of(#{parameters.first})"
166
- elsif generic_type == 'Hash'
167
- if parameters.length == 2
168
- "T::Hash[#{parameters.join(', ')}]"
169
- else
170
- handle_sord_error(parameters.join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
171
- 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)
172
172
  else
173
- "T::#{generic_type}[#{parameters.join(', ')}]"
173
+ handle_sord_error(parameters.map(&:describe).join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
174
174
  end
175
175
  else
176
- return handle_sord_error(
177
- generic_type,
178
- "unsupported generic type #{generic_type.inspect} in #{yard.inspect}",
179
- item,
180
- replace_errors_with_untyped
181
- )
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
182
187
  end
183
188
  # Converts ordered lists like Array(Symbol, String) or (Symbol, String)
184
- # into Sorbet Tuples like [Symbol, String].
189
+ # into tuples.
185
190
  when ORDERED_LIST_REGEX
186
191
  type_parameters = $1
187
192
  parameters = split_type_parameters(type_parameters)
188
- .map { |x| yard_to_sorbet(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
189
- "[#{parameters.join(', ')}]"
193
+ .map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
194
+ Parlour::Types::Tuple.new(parameters)
190
195
  when SHORTHAND_HASH_SYNTAX
191
196
  type_parameters = $1
192
197
  parameters = split_type_parameters(type_parameters)
193
- .map { |x| yard_to_sorbet(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
198
+ .map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
194
199
  # Return a warning about an invalid hash when it has more or less than two elements.
195
200
  if parameters.length == 2
196
- "T::Hash[#{parameters.join(', ')}]"
201
+ Parlour::Types::Hash.new(*parameters)
197
202
  else
198
- handle_sord_error(parameters.join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
203
+ handle_sord_error(parameters.map(&:describe).join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
199
204
  end
200
205
  when SHORTHAND_ARRAY_SYNTAX
201
206
  type_parameters = $1
202
207
  parameters = split_type_parameters(type_parameters)
203
- .map { |x| yard_to_sorbet(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
208
+ .map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
204
209
  parameters.one? \
205
- ? "T::Array[#{parameters.first}]"
206
- : "T::Array[T.any(#{parameters.join(', ')})]"
210
+ ? Parlour::Types::Array.new(parameters.first)
211
+ : Parlour::Types::Array.new(Parlour::Types::Union.new(parameters))
207
212
  else
208
213
  # Check for literals
209
214
  from_yaml = YAML.load(yard) rescue nil
210
- return from_yaml.class.to_s \
215
+ return Parlour::Types::Raw.new(from_yaml.class.to_s) \
211
216
  if [Symbol, Float, Integer].include?(from_yaml.class)
212
217
 
213
218
  return handle_sord_error(yard.to_s, "#{yard.inspect} does not appear to be a type", item, replace_errors_with_untyped)
@@ -216,14 +221,17 @@ module Sord
216
221
 
217
222
  # Handles SORD_ERRORs.
218
223
  #
219
- # @param [String] name
224
+ # @param [String, Parlour::Types::Type] name
220
225
  # @param [String] log_warning
221
226
  # @param [YARD::CodeObjects::Base] item
222
227
  # @param [Boolean] replace_errors_with_untyped
223
- # @return [String]
228
+ # @return [Parlour::Types::Type]
224
229
  def self.handle_sord_error(name, log_warning, item, replace_errors_with_untyped)
225
230
  Logging.warn(log_warning, item)
226
- return replace_errors_with_untyped ? "T.untyped" : "SORD_ERROR_#{name.gsub(/[^0-9A-Za-z_]/i, '')}"
231
+ str = name.is_a?(Parlour::Types::Type) ? name.describe : name
232
+ return replace_errors_with_untyped \
233
+ ? Parlour::Types::Untyped.new
234
+ : Parlour::Types::Raw.new("SORD_ERROR_#{name.gsub(/[^0-9A-Za-z_]/i, '')}")
227
235
  end
228
236
  end
229
237
  end
@@ -1,4 +1,4 @@
1
1
  # typed: strong
2
2
  module Sord
3
- VERSION = '1.0.0'
3
+ VERSION = '3.0.1'
4
4
  end
@@ -1,29 +1,57 @@
1
1
  # typed: strong
2
+
2
3
  module Sord
3
- VERSION = T.let('0.8.0', T.untyped)
4
+ VERSION = T.let('3.0.1', T.untyped)
4
5
 
6
+ # Handles writing logs to stdout and any other classes which request them.
5
7
  module Logging
6
8
  AVAILABLE_TYPES = T.let([:warn, :info, :duck, :error, :infer, :omit, :done].freeze, T.untyped)
7
9
 
10
+ # _@return_ — The hooks registered on the logger.
8
11
  sig { returns(T::Array[Proc]) }
9
12
  def self.hooks; end
10
13
 
14
+ # _@return_ — Whether log messages should be printed or not. This is
15
+ # used for testing.
11
16
  sig { returns(T::Boolean) }
12
17
  def self.silent?; end
13
18
 
19
+ # Sets whether log messages should be printed or not.
20
+ #
21
+ # _@param_ `value`
14
22
  sig { params(value: T::Boolean).void }
15
23
  def self.silent=(value); end
16
24
 
25
+ # Sets the array of log messages types which should be processed. Any not on
26
+ # this list will be discarded. This should be a subset of AVAILABLE_TYPES.
27
+ #
28
+ # _@param_ `value`
17
29
  sig { params(value: T::Array[Symbol]).void }
18
30
  def self.enabled_types=(value); end
19
31
 
32
+ # Gets the array of log messages types which should be processed. Any not on
33
+ # this list will be discarded.
20
34
  sig { returns(T::Array[Symbol]) }
21
35
  def self.enabled_types; end
22
36
 
37
+ # Returns a boolean indicating whether a given array is a valid value for
38
+ # #enabled_types.
39
+ #
40
+ # _@param_ `value`
23
41
  sig { params(value: T::Array[Symbol]).void }
24
42
  def self.valid_types?(value); end
25
43
 
26
44
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
45
+ # A generic log message writer which is called by all other specific logging
46
+ # methods. This shouldn't be called outside of the Logging class itself.
47
+ #
48
+ # _@param_ `kind` — The kind of log message this is.
49
+ #
50
+ # _@param_ `header` — The prefix for this log message. For consistency, it should be up to five uppercase characters wrapped in square brackets, with some unique colour applied.
51
+ #
52
+ # _@param_ `msg` — The log message to write.
53
+ #
54
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
27
55
  sig do
28
56
  params(
29
57
  kind: Symbol,
@@ -35,38 +63,91 @@ module Sord
35
63
  def self.generic(kind, header, msg, item); end
36
64
 
37
65
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
66
+ # Print a warning message. This should be used for things which require the
67
+ # user's attention but do not prevent the process from stopping.
68
+ #
69
+ # _@param_ `msg` — The log message to write.
70
+ #
71
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
38
72
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
39
73
  def self.warn(msg, item = nil); end
40
74
 
41
75
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
76
+ # Print an info message. This should be used for generic informational
77
+ # messages which the user doesn't need to act on.
78
+ #
79
+ # _@param_ `msg` — The log message to write.
80
+ #
81
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
42
82
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
43
83
  def self.info(msg, item = nil); end
44
84
 
45
85
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
86
+ # Print a duck-typing message. This should be used when the YARD
87
+ # documentation contains duck typing, which isn't supported by Sorbet, so
88
+ # it is substituted for something different.
89
+ #
90
+ # _@param_ `msg` — The log message to write.
91
+ #
92
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
46
93
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
47
94
  def self.duck(msg, item = nil); end
48
95
 
49
96
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
97
+ # Print an error message. This should be used for things which require the
98
+ # current process to stop.
99
+ #
100
+ # _@param_ `msg` — The log message to write.
101
+ #
102
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
50
103
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
51
104
  def self.error(msg, item = nil); end
52
105
 
53
106
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
107
+ # Print an infer message. This should be used when the user should be told
108
+ # that some information has been filled in or guessed for them, and that
109
+ # information is likely correct.
110
+ #
111
+ # _@param_ `msg` — The log message to write.
112
+ #
113
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
54
114
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
55
115
  def self.infer(msg, item = nil); end
56
116
 
57
117
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
118
+ # Print an omit message. This should be used as a special type of warning
119
+ # to alert the user that there is some information missing, but this
120
+ # information is not critical to the completion of the process.
121
+ #
122
+ # _@param_ `msg` — The log message to write.
123
+ #
124
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
58
125
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
59
126
  def self.omit(msg, item = nil); end
60
127
 
61
128
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
129
+ # Print a done message. This should be used when a process completes
130
+ # successfully.
131
+ #
132
+ # _@param_ `msg` — The log message to write.
133
+ #
134
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
62
135
  sig { params(msg: String, item: T.nilable(YARD::CodeObjects::Base)).void }
63
136
  def self.done(msg, item = nil); end
64
137
 
65
138
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
139
+ # Invokes all registered hooks on the logger.
140
+ #
141
+ # _@param_ `kind` — The kind of log message this is.
142
+ #
143
+ # _@param_ `msg` — The log message to write.
144
+ #
145
+ # _@param_ `item` — The CodeObject which this log is associated with, if any. This is shown before the log message if it is specified.
66
146
  sig { params(kind: Symbol, msg: String, item: YARD::CodeObjects::Base).void }
67
147
  def self.invoke_hooks(kind, msg, item); end
68
148
 
69
149
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
150
+ # Adds a hook to the logger.
70
151
  sig { params(blk: T.proc.params(kind: Symbol, msg: String, item: YARD::CodeObjects::Base).void).void }
71
152
  def self.add_hook(&blk); end
72
153
  end
@@ -78,85 +159,159 @@ module Sord
78
159
  sig { void }
79
160
  def self.clear; end
80
161
 
162
+ # _@param_ `name`
81
163
  sig { params(name: String).returns(T::Array[String]) }
82
164
  def self.paths_for(name); end
83
165
 
166
+ # _@param_ `name`
84
167
  sig { params(name: String).returns(T.nilable(String)) }
85
168
  def self.path_for(name); end
86
169
 
87
170
  sig { returns(T::Array[String]) }
88
171
  def self.builtin_classes; end
89
172
 
173
+ # _@param_ `name`
174
+ #
175
+ # _@param_ `item`
90
176
  sig { params(name: String, item: Object).returns(T::Boolean) }
91
177
  def self.resolvable?(name, item); end
92
178
  end
93
179
 
94
- class RbiGenerator
180
+ # Converts the current working directory's YARD registry into an type
181
+ # signature file.
182
+ class Generator
183
+ VALID_MODES = T.let([:rbi, :rbs], T.untyped)
184
+
185
+ # _@return_ — The number of objects this generator has processed so
186
+ # far.
95
187
  sig { returns(Integer) }
96
188
  def object_count; end
97
189
 
98
- # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
99
- sig { returns(T::Array[[String, YARD::CodeObjects::Base, Integer]]) }
100
- def warnings; end
101
-
190
+ # Create a new generator.
191
+ #
192
+ # _@param_ `options`
102
193
  sig { params(options: T::Hash[T.untyped, T.untyped]).void }
103
194
  def initialize(options); end
104
195
 
196
+ # Increment the namespace counter.
105
197
  sig { void }
106
198
  def count_namespace; end
107
199
 
200
+ # Increment the method counter.
108
201
  sig { void }
109
202
  def count_method; end
110
203
 
111
204
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
205
+ # Given a YARD CodeObject, add lines defining its mixins (that is, extends
206
+ # and includes) to the current file. Returns the number of mixins.
207
+ #
208
+ # _@param_ `item`
112
209
  sig { params(item: YARD::CodeObjects::Base).returns(Integer) }
113
210
  def add_mixins(item); end
114
211
 
115
212
  # sord warn - YARD::CodeObjects::NamespaceObject wasn't able to be resolved to a constant in this project
213
+ # Given a YARD NamespaceObject, add lines defining constants.
214
+ #
215
+ # _@param_ `item`
116
216
  sig { params(item: YARD::CodeObjects::NamespaceObject).void }
117
217
  def add_constants(item); end
118
218
 
119
219
  # sord warn - YARD::CodeObjects::NamespaceObject wasn't able to be resolved to a constant in this project
220
+ # sord warn - Parlour::TypedObject wasn't able to be resolved to a constant in this project
221
+ # Adds comments to an object based on a docstring.
222
+ #
223
+ # _@param_ `item`
224
+ #
225
+ # _@param_ `typed_object`
226
+ sig { params(item: YARD::CodeObjects::NamespaceObject, typed_object: Parlour::TypedObject).void }
227
+ def add_comments(item, typed_object); end
228
+
229
+ # sord warn - YARD::CodeObjects::NamespaceObject wasn't able to be resolved to a constant in this project
230
+ # Given a YARD NamespaceObject, add lines defining its methods and their
231
+ # signatures to the current file.
232
+ #
233
+ # _@param_ `item`
120
234
  sig { params(item: YARD::CodeObjects::NamespaceObject).void }
121
235
  def add_methods(item); end
122
236
 
123
237
  # sord warn - YARD::CodeObjects::NamespaceObject wasn't able to be resolved to a constant in this project
238
+ # Given a YARD NamespaceObject, add lines defining either its class
239
+ # and instance attributes and their signatures to the current file.
240
+ #
241
+ # _@param_ `item`
242
+ sig { params(item: YARD::CodeObjects::NamespaceObject).void }
243
+ def add_attributes(item); end
244
+
245
+ # sord warn - YARD::CodeObjects::NamespaceObject wasn't able to be resolved to a constant in this project
246
+ # Given a YARD NamespaceObject, add lines defining its mixins, methods
247
+ # and children to the file.
248
+ #
249
+ # _@param_ `item`
124
250
  sig { params(item: YARD::CodeObjects::NamespaceObject).void }
125
251
  def add_namespace(item); end
126
252
 
253
+ # Populates the generator with the contents of the YARD registry. You
254
+ # must load the YARD registry first!
127
255
  sig { void }
128
256
  def populate; end
129
257
 
258
+ # Populates the generator with the contents of the YARD registry, then
259
+ # uses the loaded Parlour::Generator to generate the file. You must
260
+ # load the YARD registry first!
130
261
  sig { void }
131
262
  def generate; end
132
263
 
264
+ # Loads the YARD registry, populates the file, and prints any relevant
265
+ # final logs.
133
266
  sig { void }
134
267
  def run; end
135
- end
136
268
 
137
- class ParlourPlugin < Parlour::Plugin
138
- # sord omit - no YARD return type given, using T.untyped
139
- sig { returns(T.untyped) }
140
- def options; end
269
+ # Given two pairs of arrays representing method parameters, in the form
270
+ # of ["variable_name", "default_value"], sort the parameters so they're
271
+ # valid for Sorbet. Sorbet requires that, e.g. required kwargs go before
272
+ # optional kwargs.
273
+ #
274
+ # _@param_ `pair1`
275
+ #
276
+ # _@param_ `pair2`
277
+ #
278
+ # _@return_ — Integer
279
+ sig { params(pair1: T::Array[T.untyped], pair2: T::Array[T.untyped]).returns(T.untyped) }
280
+ def sort_params(pair1, pair2); end
141
281
 
142
- # sord omit - no YARD return type given, using T.untyped
143
- sig { returns(T.untyped) }
144
- def parlour; end
145
-
146
- # sord omit - no YARD return type given, using T.untyped
147
- sig { params(value: T.untyped).returns(T.untyped) }
148
- def parlour=(value); end
282
+ # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
283
+ # _@return_ The
284
+ # errors encountered by by the generator. Each element is of the form
285
+ # [message, item, line].
286
+ sig { returns(T::Array[[String, YARD::CodeObjects::Base, Integer]]) }
287
+ attr_reader :warnings
288
+ end
149
289
 
150
- # sord omit - no YARD type given for "options", using T.untyped
151
- sig { params(options: T.untyped).returns(ParlourPlugin) }
290
+ class ParlourPlugin < Parlour::Plugin
291
+ # sord omit - no YARD type given for "options", using untyped
292
+ sig { params(options: T.untyped).void }
152
293
  def initialize(options); end
153
294
 
154
- # sord omit - no YARD type given for "root", using T.untyped
155
- # sord omit - no YARD return type given, using T.untyped
295
+ # sord omit - no YARD type given for "root", using untyped
296
+ # sord omit - no YARD return type given, using untyped
156
297
  sig { params(root: T.untyped).returns(T.untyped) }
157
298
  def generate(root); end
299
+
300
+ # sord omit - no YARD return type given, using untyped
301
+ sig { params(block: T.untyped).returns(T.untyped) }
302
+ def self.with_clean_env(&block); end
303
+
304
+ # sord omit - no YARD type given for :options, using untyped
305
+ # Returns the value of attribute options.
306
+ sig { returns(T.untyped) }
307
+ attr_reader :options
308
+
309
+ # Returns the value of attribute parlour.
310
+ sig { returns(T.untyped) }
311
+ attr_accessor :parlour
158
312
  end
159
313
 
314
+ # Contains methods to convert YARD types to Parlour types.
160
315
  module TypeConverter
161
316
  SIMPLE_TYPE_REGEX = T.let(/(?:\:\:)?[a-zA-Z_][\w]*(?:\:\:[a-zA-Z_][\w]*)*/, T.untyped)
162
317
  GENERIC_TYPE_REGEX = T.let(/(#{SIMPLE_TYPE_REGEX})\s*[<{]\s*(.*)\s*[>}]/, T.untyped)
@@ -164,32 +319,58 @@ module Sord
164
319
  ORDERED_LIST_REGEX = T.let(/^(?:Array|)\((.*)\s*\)$/, T.untyped)
165
320
  SHORTHAND_HASH_SYNTAX = T.let(/^{\s*(.*)\s*}$/, T.untyped)
166
321
  SHORTHAND_ARRAY_SYNTAX = T.let(/^<\s*(.*)\s*>$/, T.untyped)
167
- SORBET_SUPPORTED_GENERIC_TYPES = T.let(%w{Array Set Enumerable Enumerator Range Hash Class}, T.untyped)
168
- SORBET_SINGLE_ARG_GENERIC_TYPES = T.let(%w{Array Set Enumerable Enumerator Range}, T.untyped)
169
-
322
+ SINGLE_ARG_GENERIC_TYPES = T.let(%w{Array Set Enumerable Enumerator Range}, T.untyped)
323
+
324
+ # Given a string of YARD type parameters (without angle brackets), splits
325
+ # the string into an array of each type parameter.
326
+ #
327
+ # _@param_ `params` — The type parameters.
328
+ #
329
+ # _@return_ — The split type parameters.
170
330
  sig { params(params: String).returns(T::Array[String]) }
171
331
  def self.split_type_parameters(params); end
172
332
 
173
333
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
334
+ # sord warn - Parlour::Types::Type wasn't able to be resolved to a constant in this project
335
+ # Converts a YARD type into a Parlour type.
336
+ #
337
+ # _@param_ `yard` — The YARD type.
338
+ #
339
+ # _@param_ `item` — The CodeObject which the YARD type is associated with. This is used for logging and can be nil, but this will lead to less informative log messages.
340
+ #
341
+ # _@param_ `replace_errors_with_untyped` — If true, T.untyped is used instead of SORD_ERROR_ constants for unknown types.
342
+ #
343
+ # _@param_ `replace_unresolved_with_untyped` — If true, T.untyped is used when Sord is unable to resolve a constant.
174
344
  sig do
175
345
  params(
176
346
  yard: T.any(T::Boolean, T::Array[T.untyped], String),
177
347
  item: T.nilable(YARD::CodeObjects::Base),
178
348
  replace_errors_with_untyped: T::Boolean,
179
349
  replace_unresolved_with_untyped: T::Boolean
180
- ).returns(String)
350
+ ).returns(Parlour::Types::Type)
181
351
  end
182
- def self.yard_to_sorbet(yard, item = nil, replace_errors_with_untyped = false, replace_unresolved_with_untyped = false); end
352
+ def self.yard_to_parlour(yard, item = nil, replace_errors_with_untyped = false, replace_unresolved_with_untyped = false); end
183
353
 
354
+ # sord warn - Parlour::Types::Type wasn't able to be resolved to a constant in this project
184
355
  # sord warn - YARD::CodeObjects::Base wasn't able to be resolved to a constant in this project
356
+ # sord warn - Parlour::Types::Type wasn't able to be resolved to a constant in this project
357
+ # Handles SORD_ERRORs.
358
+ #
359
+ # _@param_ `name`
360
+ #
361
+ # _@param_ `log_warning`
362
+ #
363
+ # _@param_ `item`
364
+ #
365
+ # _@param_ `replace_errors_with_untyped`
185
366
  sig do
186
367
  params(
187
- name: String,
368
+ name: T.any(String, Parlour::Types::Type),
188
369
  log_warning: String,
189
370
  item: YARD::CodeObjects::Base,
190
371
  replace_errors_with_untyped: T::Boolean
191
- ).returns(String)
372
+ ).returns(Parlour::Types::Type)
192
373
  end
193
374
  def self.handle_sord_error(name, log_warning, item, replace_errors_with_untyped); end
194
375
  end
195
- end
376
+ end