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.



99
100
101
102
103
104
105
# File 'lib/yard/docstring.rb', line 99

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) ⇒ 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.



74
75
76
77
78
79
80
81
# File 'lib/yard/docstring.rb', line 74

def self.new!(text, tags = [], object = nil, raw_data = nil)
  docstring = allocate
  docstring.replace(text, false)
  docstring.object = object
  docstring.add_tag(*tags)
  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



112
113
114
115
116
117
118
119
# File 'lib/yard/docstring.rb', line 112

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:



235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/yard/docstring.rb', line 235

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



303
304
305
306
307
308
309
# File 'lib/yard/docstring.rb', line 303

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



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

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



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

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



148
149
150
151
152
153
154
155
156
# File 'lib/yard/docstring.rb', line 148

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



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

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

#lineFixnum?

Returns:



162
163
164
# File 'lib/yard/docstring.rb', line 162

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



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/yard/docstring.rb', line 128

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.



321
322
323
324
325
326
327
328
329
330
331
# File 'lib/yard/docstring.rb', line 321

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

    reference, @unresolved_reference = @unresolved_reference, nil
    resolved_tags = reference.docstring.tags
    self.all = [reference.docstring.all, @all].join("\n")
    add_tag(*resolved_tags)
  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.



168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/yard/docstring.rb', line 168

def summary
  resolve_reference
  return @summary if @summary
  open_parens = ['{', '(', '[']
  close_parens = ['}', ')', ']']
  num_parens = 0
  idx = length.times do |index|
    case self[index, 1]
    when ".", "\r", "\n"
      next_char = self[index + 1, 1].to_s
      if num_parens == 0 && next_char =~ /^\s*$/
        break index - 1
      end
    when "{", "(", "["
      num_parens += 1
    when "}", ")", "]"
      num_parens -= 1
    end
  end
  @summary = self[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:



258
259
260
# File 'lib/yard/docstring.rb', line 258

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:



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

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



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/yard/docstring.rb', line 200

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



121
122
123
124
# File 'lib/yard/docstring.rb', line 121

def to_s
  resolve_reference
  super
end