Class: YARD::CodeObjects::MacroObject

Inherits:
Base
  • Object
show all
Defined in:
lib/yard/code_objects/macro_object.rb

Overview

A MacroObject represents a docstring defined through @macro NAME and can be reused by specifying the tag @macro NAME. You can also provide the attached type flag to the macro definition to have it attached to the specific DSL method so it will be implicitly reused.

Macros are fully described in the Tags Overview document.

Examples:

Creating a basic named macro

# @macro prop
# @method $1(${3-})
# @return [$2] the value of the $0
property :foo, String, :a, :b

# @macro prop
property :bar, Numeric, :value

Creating a macro that is attached to the method call

# @macro [attach] prop2
# @method $1(value)
property :foo

# Extra data added to docstring
property :bar

Constant Summary collapse

MACRO_MATCH =
/(\\)?\$(?:\{(-?\d+|\*)(-)?(-?\d+)?\}|(-?\d+|\*))/

Instance Attribute Summary collapse

Attributes inherited from Base

#docstring, #dynamic, #files, #group, #namespace, #signature, #source, #source_type, #visibility

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

===, #[], #[]=, #add_file, #dynamic?, #equal?, #file, #format, #format_source, #has_tag?, #hash, #initialize, #inspect, #line, #method_missing, #name, new, #relative_path, #root?, #tag, #tags, #type

Constructor Details

This class inherits a constructor from YARD::CodeObjects::Base

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class YARD::CodeObjects::Base

Instance Attribute Details

#macro_dataString

Returns the macro data stored on the object.

Returns:

  • (String)

    the macro data stored on the object



189
190
191
# File 'lib/yard/code_objects/macro_object.rb', line 189

def macro_data
  @macro_data
end

#method_objectCodeObjects::Base

Returns the method object that this macro is attached to.

Returns:



193
194
195
# File 'lib/yard/code_objects/macro_object.rb', line 193

def method_object
  @method_object
end

Class Method Details

.apply(docstring, call_params = [], full_source = '', block_source = '', method_object = nil) ⇒ String

Applies a macro on a docstring by creating any macro data inside of the docstring first. Equivalent to calling find_or_create and apply_macro on the new macro object.

Parameters:

  • docstring (Docstring)

    the docstring to create a macro out of

  • call_params (Array<String>) (defaults to: [])

    the method name and parameters to the method call. These arguments will fill $0-N

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

    the full source line (excluding block) interpolated as $*

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

    Currently unused. Will support interpolating the block data as a variable.

Returns:

  • (String)

    the expanded macro data

See Also:



120
121
122
123
# File 'lib/yard/code_objects/macro_object.rb', line 120

def apply(docstring, call_params = [], full_source = '', block_source = '', method_object = nil)
  macro = find_or_create(docstring, method_object)
  apply_macro(macro, docstring, call_params, full_source, block_source)
end

.apply_macro(macro, docstring, call_params = [], full_source = '', block_source = '') ⇒ String

Applies a macro to a docstring, interpolating the macro’s data on the docstring and appending any extra local docstring data that was in the original docstring object.

Parameters:

  • macro (MacroObject)

    the macro object

  • call_params (Array<String>) (defaults to: [])

    the method name and parameters to the method call. These arguments will fill $0-N

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

    the full source line (excluding block) interpolated as $*

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

    Currently unused. Will support interpolating the block data as a variable.

Returns:

  • (String)

    the expanded macro data



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

def apply_macro(macro, docstring, call_params = [], full_source = '', block_source = '')
  docstring = Docstring.new(docstring) unless Docstring === docstring
  data = []
  data << macro.expand(call_params, full_source, block_source) if macro
  if !macro && new_macro?(docstring)
    data << expand(macro_data(docstring), call_params, full_source, block_source)
  end
  data << nonmacro_data(docstring)
  data.join("\n").strip
end

.create(macro_name, data, method_object = nil) ⇒ MacroObject

Creates a new macro and fills in the relevant properties.

Parameters:

  • macro_name (String)

    the name of the macro, must be unique.

  • data (String)

    the data the macro should expand when re-used

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

    an object to attach this macro to. If supplied, #attached? will be true

