Class: YARD::Docstring

Inherits:
String
  • Object
show all
Defined in:
lib/yard/docstring.rb

Overview

A documentation string, or “docstring” for short, encapsulates the comments and metadata, or “tags”, of an object. Meta-data is expressed in the form @tag VALUE, where VALUE can span over multiple lines as long as they are indented. The following @example tag shows how tags can be indented:

# @example My example
#   a = "hello world"
#   a.reverse
# @version 1.0

Tags can be nested in a documentation string, though the Tags::Tag itself is responsible for parsing the inner tags.

Constant Summary collapse

META_MATCH =

Matches a tag at the start of a comment line

DocstringParser::META_MATCH

Class Attribute Summary collapse

Instance Attribute Summary collapse

Creating a Docstring Object collapse

Creating and Accessing Meta-data collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(content = '', object = nil) ⇒ Docstring

Note:

To properly parse directives with proper parser context within handlers, you should not use this method to create a Docstring. Instead, use the parser, which takes a handler object that can pass parser state onto directives. If a Docstring is created with this method, directives do not have access to any parser state, and may not function as expected.

Creates a new docstring with the raw contents attached to an optional object. Parsing will be done by the YARD::DocstringParser class.

Examples:

Docstring.new("hello world\n@return Object return", someobj)

Parameters:

  • content (String) (defaults to: '')

    the raw comments to be parsed into a docstring and associated meta-data.

  • object (CodeObjects::Base) (defaults to: nil)

    an object to associate the docstring with.



102
103
104
105
106
107
108
# File 'lib/yard/docstring.rb', line 102

def initialize(content = '', object = nil)
  @object = object
  @summary = nil
  @hash_flag = false

  self.all = content
end

Class Attribute Details

.default_parserClass<DocstringParser>

Note:

Plugin developers should make sure to reset this value after parsing finishes. This can be done via the Parser::SourceParser.after_parse_list callback. This will ensure that YARD can properly parse multiple projects in the same process.

Returns the parser class used to parse text and optional meta-data from docstrings. Defaults to YARD::DocstringParser.

Returns:

See Also:



27
28
29
# File 'lib/yard/docstring.rb', line 27

def default_parser
  @default_parser
end

Instance Attribute Details

#allString (readonly)

Returns the raw documentation (including raw tag text).

Returns:

  • (String)

    the raw documentation (including raw tag text)



52
53
54
# File 'lib/yard/docstring.rb', line 52

def all
  @all
end

#hash_flagBoolean

Returns whether the docstring was started with “##”.

Returns:

  • (Boolean)

    whether the docstring was started with “##”



55
56
57
# File 'lib/yard/docstring.rb', line 55

def hash_flag
  @hash_flag
end

#line_rangeRange

Returns line range in the #object‘s file where the docstring was parsed from.

Returns:

  • (Range)

    line range in the #object‘s file where the docstring was parsed from



49
50
51
# File 'lib/yard/docstring.rb', line 49

def line_range
  @line_range
end

#objectCodeObjects::Base

Returns the object that owns the docstring.

Returns:



46
47
48
# File 'lib/yard/docstring.rb', line 46

def object
  @object
end

#ref_tagsArray<Tags::RefTag> (readonly)

Returns the list of reference tags.

Returns:



43
44
45
# File 'lib/yard/docstring.rb', line 43

def ref_tags
  @ref_tags
end

Class Method Details

.new!(text, tags = [], object = nil, raw_data = nil, ref_object = nil) ⇒ Object

Creates a new docstring without performing any parsing through a YARD::DocstringParser. This method is called by DocstringParser when creating the new docstring object.

Parameters:

  • text (String)

    the textual portion of the docstring

  • tags (Array<Tag>) (defaults to: [])

    the list of tag objects in the docstring

  • object (CodeObjects::Base, nil) (defaults to: nil)

    the object associated with the docstring. May be nil.

  • raw_data (String) (defaults to: nil)

    the complete docstring, including all original formatting and any unparsed tags/directives.

  • ref_object (CodeObjects::Base, nil) (defaults to: nil)

    a reference object used for the base set of documentation / tag information.



76
77
78
79
80
81
82
83
84
# File 'lib/yard/docstring.rb', line 76

def self.new!(text, tags = [], object = nil, raw_data = nil, ref_object = nil)
  docstring = allocate
  docstring.replace(text, false)
  docstring.object = object
  docstring.add_tag(*tags)
  docstring.instance_variable_set("@unresolved_reference", ref_object)
  docstring.instance_variable_set("@all", raw_data) if raw_data
  docstring
