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:



223
224
225
226
227
228
229
230
231
232
233
234
235
# File 'lib/yard/docstring.rb', line 223

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



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

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



281
282
283
284
# File 'lib/yard/docstring.rb', line 281

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



272
273
274
# File 'lib/yard/docstring.rb', line 272

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



138
139
140
141
142
143
144
145
# File 'lib/yard/docstring.rb', line 138

def dup
  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



264
265
266
# File 'lib/yard/docstring.rb', line 264

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

#lineFixnum?

Returns:



151
152
153
# File 'lib/yard/docstring.rb', line 151

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



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

def replace(content, parse = true)
  content = content.join("\n") if content.is_a?(Array)
  @tags, @ref_tags = [], []
  @all = content
  super(parse ? parse_comments(content) : content)
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.



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/yard/docstring.rb', line 157

def summary
  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:



246
247
248
# File 'lib/yard/docstring.rb', line 246

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:



254
255
256
257
258
# File 'lib/yard/docstring.rb', line 254

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



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/yard/docstring.rb', line 188

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