Returns:



37
38
39
40
41
42
# File 'lib/yard/code_objects/macro_object.rb', line 37

def create(macro_name, data, method_object = nil)
  obj = new(:root, macro_name)
  obj.macro_data = data
  obj.method_object = method_object
  obj
end

.expand(macro_data, call_params = [], full_source = '', block_source = '') ⇒ Object

Expands macro_data using the interpolation parameters.

Interpolation rules:

  • $0, $1, $2, … = the Nth parameter in call_params

  • $* = the full statement source (excluding block)

  • Also supports ${N-M} ranges, as well as negative indexes on N or M

  • Use $ to escape the variable name in a macro.

Parameters:



96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/yard/code_objects/macro_object.rb', line 96

def expand(macro_data, call_params = [], full_source = '', block_source = '')
  macro_data = macro_data.all if macro_data.is_a?(Docstring)
  macro_data.gsub(MACRO_MATCH) do
    escape, first, last, rng = $1, $2 || $5, $4, $3 ? true : false
    next $&[1..-1] if escape
    if first == '*'
      last ? $& : full_source
    else
      first_i = first.to_i
      last_i = (last ? last.to_i : call_params.size)
      last_i = first_i unless rng
      params = call_params[first_i..last_i]
      params ? params.join(", ") : ''
    end
  end
end

.find(macro_name) ⇒ MacroObject?

Finds a macro using macro_name

Returns:

  • (MacroObject)

    if a macro is found

  • (nil)

    if there is no registered macro by that name



47
48
49
# File 'lib/yard/code_objects/macro_object.rb', line 47

def find(macro_name)
  Registry.at('.macro.' + macro_name.to_s)
end

.find_or_create(data, method_object = nil) ⇒ MacroObject? Also known as: create_docstring

Parses a given docstring and determines if the macro is “new” or not. If the macro has $variable names or if it has a @macro tag with the [new] or [attached] flag, it is considered new.

If a new macro is found, the macro is created and registered. Otherwise the macro name is searched and returned. If a macro is not found, nil is returned.

Parameters:

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

    an optional method to attach the macro to. Only used if the macro is being created, otherwise this argument is ignored.

Returns:

  • (MacroObject)

    the newly created or existing macro, depending on whether the @macro tag was a new tag or not.

  • (nil)

    if the data has no macro tag or if the macro is not new and no macro by the macro name is found.



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/yard/code_objects/macro_object.rb', line 66

def find_or_create(data, method_object = nil)
  docstring = Docstring === data ? data : Docstring.new(data)
  return unless docstring.tag(:macro)
  return unless name = macro_name(docstring)
  if new_macro?(docstring)
    method_object = nil unless attached_macro?(docstring, method_object)
    create(name, macro_data(docstring), method_object)
  else
    find(name)
  end
end

Instance Method Details

#attached?Boolean

Returns whether this macro is attached to a method.

Returns:

  • (Boolean)

    whether this macro is attached to a method



196
# File 'lib/yard/code_objects/macro_object.rb', line 196

def attached?; method_object ? true : false end

#expand(call_params = [], full_source = '', block_source = '') ⇒ Object

Expands the macro using

Examples:

Expanding a Macro

macro.expand(%w(property foo bar), 'property :foo, :bar', '') #=>
  "...macro data interpolating this line of code..."

Parameters:

  • call_params (Array<String>) (defaults to: [])

    a list of tokens that are passed to the method call

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

    the full method call (not including the block)

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

    the source passed in the block of the method call, if there is a block.

See Also:



210
211
212
# File 'lib/yard/code_objects/macro_object.rb', line 210

def expand(call_params = [], full_source = '', block_source = '')
  self.class.expand(macro_data, call_params, full_source, block_source)
end

#pathObject



197
# File 'lib/yard/code_objects/macro_object.rb', line 197

def path; '.macro.' + name.to_s end

#sepObject



198
# File 'lib/yard/code_objects/macro_object.rb', line 198

def sep; '.' end