end

.parser(*args) ⇒ DocstringParser

Creates a parser object using the current default_parser. Equivalent to:

Docstring.default_parser.new(*args)

Parameters:

Returns:



37
# File 'lib/yard/docstring.rb', line 37

def parser(*args) default_parser.new(*args) end

Instance Method Details

#+(other) ⇒ Docstring

Adds another YARD::Docstring, copying over tags.

Parameters:

Returns:

  • (Docstring)

    a new docstring with both docstrings combines



115
116
117
118
119
120
121
122
# File 'lib/yard/docstring.rb', line 115

def +(other)
  case other
  when Docstring
    Docstring.new([all, other.all].join("\n"), object)
  else
    super
  end
end

#add_tag(*tags) ⇒ void

This method returns an undefined value.

Adds a tag or reftag object to the tag list. If you want to parse tag data based on the Tags::DefaultFactory tag factory, use YARD::DocstringParser instead.

Parameters:



244
245
246
247
248
249
250
251
252
253
254
255
256
# File 'lib/yard/docstring.rb', line 244

def add_tag(*tags)
  tags.each_with_index do |tag, i|
    case tag
    when Tags::Tag
      tag.object = object
      @tags << tag
    when Tags::RefTag, Tags::RefTagList
      @ref_tags << tag
    else
      raise ArgumentError, "expected Tag or RefTag, got #{tag.class} (at index #{i})"
    end
  end
end

#blank?(only_visible_tags = true) ⇒ Boolean

Returns true if the docstring has no content that is visible to a template.

Parameters:

  • only_visible_tags (Boolean) (defaults to: true)

    whether only Tags::Library.visible_tags should be checked, or if all tags should be considered.

Returns:

  • (Boolean)

    whether or not the docstring has content



312
313
314
315
316
317
318
# File 'lib/yard/docstring.rb', line 312

def blank?(only_visible_tags = true)
  if only_visible_tags
    empty? && !tags.any? {|tag| Tags::Library.visible_tags.include?(tag.tag_name.to_sym) }
  else
    empty? && @tags.empty? && @ref_tags.empty?
  end
end

#delete_tag_if {|tag| ... } ⇒ void

This method returns an undefined value.

Deletes all tags where the block returns true

Yield Parameters:

  • tag (Tags::Tag)

    the tag that is being tested

Yield Returns:

  • (Boolean)

    true if the tag should be deleted

Since:

  • 0.7.0



302
303
304
305
# File 'lib/yard/docstring.rb', line 302

def delete_tag_if(&block)
  @tags.delete_if(&block)
  @ref_tags.delete_if(&block)
end

#delete_tags(name) ⇒ void

This method returns an undefined value.

Delete all tags with name

Parameters:

  • name (String)

    the tag name

Since:

  • 0.7.0



293
294
295
# File 'lib/yard/docstring.rb', line 293

def delete_tags(name)
  delete_tag_if {|tag| tag.tag_name.to_s == name.to_s }
end

#dupDocstring

Note:

This method creates a new docstring with new tag lists, but does not create new individual tags. Modifying the tag objects will still affect the original tags.

Deep-copies a docstring

Returns:

Since:

  • 0.7.0



151
152
153
154
155
156
157
158
159
# File 'lib/yard/docstring.rb', line 151

def dup
  resolve_reference
  obj = super
  %w(all summary tags ref_tags).each do |name|
    val = instance_variable_get("@#{name}")
    obj.instance_variable_set("@#{name}", val ? val.dup : nil)
  end
  obj
end

#has_tag?(name) ⇒ Boolean

Returns true if at least one tag by the name name was declared

Parameters:

  • name (String)

    the tag name to search for

Returns:

  • (Boolean)

    whether or not the tag name was declared



285
286
287
# File 'lib/yard/docstring.rb', line 285

def has_tag?(name)
  tags.any? {|tag| tag.tag_name.to_s == name.to_s }
end

#lineFixnum?

Returns:



165
166
167
# File 'lib/yard/docstring.rb', line 165

def line
  line_range ? line_range.first : nil
end

#replace(content, parse = true) ⇒ Object Also known as: all=

Replaces the docstring with new raw content. Called by #all=.

Parameters:

  • content (String)

    the raw comments to be parsed



131
132
133
134
135
136
137
138
139
140
141
# File 'lib/yard/docstring.rb', line 131

def replace(content, parse = true)
  content = content.join("\n") if content.is_a?(Array)
  @tags, @ref_tags = [], []
  if parse
    super(parse_comments(content))
  else
    @all = content
    @unresolved_reference = nil
    super(content)
  end
