diff --git a/lib/sord/type_converter.rb b/lib/sord/type_converter.rb index 094d699..c79e38d 100644 --- a/lib/sord/type_converter.rb +++ b/lib/sord/type_converter.rb @@ -129,6 +129,8 @@ def self.yard_to_parlour(yard, item, config) case yard when nil # Type not specified Parlour::Types::Untyped.new + when "nil" + Parlour::Types::Raw.new('NilClass') when "bool", "Bool", "boolean", "Boolean", "true", "false" Parlour::Types::Boolean.new when 'self' @@ -195,10 +197,11 @@ def self.yard_to_parlour(yard, item, config) relative_generic_type = generic_type.start_with?('::') \ ? generic_type[2..-1] : generic_type - parameters = split_type_parameters(type_parameters) + yard_parameters = split_type_parameters(type_parameters) + parameters = yard_parameters .map { |x| yard_to_parlour(x, item, config) } - if SINGLE_ARG_GENERIC_TYPES.include?(relative_generic_type) && parameters.length > 1 - Parlour::Types.const_get(relative_generic_type).new(Parlour::Types::Union.new(parameters)) + if SINGLE_ARG_GENERIC_TYPES.include?(relative_generic_type) && yard_parameters.length > 1 + Parlour::Types.const_get(relative_generic_type).new(yard_to_parlour(yard_parameters, item, config)) elsif relative_generic_type == 'Class' if parameters.length == 1 Parlour::Types::Class.new(parameters.first) diff --git a/spec/type_converter_spec.rb b/spec/type_converter_spec.rb index 0a8f0b4..0a17533 100644 --- a/spec/type_converter_spec.rb +++ b/spec/type_converter_spec.rb @@ -77,6 +77,7 @@ def yard_to_parlour_default(type) context 'with literals' do it 'converts literals to their types' do + expect(yard_to_parlour_default('nil')).to eq Types::Raw.new('NilClass') expect(yard_to_parlour_default([':up', ':down'])).to eq Types::Raw.new('Symbol') expect(yard_to_parlour_default(['String', ':up', ':down'])).to eq \ Types::Union.new(['String', 'Symbol']) @@ -132,6 +133,11 @@ def self.path Types::Array.new(Types::Union.new(['String', 'Integer'])) end + it 'handles nil is one of multiple arguments in a one-argument type parameter' do + expect(yard_to_parlour_default('Array')).to eq \ + Types::Array.new(Types::Nilable.new('String')) + end + it 'handles whitespace' do expect(yard_to_parlour_default('Array < String >')).to eq Types::Array.new('String') end @@ -148,6 +154,7 @@ def self.path it 'handles correctly-formed two-argument type parameters with hash rockets' do expect(yard_to_parlour_default('HashSymbol>')).to eq Types::Hash.new('String', 'Symbol') expect(yard_to_parlour_default('Hash{String=>Symbol}')).to eq Types::Hash.new('String', 'Symbol') + expect(yard_to_parlour_default('Hash{String=>String}')).to eq Types::Hash.new('String', 'String') expect(yard_to_parlour_default('Hash{String => Symbol}')).to eq Types::Hash.new('String', 'Symbol') expect(yard_to_parlour_default('Hash{String, Integer => Symbol, Float}')).to eq \ Types::Hash.new( @@ -339,7 +346,7 @@ def self.path Sord::TypeConverter::Configuration.new( output_language: :rbs, replace_errors_with_untyped: false, - replace_unresolved_with_untyped: false, + replace_unresolved_with_untyped: false, ) end