sord 0.8.0 → 3.0.0.beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- data/.github/ISSUE_TEMPLATE/feature-request.md +0 -0
- data/.gitignore +0 -0
- data/.parlour +11 -0
- data/.rspec +0 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +99 -0
- data/CODE_OF_CONDUCT.md +0 -0
- data/Gemfile +0 -0
- data/LICENSE.txt +0 -0
- data/README.md +17 -11
- data/Rakefile +87 -12
- data/exe/sord +50 -33
- data/lib/sord.rb +2 -1
- data/lib/sord/generator.rb +592 -0
- data/lib/sord/logging.rb +21 -30
- data/lib/sord/parlour_plugin.rb +84 -0
- data/lib/sord/resolver.rb +9 -2
- data/lib/sord/type_converter.rb +88 -42
- data/lib/sord/version.rb +1 -1
- data/rbi/sord.rbi +279 -68
- data/sord.gemspec +3 -3
- metadata +23 -38
- data/lib/sord/rbi_generator.rb +0 -334
- data/sorbet/config +0 -0
- data/sorbet/rbi/gems/colorize.rbi +0 -81
- data/sorbet/rbi/gems/docile.rbi +0 -31
- data/sorbet/rbi/gems/rake.rbi +0 -643
- data/sorbet/rbi/gems/rspec-core.rbi +0 -1658
- data/sorbet/rbi/gems/rspec-expectations.rbi +0 -389
- data/sorbet/rbi/gems/rspec-mocks.rbi +0 -823
- data/sorbet/rbi/gems/rspec-support.rbi +0 -268
- data/sorbet/rbi/gems/rspec.rbi +0 -14
- data/sorbet/rbi/gems/simplecov-html.rbi +0 -30
- data/sorbet/rbi/gems/simplecov.rbi +0 -223
- data/sorbet/rbi/gems/sorbet-runtime.rbi +0 -647
- data/sorbet/rbi/gems/yard.rbi +0 -310
- data/sorbet/rbi/hidden-definitions/errors.txt +0 -9353
- data/sorbet/rbi/hidden-definitions/hidden.rbi +0 -16640
- data/sorbet/rbi/sorbet-typed/lib/bundler/all/bundler.rbi +0 -8547
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/open3.rbi +0 -111
- data/sorbet/rbi/sorbet-typed/lib/ruby/all/resolv.rbi +0 -543
data/lib/sord/logging.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
|
1
|
+
# typed: true
|
2
|
+
require 'rainbow'
|
2
3
|
|
3
4
|
module Sord
|
4
5
|
# Handles writing logs to stdout and any other classes which request them.
|
@@ -68,18 +69,17 @@ module Sord
|
|
68
69
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
69
70
|
# is associated with, if any. This is shown before the log message if it is
|
70
71
|
# specified.
|
71
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
72
72
|
# @return [void]
|
73
|
-
def self.generic(kind, header, msg, item
|
73
|
+
def self.generic(kind, header, msg, item)
|
74
74
|
return unless enabled_types.include?(kind)
|
75
75
|
|
76
76
|
if item
|
77
|
-
puts "#{header} (#{item.path.bold}) #{msg}" unless silent?
|
77
|
+
puts "#{header} (#{Rainbow(item.path).bold}) #{msg}" unless silent?
|
78
78
|
else
|
79
79
|
puts "#{header} #{msg}" unless silent?
|
80
80
|
end
|
81
81
|
|
82
|
-
invoke_hooks(kind, msg, item
|
82
|
+
invoke_hooks(kind, msg, item)
|
83
83
|
end
|
84
84
|
|
85
85
|
# Print a warning message. This should be used for things which require the
|
@@ -88,10 +88,9 @@ module Sord
|
|
88
88
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
89
89
|
# is associated with, if any. This is shown before the log message if it is
|
90
90
|
# specified.
|
91
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
92
91
|
# @return [void]
|
93
|
-
def self.warn(msg, item = nil
|
94
|
-
generic(:warn, '[WARN ]'.yellow, msg, item
|
92
|
+
def self.warn(msg, item = nil)
|
93
|
+
generic(:warn, Rainbow('[WARN ]').yellow, msg, item)
|
95
94
|
end
|
96
95
|
|
97
96
|
# Print an info message. This should be used for generic informational
|
@@ -100,10 +99,9 @@ module Sord
|
|
100
99
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
101
100
|
# is associated with, if any. This is shown before the log message if it is
|
102
101
|
# specified.
|
103
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
104
102
|
# @return [void]
|
105
|
-
def self.info(msg, item = nil
|
106
|
-
generic(:info, '[INFO ]', msg, item
|
103
|
+
def self.info(msg, item = nil)
|
104
|
+
generic(:info, '[INFO ]', msg, item)
|
107
105
|
end
|
108
106
|
|
109
107
|
# Print a duck-typing message. This should be used when the YARD
|
@@ -113,10 +111,9 @@ module Sord
|
|
113
111
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
114
112
|
# is associated with, if any. This is shown before the log message if it is
|
115
113
|
# specified.
|
116
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
117
114
|
# @return [void]
|
118
|
-
def self.duck(msg, item = nil
|
119
|
-
generic(:duck, '[DUCK ]'.cyan, msg, item
|
115
|
+
def self.duck(msg, item = nil)
|
116
|
+
generic(:duck, Rainbow('[DUCK ]').cyan, msg, item)
|
120
117
|
end
|
121
118
|
|
122
119
|
# Print an error message. This should be used for things which require the
|
@@ -125,10 +122,9 @@ module Sord
|
|
125
122
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
126
123
|
# is associated with, if any. This is shown before the log message if it is
|
127
124
|
# specified.
|
128
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
129
125
|
# @return [void]
|
130
|
-
def self.error(msg, item = nil
|
131
|
-
generic(:error, '[ERROR]'.red, msg, item
|
126
|
+
def self.error(msg, item = nil)
|
127
|
+
generic(:error, Rainbow('[ERROR]').red, msg, item)
|
132
128
|
end
|
133
129
|
|
134
130
|
# Print an infer message. This should be used when the user should be told
|
@@ -138,10 +134,9 @@ module Sord
|
|
138
134
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
139
135
|
# is associated with, if any. This is shown before the log message if it is
|
140
136
|
# specified.
|
141
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
142
137
|
# @return [void]
|
143
|
-
def self.infer(msg, item = nil
|
144
|
-
generic(:infer, '[INFER]'.
|
138
|
+
def self.infer(msg, item = nil)
|
139
|
+
generic(:infer, Rainbow('[INFER]').blue, msg, item)
|
145
140
|
end
|
146
141
|
|
147
142
|
# Print an omit message. This should be used as a special type of warning
|
@@ -151,10 +146,9 @@ module Sord
|
|
151
146
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
152
147
|
# is associated with, if any. This is shown before the log message if it is
|
153
148
|
# specified.
|
154
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
155
149
|
# @return [void]
|
156
|
-
def self.omit(msg, item = nil
|
157
|
-
generic(:omit, '[OMIT ]'.magenta, msg, item
|
150
|
+
def self.omit(msg, item = nil)
|
151
|
+
generic(:omit, Rainbow('[OMIT ]').magenta, msg, item)
|
158
152
|
end
|
159
153
|
|
160
154
|
# Print a done message. This should be used when a process completes
|
@@ -163,10 +157,9 @@ module Sord
|
|
163
157
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
164
158
|
# is associated with, if any. This is shown before the log message if it is
|
165
159
|
# specified.
|
166
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
167
160
|
# @return [void]
|
168
|
-
def self.done(msg, item = nil
|
169
|
-
generic(:done, '[DONE ]'.green, msg, item)
|
161
|
+
def self.done(msg, item = nil)
|
162
|
+
generic(:done, Rainbow('[DONE ]').green, msg, item)
|
170
163
|
end
|
171
164
|
|
172
165
|
# Invokes all registered hooks on the logger.
|
@@ -175,11 +168,10 @@ module Sord
|
|
175
168
|
# @param [YARD::CodeObjects::Base] item The CodeObject which this log
|
176
169
|
# is associated with, if any. This is shown before the log message if it is
|
177
170
|
# specified.
|
178
|
-
# @param [Integer] indent_level The level at which to indent the code.
|
179
171
|
# @return [void]
|
180
|
-
def self.invoke_hooks(kind, msg, item
|
172
|
+
def self.invoke_hooks(kind, msg, item)
|
181
173
|
@@hooks.each do |hook|
|
182
|
-
hook.(kind, msg, item
|
174
|
+
hook.(kind, msg, item) rescue nil
|
183
175
|
end
|
184
176
|
end
|
185
177
|
|
@@ -189,7 +181,6 @@ module Sord
|
|
189
181
|
# @yieldparam [YARD::CodeObjects::Base] item The CodeObject which this log
|
190
182
|
# is associated with, if any. This is shown before the log message if it is
|
191
183
|
# specified.
|
192
|
-
# @yieldparam [Integer] indent_level The level at which to indent the code.
|
193
184
|
# @yieldreturn [void]
|
194
185
|
# @return [void]
|
195
186
|
def self.add_hook(&blk)
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# typed: true
|
2
|
+
require 'parlour'
|
3
|
+
|
4
|
+
module Sord
|
5
|
+
class ParlourPlugin < Parlour::Plugin
|
6
|
+
attr_reader :options
|
7
|
+
attr_accessor :parlour
|
8
|
+
|
9
|
+
def initialize(options)
|
10
|
+
@parlour = nil
|
11
|
+
@options = options
|
12
|
+
|
13
|
+
options[:sord_comments] = true if options[:sord_comments].nil?
|
14
|
+
options[:regenerate] = true if options[:regenerate].nil?
|
15
|
+
options[:replace_errors_with_untyped] ||= false
|
16
|
+
options[:replace_unresolved_with_untyped] ||= false
|
17
|
+
end
|
18
|
+
|
19
|
+
def generate(root)
|
20
|
+
if options[:include_messages] && options[:exclude_messages]
|
21
|
+
Sord::Logging.error('Please specify only one of --include-messages and --exclude-messages.')
|
22
|
+
return false
|
23
|
+
elsif options[:include_messages]
|
24
|
+
whitelist = options[:include_messages].map { |x| x.downcase.to_sym }
|
25
|
+
unless Sord::Logging.valid_types?(whitelist)
|
26
|
+
Sord::Logging.error('Not all types on your --include-messages list are valid.')
|
27
|
+
Sord::Logging.error("Valid options are: #{Sord::Logging::AVAILABLE_TYPES.map(&:to_s).join(', ')}")
|
28
|
+
return false
|
29
|
+
end
|
30
|
+
Sord::Logging.enabled_types = whitelist | [:done]
|
31
|
+
elsif options[:exclude_messages]
|
32
|
+
blacklist = options[:exclude_messages].map { |x| x.downcase.to_sym }
|
33
|
+
unless Sord::Logging.valid_types?(blacklist)
|
34
|
+
Sord::Logging.error('Not all types on your --include-messages list are valid.')
|
35
|
+
Sord::Logging.error("Valid options are: #{Sord::Logging::AVAILABLE_TYPES.map(&:to_s).join(', ')}")
|
36
|
+
return false
|
37
|
+
end
|
38
|
+
Sord::Logging.enabled_types = Sord::Logging::AVAILABLE_TYPES - blacklist
|
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
|
50
|
+
|
51
|
+
if options[:regenerate]
|
52
|
+
begin
|
53
|
+
Sord::Logging.info('Running YARD...')
|
54
|
+
Sord::ParlourPlugin.with_clean_env do
|
55
|
+
system('bundle exec yard')
|
56
|
+
end
|
57
|
+
rescue Errno::ENOENT
|
58
|
+
Sord::Logging.error('The YARD tool could not be found on your PATH.')
|
59
|
+
Sord::Logging.error('You may need to run \'gem install yard\'.')
|
60
|
+
Sord::Logging.error('If documentation has already been generated, pass --no-regenerate to Sord.')
|
61
|
+
return false
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
options[:mode] = \
|
66
|
+
if options[:rbi] then :rbi elsif options[:rbs] then :rbs end
|
67
|
+
options[:parlour] = @parlour
|
68
|
+
options[:root] = root
|
69
|
+
|
70
|
+
Sord::Generator.new(options).run
|
71
|
+
|
72
|
+
true
|
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
|
83
|
+
end
|
84
|
+
end
|
data/lib/sord/resolver.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# typed: false
|
1
2
|
require 'stringio'
|
2
3
|
|
3
4
|
module Sord
|
@@ -50,12 +51,18 @@ module Sord
|
|
50
51
|
# @param [Object] item
|
51
52
|
# @return [Boolean]
|
52
53
|
def self.resolvable?(name, item)
|
53
|
-
name_parts = name.split('::')
|
54
|
-
|
55
54
|
current_context = item
|
56
55
|
current_context = current_context.parent \
|
57
56
|
until current_context.is_a?(YARD::CodeObjects::NamespaceObject)
|
58
57
|
|
58
|
+
# If there is any matching object directly in the heirarchy, this is
|
59
|
+
# always true. Ruby can do the resolution.
|
60
|
+
unless name.include?('::')
|
61
|
+
return true if current_context.path.split('::').include?(name)
|
62
|
+
end
|
63
|
+
|
64
|
+
name_parts = name.split('::')
|
65
|
+
|
59
66
|
matching_paths = []
|
60
67
|
|
61
68
|
loop do
|
data/lib/sord/type_converter.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# typed: true
|
1
2
|
require 'yaml'
|
2
3
|
require 'sord/logging'
|
3
4
|
require 'sord/resolver'
|
5
|
+
require 'parlour'
|
4
6
|
|
5
7
|
module Sord
|
6
|
-
# Contains methods to convert YARD types to
|
8
|
+
# Contains methods to convert YARD types to Parlour types.
|
7
9
|
module TypeConverter
|
8
10
|
# A regular expression which matches Ruby namespaces and identifiers.
|
9
11
|
# "Foo", "Foo::Bar", and "::Foo::Bar" are all matches, whereas "Foo.Bar"
|
@@ -36,9 +38,9 @@ module Sord
|
|
36
38
|
# "<String>".
|
37
39
|
SHORTHAND_ARRAY_SYNTAX = /^<\s*(.*)\s*>$/
|
38
40
|
|
39
|
-
# An array of built-in
|
40
|
-
|
41
|
-
|
41
|
+
# An array of built-in types supported by Parlour.
|
42
|
+
SUPPORTED_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range Hash Class}
|
43
|
+
SINGLE_ARG_GENERIC_TYPES = %w{Array Set Enumerable Enumerator Range}
|
42
44
|
|
43
45
|
# Given a string of YARD type parameters (without angle brackets), splits
|
44
46
|
# the string into an array of each type parameter.
|
@@ -89,37 +91,47 @@ module Sord
|
|
89
91
|
result
|
90
92
|
end
|
91
93
|
|
92
|
-
# Converts a YARD type into a
|
94
|
+
# Converts a YARD type into a Parlour type.
|
93
95
|
# @param [Boolean, Array, String] yard The YARD type.
|
94
96
|
# @param [YARD::CodeObjects::Base] item The CodeObject which the YARD type
|
95
97
|
# is associated with. This is used for logging and can be nil, but this
|
96
98
|
# will lead to less informative log messages.
|
97
|
-
# @param [Integer] indent_level
|
98
99
|
# @param [Boolean] replace_errors_with_untyped If true, T.untyped is used
|
99
100
|
# instead of SORD_ERROR_ constants for unknown types.
|
100
|
-
# @
|
101
|
-
|
101
|
+
# @param [Boolean] replace_unresolved_with_untyped If true, T.untyped is used
|
102
|
+
# when Sord is unable to resolve a constant.
|
103
|
+
# @return [Parlour::Types::Type]
|
104
|
+
def self.yard_to_parlour(yard, item = nil, replace_errors_with_untyped = false, replace_unresolved_with_untyped = false)
|
102
105
|
case yard
|
103
106
|
when nil # Type not specified
|
104
|
-
|
107
|
+
Parlour::Types::Untyped.new
|
105
108
|
when "bool", "Bool", "boolean", "Boolean", "true", "false"
|
106
|
-
|
109
|
+
Parlour::Types::Boolean.new
|
107
110
|
when 'self'
|
108
|
-
|
111
|
+
Parlour::Types::Self.new
|
109
112
|
when Array
|
110
113
|
# If there's only one element, unwrap it, otherwise allow for a
|
111
114
|
# selection of any of the types
|
112
115
|
types = yard
|
113
116
|
.reject { |x| x == 'nil' }
|
114
|
-
.map { |x|
|
115
|
-
.uniq
|
116
|
-
result = types.length == 1
|
117
|
-
|
117
|
+
.map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
|
118
|
+
.uniq(&:hash)
|
119
|
+
result = types.length == 1 \
|
120
|
+
? types.first
|
121
|
+
: Parlour::Types::Union.new(types)
|
122
|
+
result = Parlour::Types::Nilable.new(result) if yard.include?('nil')
|
118
123
|
result
|
119
124
|
when /^#{SIMPLE_TYPE_REGEX}$/
|
125
|
+
if SINGLE_ARG_GENERIC_TYPES.include?(yard)
|
126
|
+
return Parlour::Types.const_get(yard).new(Parlour::Types::Untyped.new)
|
127
|
+
elsif yard == "Hash"
|
128
|
+
return Parlour::Types::Hash.new(
|
129
|
+
Parlour::Types::Untyped.new, Parlour::Types::Untyped.new
|
130
|
+
)
|
131
|
+
end
|
120
132
|
# If this doesn't begin with an uppercase letter, warn
|
121
133
|
if /^[_a-z]/ === yard
|
122
|
-
Logging.warn("#{yard} is probably not a type, but using anyway", item
|
134
|
+
Logging.warn("#{yard} is probably not a type, but using anyway", item)
|
123
135
|
end
|
124
136
|
|
125
137
|
# Check if whatever has been specified is actually resolvable; if not,
|
@@ -127,65 +139,99 @@ module Sord
|
|
127
139
|
if item && !Resolver.resolvable?(yard, item)
|
128
140
|
if Resolver.path_for(yard)
|
129
141
|
new_path = Resolver.path_for(yard)
|
130
|
-
Logging.infer("#{yard} was resolved to #{new_path}", item
|
142
|
+
Logging.infer("#{yard} was resolved to #{new_path}", item) \
|
131
143
|
unless yard == new_path
|
132
|
-
new_path
|
144
|
+
Parlour::Types::Raw.new(new_path)
|
133
145
|
else
|
134
|
-
|
135
|
-
|
146
|
+
if replace_unresolved_with_untyped
|
147
|
+
Logging.warn("#{yard} wasn't able to be resolved to a constant in this project, replaced with untyped", item)
|
148
|
+
Parlour::Types::Untyped.new
|
149
|
+
else
|
150
|
+
Logging.warn("#{yard} wasn't able to be resolved to a constant in this project", item)
|
151
|
+
Parlour::Types::Raw.new(yard)
|
152
|
+
end
|
136
153
|
end
|
137
154
|
else
|
138
|
-
yard
|
155
|
+
Parlour::Types::Raw.new(yard)
|
139
156
|
end
|
140
157
|
when DUCK_TYPE_REGEX
|
141
|
-
Logging.duck("#{yard} looks like a duck type, replacing with
|
142
|
-
|
158
|
+
Logging.duck("#{yard} looks like a duck type, replacing with untyped", item)
|
159
|
+
Parlour::Types::Untyped.new
|
143
160
|
when /^#{GENERIC_TYPE_REGEX}$/
|
144
161
|
generic_type = $1
|
145
162
|
type_parameters = $2
|
146
163
|
|
147
|
-
if
|
164
|
+
if SUPPORTED_GENERIC_TYPES.include?(generic_type)
|
148
165
|
parameters = split_type_parameters(type_parameters)
|
149
|
-
.map { |x|
|
150
|
-
if
|
151
|
-
|
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))
|
152
169
|
elsif generic_type == 'Class' && parameters.length == 1
|
153
|
-
|
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
|
154
177
|
else
|
155
|
-
|
178
|
+
Parlour::Types.const_get(generic_type).new(*parameters)
|
156
179
|
end
|
157
180
|
else
|
158
|
-
|
159
|
-
|
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
|
+
)
|
160
187
|
end
|
161
188
|
# Converts ordered lists like Array(Symbol, String) or (Symbol, String)
|
162
|
-
# into
|
189
|
+
# into tuples.
|
163
190
|
when ORDERED_LIST_REGEX
|
164
191
|
type_parameters = $1
|
165
192
|
parameters = split_type_parameters(type_parameters)
|
166
|
-
.map { |x|
|
167
|
-
|
193
|
+
.map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
|
194
|
+
Parlour::Types::Tuple.new(parameters)
|
168
195
|
when SHORTHAND_HASH_SYNTAX
|
169
196
|
type_parameters = $1
|
170
197
|
parameters = split_type_parameters(type_parameters)
|
171
|
-
.map { |x|
|
172
|
-
|
198
|
+
.map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
|
199
|
+
# Return a warning about an invalid hash when it has more or less than two elements.
|
200
|
+
if parameters.length == 2
|
201
|
+
Parlour::Types::Hash.new(*parameters)
|
202
|
+
else
|
203
|
+
handle_sord_error(parameters.map(&:describe).join, "Invalid hash, must have exactly two types: #{yard.inspect}.", item, replace_errors_with_untyped)
|
204
|
+
end
|
173
205
|
when SHORTHAND_ARRAY_SYNTAX
|
174
206
|
type_parameters = $1
|
175
207
|
parameters = split_type_parameters(type_parameters)
|
176
|
-
.map { |x|
|
208
|
+
.map { |x| yard_to_parlour(x, item, replace_errors_with_untyped, replace_unresolved_with_untyped) }
|
177
209
|
parameters.one? \
|
178
|
-
?
|
179
|
-
:
|
210
|
+
? Parlour::Types::Array.new(parameters.first)
|
211
|
+
: Parlour::Types::Array.new(Parlour::Types::Union.new(parameters))
|
180
212
|
else
|
181
213
|
# Check for literals
|
182
214
|
from_yaml = YAML.load(yard) rescue nil
|
183
|
-
return from_yaml.class.to_s \
|
215
|
+
return Parlour::Types::Raw.new(from_yaml.class.to_s) \
|
184
216
|
if [Symbol, Float, Integer].include?(from_yaml.class)
|
185
217
|
|
186
|
-
|
187
|
-
replace_errors_with_untyped ? "T.untyped" : "SORD_ERROR_#{yard.gsub(/[^0-9A-Za-z_]/i, '')}"
|
218
|
+
return handle_sord_error(yard.to_s, "#{yard.inspect} does not appear to be a type", item, replace_errors_with_untyped)
|
188
219
|
end
|
189
220
|
end
|
221
|
+
|
222
|
+
# Handles SORD_ERRORs.
|
223
|
+
#
|
224
|
+
# @param [String, Parlour::Types::Type] name
|
225
|
+
# @param [String] log_warning
|
226
|
+
# @param [YARD::CodeObjects::Base] item
|
227
|
+
# @param [Boolean] replace_errors_with_untyped
|
228
|
+
# @return [Parlour::Types::Type]
|
229
|
+
def self.handle_sord_error(name, log_warning, item, replace_errors_with_untyped)
|
230
|
+
Logging.warn(log_warning, item)
|
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, '')}")
|
235
|
+
end
|
190
236
|
end
|
191
237
|
end
|