end

#resolve_referencevoid

This method returns an undefined value.

Resolves unresolved other docstring reference if there is unresolved reference. Does nothing if there is no unresolved reference.

Normally, you don’t need to call this method explicitly. Resolving unresolved reference is done implicitly.



330
331
332
333
334
335
336
337
338
# File 'lib/yard/docstring.rb', line 330

def resolve_reference
  loop do
    return if @unresolved_reference.nil?
    return if CodeObjects::Proxy === @unresolved_reference

    reference, @unresolved_reference = @unresolved_reference, nil
    self.all = [reference.docstring.all, @all].join("\n")
  end
end

#summaryString

Gets the first line of a docstring to the period or the first paragraph.

Returns:

  • (String)

    The first line or paragraph of the docstring; always ends with a period.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
# File 'lib/yard/docstring.rb', line 171

def summary
  resolve_reference
  return @summary if @summary
  stripped = self.gsub(/[\r\n](?![\r\n])/, ' ').strip
  num_parens = 0
  idx = length.times do |index|
    case stripped[index, 1]
    when "."
      next_char = stripped[index + 1, 1].to_s
      break index - 1 if num_parens <= 0 && next_char =~ /^\s*$/
    when "\r", "\n"
      next_char = stripped[index + 1, 1].to_s
      if next_char =~ /^\s*$/
        if stripped[index - 1, 1] == '.'
          break index - 2
        else
          break index - 1
        end
      end
    when "{", "(", "["
      num_parens += 1
    when "}", ")", "]"
      num_parens -= 1
    end
  end
  @summary = stripped[0..idx]
  if !@summary.empty? && @summary !~ /\A\s*\{include:.+\}\s*\Z/
    @summary += '.'
  end
  @summary
end

#tag(name) ⇒ Tags::Tag

Convenience method to return the first tag object in the list of tag objects of that name

Examples:

doc = Docstring.new("@return zero when nil")
doc.tag(:return).text  # => "zero when nil"

Parameters:

  • name (#to_s)

    the tag name to return data for

Returns:



267
268
269
# File 'lib/yard/docstring.rb', line 267

def tag(name)
  tags.find {|tag| tag.tag_name.to_s == name.to_s }
end

#tags(name = nil) ⇒ Array<Tags::Tag>

Returns a list of tags specified by name or all tags if name is not specified.

Parameters:

  • name (#to_s) (defaults to: nil)

    the tag name to return data for, or nil for all tags

Returns:



275
276
277
278
279
# File 'lib/yard/docstring.rb', line 275

def tags(name = nil)
  list = @tags + convert_ref_tags
  return list unless name
  list.select {|tag| tag.tag_name.to_s == name.to_s }
end

#to_rawString

TODO:

Add Tags::Tag#to_raw and refactor

Reformats and returns a raw representation of the tag data using the current tag and docstring data, not the original text.

Returns:

  • (String)

    the updated raw formatted docstring data

Since:

  • 0.7.0



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'lib/yard/docstring.rb', line 209

def to_raw
  tag_data = tags.sort_by {|t| t.tag_name }.map do |tag|
    case tag
    when Tags::OverloadTag
      tag_text = "@#{tag.tag_name} #{tag.signature}\n"
      unless tag.docstring.blank?
        tag_text += "\n  " + tag.docstring.all.gsub(/\r?\n/, "\n  ")
      end
    when Tags::OptionTag
      tag_text = "@#{tag.tag_name} #{tag.name}"
      tag_text += ' [' + tag.pair.types.join(', ') + ']' if tag.pair.types
      tag_text += ' ' + tag.pair.name.to_s if tag.pair.name
      tag_text += "\n " if tag.name && tag.text
      tag_text += ' (' + tag.pair.defaults.join(', ') + ')' if tag.pair.defaults
      tag_text += " " + tag.pair.text.strip.gsub(/\n/, "\n  ") if tag.pair.text
    else
      tag_text = '@' + tag.tag_name
      tag_text += ' [' + tag.types.join(', ') + ']' if tag.types
      tag_text += ' ' + tag.name.to_s if tag.name
      tag_text += "\n " if tag.name && tag.text
      tag_text += ' ' + tag.text.strip.gsub(/\n/, "\n  ") if tag.text
    end
    tag_text
  end
  [strip, tag_data.join("\n")].reject {|l| l.empty? }.compact.join("\n")
end

#to_sObject



124
125
126
127
# File 'lib/yard/docstring.rb', line 124

def to_s
  resolve_reference
  super
end