Skip to content

Commit 1250332

Browse files
committed
Refactor: Extract Litral & Duck type classes
This could be useful for solargraph gem
1 parent 71eee3b commit 1250332

File tree

2 files changed

+46
-18
lines changed

2 files changed

+46
-18
lines changed

lib/yard/tags/types_explainer.rb

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -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
58+
"a literal value #{name}"
59+
end
60+
end
61+
62+
# @private
63+
class DuckType < Type
64+
def to_s
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

spec/tags/types_explainer_spec.rb

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
RSpec.describe YARD::Tags::TypesExplainer do
44
Type = YARD::Tags::TypesExplainer::Type
5+
LiteralType = YARD::Tags::TypesExplainer::LiteralType
6+
DuckType = YARD::Tags::TypesExplainer::DuckType
57
CollectionType = YARD::Tags::TypesExplainer::CollectionType
68
FixedCollectionType = YARD::Tags::TypesExplainer::FixedCollectionType
79
HashCollectionType = YARD::Tags::TypesExplainer::HashCollectionType
@@ -32,25 +34,29 @@ def parse_fail(types)
3234
expect(@t.to_s(false)).to eq "Arrays"
3335
end
3436

35-
it "works for a method (ducktype)" do
36-
@t.name = "#mymethod"
37-
expect(@t.to_s).to eq "an object that responds to #mymethod"
38-
expect(@t.to_s(false)).to eq "objects that respond to #mymethod"
39-
end
40-
4137
it "works for a constant value" do
4238
['false', 'true', 'nil', '4'].each do |name|
4339
@t.name = name
4440
expect(@t.to_s).to eq name
4541
expect(@t.to_s(false)).to eq name
4642
end
4743
end
44+
end
45+
46+
describe DuckType, '#to_s' do
47+
it "works for a method (ducktype)" do
48+
duck_type = DuckType.new("#mymethod")
49+
expect(duck_type.to_s).to eq "an object that responds to #mymethod"
50+
expect(duck_type.to_s(false)).to eq "objects that respond to #mymethod"
51+
end
52+
end
4853

54+
describe LiteralType, '#to_s' do
4955
it "works for literal values" do
5056
[':symbol', "'5'"].each do |name|
51-
@t.name = name
52-
expect(@t.to_s).to eq "a literal value #{name}"
53-
expect(@t.to_s(false)).to eq "a literal value #{name}"
57+
literal_type = LiteralType.new(name)
58+
expect(literal_type.to_s).to eq "a literal value #{name}"
59+
expect(literal_type.to_s(false)).to eq "a literal value #{name}"
5460
end
5561
end
5662
end
@@ -93,7 +99,7 @@ def parse_fail(types)
9399
end
94100
end
95101

96-
describe FixedCollectionType, '#to_s' do
102+
describe HashCollectionType, '#to_s' do
97103
before { @t = HashCollectionType.new("Hash", nil, nil) }
98104

99105
it "can contain a single key type and value type" do

0 commit comments

Comments
 (0)