@@ -31,18 +31,14 @@ def initialize(name)
3131 end
3232
3333 def to_s ( singular = true )
34- if name [ 0 , 1 ] == "#"
35- singular ? "an object that responds to #{ name } " : "objects that respond to #{ name } "
36- elsif name [ 0 , 1 ] == ":" || ( name [ 0 , 1 ] =~ /['"]/ && name [ -1 , 1 ] =~ /['"]/ )
37- "a literal value #{ name } "
38- elsif name [ 0 , 1 ] =~ /[A-Z]/
34+ if name [ 0 , 1 ] =~ /[A-Z]/
3935 singular ? "a#{ name [ 0 , 1 ] =~ /[aeiou]/i ? 'n' : '' } " + name : "#{ name } #{ name [ -1 , 1 ] =~ /[A-Z]/ ? "'" : '' } s"
4036 else
4137 name
4238 end
4339 end
4440
45- private
41+ protected
4642
4743 def list_join ( list )
4844 index = 0
@@ -56,6 +52,20 @@ def list_join(list)
5652 end
5753 end
5854
55+ # @private
56+ class LiteralType < Type
57+ def to_s ( _singular = true )
58+ "a literal value #{ name } "
59+ end
60+ end
61+
62+ # @private
63+ class DuckType < Type
64+ def to_s ( singular = true )
65+ singular ? "an object that responds to #{ name } " : "objects that respond to #{ name } "
66+ end
67+ end
68+
5969 # @private
6070 class CollectionType < Type
6171 attr_accessor :types
@@ -137,7 +147,7 @@ def parse
137147 name = token
138148 when :type_next
139149 raise SyntaxError , "expecting name, got '#{ token } ' at #{ @scanner . pos } " if name . nil?
140- type = Type . new ( name ) unless type
150+ type = create_type ( name ) unless type
141151 types << type
142152 type = nil
143153 name = nil
@@ -150,14 +160,26 @@ def parse
150160 type = HashCollectionType . new ( name , parse , parse )
151161 when :hash_collection_next , :hash_collection_end , :fixed_collection_end , :collection_end , :parse_end
152162 raise SyntaxError , "expecting name, got '#{ token } '" if name . nil?
153- type = Type . new ( name ) unless type
163+ type = create_type ( name ) unless type
154164 types << type
155165 return types
156166 end
157167 end
158168 raise SyntaxError , "invalid character at #{ @scanner . peek ( 1 ) } " unless found
159169 end
160170 end
171+
172+ private
173+
174+ def create_type ( name )
175+ if name [ 0 , 1 ] == ":" || ( name [ 0 , 1 ] =~ /['"]/ && name [ -1 , 1 ] =~ /['"]/ )
176+ LiteralType . new ( name )
177+ elsif name [ 0 , 1 ] == "#"
178+ DuckType . new ( name )
179+ else
180+ Type . new ( name )
181+ end
182+ end
161183 end
162184 end
163185 end
0 commit comments