class JsDuck::Process::Accessors

Expands accessors.

Looks up configs with @accessor tag (or configs defined inside config: {} or eventedConfig: {} block).

For such config “foo” it generates:

Public Class Methods

new(classes) click to toggle source
# File lib/jsduck/process/accessors.rb, line 18
def initialize(classes)
  @classes = classes
end

Public Instance Methods

process_all!() click to toggle source

Generates accessors in all classes.

# File lib/jsduck/process/accessors.rb, line 23
def process_all!
  @classes.each_value {|cls| process(cls) }
end

Private Instance Methods

add_shared(hash, cfg) click to toggle source

Copy over from @cfg all the fields that aren't already present.

# File lib/jsduck/process/accessors.rb, line 130
def add_shared(hash, cfg)
  ignored_fields = [
    # These don't make sense for methods and events.
    :type, :default,
    # It's the config that's tagged with these, don't propagate them to methods/events.
    :accessor, :evented,
    # The :doc field get auto-created and we don't want any other docs.
    :inheritdoc, :localdoc,
  ]

  cfg.each_pair do |key, value|
    hash[key] = value unless ignored_fields.include?(key) || hash[key]
  end
  hash
end
build_lookup_table(members, tagname) click to toggle source
# File lib/jsduck/process/accessors.rb, line 63
def build_lookup_table(members, tagname)
  map = {}
  members.each do |m|
    map[m[:name]] = m if m[:tagname] == tagname
  end
  map
end
create_event(cfg) click to toggle source
# File lib/jsduck/process/accessors.rb, line 101
def create_event(cfg)
  name = cfg[:name].downcase + "change"
  setter_name = "set" + upcase_first(cfg[:name]);
  return add_shared({
      :tagname => :event,
      :name => name,
      :doc => "Fires when the {@link ##{cfg[:id]}} configuration is changed by {@link #method-#{setter_name}}.",
      :params => [
        {
          :name => "this",
          :type => cfg[:owner],
          :doc => "The #{cfg[:owner]} instance."
        },
        {
          :name => "value",
          :type => cfg[:type],
          :doc => "The new value being set."
        },
        {
          :name => "oldValue",
          :type => cfg[:type],
          :doc => "The existing value."
        },
      ],
      :id => "event-" + name,
    }, cfg)
end
create_getter(cfg) click to toggle source
# File lib/jsduck/process/accessors.rb, line 71
def create_getter(cfg)
  name = "get" + upcase_first(cfg[:name])
  return add_shared({
      :tagname => :method,
      :name => name,
      :doc => "Returns the value of {@link #cfg-#{cfg[:name]}}.",
      :params => [],
      :return => {
        :type => cfg[:type],
        :doc => "",
      },
      :id => "method-" + name,
    }, cfg)
end
create_setter(cfg) click to toggle source
# File lib/jsduck/process/accessors.rb, line 86
def create_setter(cfg)
  name = "set" + upcase_first(cfg[:name]);
  return add_shared({
      :tagname => :method,
      :name => name,
      :doc => "Sets the value of {@link #cfg-#{cfg[:name]}}.",
      :params => [{
          :type => cfg[:type],
          :name => cfg[:name],
          :doc => "The new value.",
        }],
      :id => "method-" + name,
    }, cfg)
end
process(cls) click to toggle source

Given a class, generates accessor methods to configs with @accessor tag. Modifies the class by adding these methods. When class already contains a getter or setter, the method is not added.

# File lib/jsduck/process/accessors.rb, line 33
def process(cls)
  # Grab all configs tagged as @accessor
  accessors = cls[:members].find_all {|m| m[:tagname] == :cfg && m[:accessor] }

  # Build lookup tables of method and event names
  methods = build_lookup_table(cls[:members], :method)
  events = build_lookup_table(cls[:members], :event)

  accessors.each do |cfg|
    # add getter if no method with same name exists
    get = create_getter(cfg)
    if !methods[get[:name]]
      cls[:members] << get
    end
    # add setter if no method with same name exists
    set = create_setter(cfg)
    if !methods[set[:name]]
      cls[:members] << set
    end
    # for evented accessors
    if cfg[:evented]
      # add event if no event with same name exists
      ev = create_event(cfg)
      if !events[ev[:name]]
        cls[:members] << ev
      end
    end
  end
end
upcase_first(str) click to toggle source
# File lib/jsduck/process/accessors.rb, line 146
def upcase_first(str)
  str[0,1].upcase + str[1..-1]
end