Class: YARD::CodeObjects::Base Abstract
- Inherits:
-
Object
- Object
- YARD::CodeObjects::Base
- Defined in:
- lib/yard/code_objects/base.rb
Overview
This class is abstract. This class should not be used directly. Instead, create a subclass that implements #path, #sep or #type.
Base is the superclass of all code objects recognized by YARD. A code object is any entity in the Ruby language (class, method, module). A DSL might subclass Base to create a new custom object representing a new entity type.
Registry Integration
Any created object associated with a namespace is immediately registered with the registry. This allows the Registry to act as an identity map to ensure that no object is represented by more than one Ruby object in memory. A unique #path is essential for this identity map to work correctly.
Custom Attributes
Code objects allow arbitrary custom attributes to be set using the #[]= assignment method.
Namespaces
There is a special type of object called a “namespace”. These are subclasses of the NamespaceObject and represent Ruby entities that can have objects defined within them. Classically these are modules and classes, though a DSL might create a custom NamespaceObject to describe a specific set of objects.
Instance Attribute Summary
- - (Docstring) docstring The documentation string associated with the object.
- - (Boolean) dynamic Marks whether or not the method is conditionally defined at runtime.
- - (Array<String>) files readonly The files the object was defined in.
- - (NamespaceObject) namespace (also: #parent) The namespace the object is defined in.
- - (String) signature The one line signature representing an object.
- - (String?) source The source code associated with the object.
- - (Symbol) source_type Language of the source code associated with the object.
Class Method Summary
- + (Boolean) ==(other) Compares the class with subclasses.
- + (Base) new(namespace, name, *args, &block) Allocates a new code object.
Instance Method Summary
- - (Boolean) =(other) Tests if another object is equal to this, including a proxy.
- - (Object?) [](key) Accesses a custom attribute on the object.
- - (void) [](key, value) Sets a custom attribute on the object.
- - (Object) add_file(file, line = nil, has_comments = false) Associates a file with a code object, optionally adding the line where it was defined.
- - (Boolean) dynamic? Is the object defined conditionally at runtime?.
- - (String) file Returns the filename the object was first parsed at, taking definitions with docstrings first.
- - (String) format(options = {}) Renders the object using the templating system.
- - (String) format_source(source) protected Formats source code by removing leading indentation.
- - (Boolean) has_tag?(name) Tests if the #docstring has a tag.
- - (Base) initialize(namespace, name, *args) {|self| ... } constructor Creates a new code object.
- - (String) inspect Inspects the object, returning the type and path.
- - (Fixnum?) line Returns the line the object was first parsed at (or nil).
- - (Object) method_missing(meth, *args, &block) Checks if the method matches the name of an existing custom attribute.
- - (Symbol, String) name(prefix = false) The name of the object.
- - (Object) parent
- - (Object) parent
- - (String) path (also: #to_s) Represents the unique path of the object.
- - (String) relative_path(other) The shortest relative path from this object to other.
- - (Boolean) root? Whether or not this object is a RootObject.
- - (String) sep protected Override this method with a custom component separator.
- - (Object) tag(name) Gets a tag from the #docstring.
- - (Object) tags(name = nil) Gets a list of tags from the #docstring.
- - (Object) to_s
- - (Symbol) type Default type is the lowercase class name without the “Object” suffix.
Constructor Details
- (Base) initialize(namespace, name, *args) {|self| ... }
Creates a new code object
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 |
# File 'lib/yard/code_objects/base.rb', line 185 def initialize(namespace, name, *args) if namespace && namespace != :root && !namespace.is_a?(NamespaceObject) && !namespace.is_a?(Proxy) raise ArgumentError, "Invalid namespace object: #{namespace}" end @files = [] @current_file_has_comments = false @name = name.to_sym @source_type = :ruby @tags = [] @docstring = Docstring.new('', self) self.namespace = namespace yield(self) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
- (Object) method_missing(meth, *args, &block)
Checks if the method matches the name of an existing custom attribute.
289 290 291 292 293 294 295 296 297 |
# File 'lib/yard/code_objects/base.rb', line 289 def method_missing(meth, *args, &block) if meth.to_s =~ /=$/ self[meth.to_s[0..-2]] = args.first elsif instance_variable_get("@#{meth}") self[meth] else super end end |
Instance Attribute Details
- (Docstring) docstring
The documentation string associated with the object
117 118 119 |
# File 'lib/yard/code_objects/base.rb', line 117 def docstring @docstring end |
- (Boolean) dynamic
Marks whether or not the method is conditionally defined at runtime
121 122 123 |
# File 'lib/yard/code_objects/base.rb', line 121 def dynamic @dynamic end |
- (Array<String>) files (readonly)
The files the object was defined in. To add a file, use #add_file.
91 92 93 |
# File 'lib/yard/code_objects/base.rb', line 91 def files @files end |
- (NamespaceObject) namespace Also known as: parent
The namespace the object is defined in. If the object is in the top level namespace, this is Registry#root
96 97 98 |
# File 'lib/yard/code_objects/base.rb', line 96 def namespace @namespace end |
- (String) signature
The one line signature representing an object. For a method, this will be of the form “def meth(arguments…)”. This is usually the first source line.
113 114 115 |
# File 'lib/yard/code_objects/base.rb', line 113 def signature @signature end |
- (String?) source
The source code associated with the object
100 101 102 |
# File 'lib/yard/code_objects/base.rb', line 100 def source @source end |
- (Symbol) source_type
Language of the source code associated with the object. Defaults to :ruby.
106 107 108 |
# File 'lib/yard/code_objects/base.rb', line 106 def source_type @source_type end |
Class Method Details
+ (Boolean) ===(other)
Compares the class with subclasses
166 167 168 |
# File 'lib/yard/code_objects/base.rb', line 166 def ===(other) other.is_a?(self) end |
+ (Base) new(namespace, name, *args, &block)
Allocates a new code object
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/yard/code_objects/base.rb', line 131 def new(namespace, name, *args, &block) raise ArgumentError, "invalid empty object name" if name.to_s.empty? if name.to_s[0,2] == NSEP name = name.to_s[2..-1] namespace = Registry.root elsif name =~ /(?:#{NSEPQ}|#{ISEPQ}|#{CSEPQ})([^#{NSEPQ}#{ISEPQ}#{CSEPQ}]+)$/ return new(Proxy.new(namespace, $`), $1, *args, &block) end keyname = namespace && namespace.respond_to?(:path) ? namespace.path : '' if self == RootObject keyname = :root elsif self == MethodObject keyname += (args.first && args.first.to_sym == :class ? CSEP : ISEP) + name.to_s elsif keyname.empty? keyname = name.to_s else keyname += NSEP + name.to_s end obj = Registry.objects[keyname] obj = nil if obj && obj.class != self if self != RootObject && obj yield(obj) if block_given? obj else Registry.objects[keyname] = super(namespace, name, *args, &block) end end |
Instance Method Details
- (Boolean) ==(other)
Tests if another object is equal to this, including a proxy
250 251 252 253 254 255 256 |
# File 'lib/yard/code_objects/base.rb', line 250 def ==(other) if other.is_a?(Proxy) path == other.path else super end end |
- (Object?) [](key)
Accesses a custom attribute on the object
262 263 264 265 266 267 268 |
# File 'lib/yard/code_objects/base.rb', line 262 def [](key) if respond_to?(key) send(key) else instance_variable_get("@#{key}") end end |
- (void) []=(key, value)
This method returns an undefined value.
Sets a custom attribute on the object
275 276 277 278 279 280 281 |
# File 'lib/yard/code_objects/base.rb', line 275 def []=(key, value) if respond_to?("#{key}=") send("#{key}=", value) else instance_variable_set("@#{key}", value) end end |
- (Object) add_file(file, line = nil, has_comments = false)
Associates a file with a code object, optionally adding the line where it
was defined. By convention, ’
219 220 221 222 223 224 225 226 227 228 |
# File 'lib/yard/code_objects/base.rb', line 219 def add_file(file, line = nil, has_comments = false) raise(ArgumentError, "file cannot be nil or empty") if file.nil? || file == '' obj = [file.to_s, line] if has_comments && !@current_file_has_comments @current_file_has_comments = true @files.unshift(obj) else @files << obj # back of the line end end |
- (Boolean) dynamic?
Is the object defined conditionally at runtime?
125 |
# File 'lib/yard/code_objects/base.rb', line 125 def dynamic?; @dynamic end |
- (String) file
Returns the filename the object was first parsed at, taking definitions with docstrings first.
234 235 236 |
# File 'lib/yard/code_objects/base.rb', line 234 def file @files.first ? @files.first[0] : nil end |
- (String) format(options = {})
Renders the object using the templating system.
371 372 373 374 |
# File 'lib/yard/code_objects/base.rb', line 371 def format( = {}) .merge!(:object => self) Templates::Engine.render() end |
- (String) format_source(source) (protected)
Formats source code by removing leading indentation
434 435 436 437 438 439 |
# File 'lib/yard/code_objects/base.rb', line 434 def format_source(source) source.chomp! last = source.split(/\r?\n/).last indent = last ? last[/^([ \t]*)/, 1].length : 0 source.gsub(/^[ \t]{#{indent}}/, '') end |
- (Boolean) has_tag?(name)
Tests if the #docstring has a tag
414 |
# File 'lib/yard/code_objects/base.rb', line 414 def has_tag?(name); @docstring.has_tag?(name) end |
- (String) inspect
Inspects the object, returning the type and path
378 379 380 |
# File 'lib/yard/code_objects/base.rb', line 378 def inspect "#<yardoc #{type} #{path}>" end |
- (Fixnum?) line
Returns the line the object was first parsed at (or nil)
242 243 244 |
# File 'lib/yard/code_objects/base.rb', line 242 def line @files.first ? @files.first[1] : nil end |
- (Symbol, String) name(prefix = false)
The name of the object
207 208 209 |
# File 'lib/yard/code_objects/base.rb', line 207 def name(prefix = false) prefix ? @name.to_s : @name end |
- (Object) parent
401 402 403 |
# File 'lib/yard/code_objects/base.rb', line 401 def namespace @namespace end |
- (Object) parent=
402 403 404 405 406 407 408 409 410 411 412 413 414 |
# File 'lib/yard/code_objects/base.rb', line 402 def namespace=(obj) if @namespace @namespace.children.delete(self) Registry.delete(self) end @namespace = (obj == :root ? Registry.root : obj) if @namespace @namespace.children << self unless @namespace.is_a?(Proxy) Registry.register(self) end end |
- (String) path Also known as: to_s
Represents the unique path of the object. The default implementation joins the path of #namespace with #name via the value of #sep. Custom code objects should ensure that the path is unique to the code object by either overriding #sep or this method.
341 342 343 344 345 346 347 |
# File 'lib/yard/code_objects/base.rb', line 341 def path if parent && !parent.root? [parent.path, name.to_s].join(sep) else name.to_s end end |
- (String) relative_path(other)
The shortest relative path from this object to other
352 353 354 355 356 |
# File 'lib/yard/code_objects/base.rb', line 352 def relative_path(other) other = other.path if other.respond_to?(:path) return other unless namespace other.gsub(/^#{Regexp.quote namespace.path}(::|\.)?/, '') end |
- (Boolean) root?
Whether or not this object is a RootObject
417 |
# File 'lib/yard/code_objects/base.rb', line 417 def root?; false end |
- (String) sep (protected)
Override this method with a custom component separator. For instance, MethodObject implements sep as ’#’ or ’.’ (depending on if the method is instance or class respectively). #path depends on this value to generate the full path in the form: namespace.path + sep + name
428 |
# File 'lib/yard/code_objects/base.rb', line 428 def sep; NSEP end |
- (Object) tag(name)
Gets a tag from the #docstring
406 |
# File 'lib/yard/code_objects/base.rb', line 406 def tag(name); @docstring.tag(name) end |
- (Object) tags(name = nil)
Gets a list of tags from the #docstring
410 |
# File 'lib/yard/code_objects/base.rb', line 410 def (name = nil); @docstring.(name) end |
- (Object) to_s
348 349 350 351 352 353 354 |
# File 'lib/yard/code_objects/base.rb', line 348 def path if parent && !parent.root? [parent.path, name.to_s].join(sep) else name.to_s end end |
- (Symbol) type
Default type is the lowercase class name without the “Object” suffix. Override this method to provide a custom object type
328 329 330 |
# File 'lib/yard/code_objects/base.rb', line 328 def type self.class.name.split(/#{NSEPQ}/).last.gsub(/Object$/, '').downcase.to_sym end |