Commit 3686ee96 authored by Rene Saarsoo's avatar Rene Saarsoo
Browse files

Move all processor classes to process/ subdir.

To clean up extra cruft from the main /lib/jsduck dir.
parent 35f6161b
Loading
Loading
Loading
Loading

lib/jsduck/accessors.rb

deleted100644 → 0
+0 −135
Original line number Diff line number Diff line
require 'jsduck/logger'

module JsDuck

  class Accessors
    def initialize(classes)
      @classes = classes
    end

    # Generates accessors in all classes.
    def process_all!
      @classes.each_value {|cls| process(cls) }
    end

    # 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.
    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

    def build_lookup_table(members, tagname)
      map = {}
      members.each do |m|
        map[m[:name]] = m if m[:tagname] == tagname
      end
      map
    end

    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

    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 => "",
          }],
        :return => {
          :type => "undefined",
          :doc => "",
        },
        :id => "method-" + name,
      }, cfg)
    end

    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

    def add_shared(hash, cfg)
      hash.merge!({
        :owner => cfg[:owner],
        :files => cfg[:files],
        :private => cfg[:private],
        :protected => cfg[:protected],
        :autodetected => cfg[:autodetected],
        :hide => cfg[:hide],
      })
    end

    def upcase_first(str)
      str[0,1].upcase + str[1..-1]
    end
  end

end
+20 −20
Original line number Diff line number Diff line
@@ -2,19 +2,19 @@ require 'jsduck/util/parallel'
require 'jsduck/util/io'
require 'jsduck/source/file'
require 'jsduck/aggregator'
require 'jsduck/ignore'
require 'jsduck/enum'
require 'jsduck/accessors'
require 'jsduck/ext4_events'
require 'jsduck/override'
require 'jsduck/class'
require 'jsduck/relations'
require 'jsduck/logger'
require 'jsduck/inherit_doc'
require 'jsduck/importer'
require 'jsduck/return_values'
require 'jsduck/lint'
require 'jsduck/circular_deps'
require 'jsduck/process/ignore'
require 'jsduck/process/enum'
require 'jsduck/process/accessors'
require 'jsduck/process/ext4_events'
require 'jsduck/process/override'
require 'jsduck/process/inherit_doc'
require 'jsduck/process/importer'
require 'jsduck/process/return_values'
require 'jsduck/process/lint'
require 'jsduck/process/circular_deps'

module JsDuck

@@ -64,12 +64,12 @@ module JsDuck
      agr.create_global_class
      classes = agr.classes

      Ignore.new(classes).process_all!
      Accessors.new(classes).process_all!
      Ext4Events.new(classes, @opts).process_all!
      Enum.new(classes).process_all!
      Process::Ignore.new(classes).process_all!
      Process::Accessors.new(classes).process_all!
      Process::Ext4Events.new(classes, @opts).process_all!
      Process::Enum.new(classes).process_all!
      # Ignore override classes after applying them to actual classes
      @opts.external_classes += Override.new(classes).process_all!
      @opts.external_classes += Process::Override.new(classes).process_all!

      classes.values
    end
@@ -102,11 +102,11 @@ module JsDuck

    # Do all kinds of post-processing on relations.
    def apply_extra_processing
      CircularDeps.new(@relations).process_all!
      InheritDoc.new(@relations).process_all!
      Importer.new(@relations, @opts).process_all!
      ReturnValues.new(@relations).process_all!
      Lint.new(@relations).process_all!
      Process::CircularDeps.new(@relations).process_all!
      Process::InheritDoc.new(@relations).process_all!
      Process::Importer.new(@relations, @opts).process_all!
      Process::ReturnValues.new(@relations).process_all!
      Process::Lint.new(@relations).process_all!
    end

  end

lib/jsduck/circular_deps.rb

deleted100644 → 0
+0 −56
Original line number Diff line number Diff line
require 'jsduck/logger'

module JsDuck

  # Checks for circular dependencies
  class CircularDeps
    def initialize(classes)
      @classes = classes
    end

    # Checks all classes for circular dependencies.
    #
    # When found, exits with a fatal error message.
    def process_all!
      @classes.each do |cls|
        if chain = check(cls)
          Logger.fatal("Class #{cls[:name]} has a circular dependency: #{chain}")
          exit 1
        end
      end
    end

    # Checks class for circular dependencies.
    #
    # When all OK, returns false.
    #
    # When circular dependencies found returns a string describing the
    # problematic dependency chain e.g. "Foo extends Bar mixins Foo".
    def check(cls, names = [])
      names += [cls[:name]]

      if cls.parent && chain = track_circular(" extends ", cls.parent, names)
        return chain
      end

      cls.mixins.each do |mixin|
        if chain = track_circular(" mixins ", mixin, names)
          return chain
        end
      end

      false
    end

    def track_circular(type, cls, names)
      names += [type]
      if names.include?(cls[:name])
        (names + [cls[:name]]).join("")
      else
        check(cls, names)
      end
    end

  end

end

lib/jsduck/enum.rb

deleted100644 → 0
+0 −72
Original line number Diff line number Diff line
module JsDuck

  class Enum
    def initialize(classes)
      @classes = classes
    end

    # Applies additional processing to all enum-classes.
    def process_all!
      @classes.each_value do |cls|
        if cls[:enum]
          process(cls)
        end
      end
    end

    private

    # processes single class
    def process(cls)
      expand_default(cls)
      strip_inheritdoc(cls)
      cls[:enum][:type] = infer_type(cls) unless cls[:enum][:type]
    end

    # Given an enum class, returns the type infered from its values.
    def infer_type(cls)
      if cls[:members].length > 0
        types = cls[:members].map {|p| p[:type] }
        types.sort.uniq.join("/")
      else
        "Object"
      end
    end

    # Expands default value like widget.* into list of properties
    def expand_default(cls)
      if cls[:enum][:default] =~ /\A(.*)\.\*\Z/
        each_alias($1) do |name, owner|
          cls[:members] << {
            :tagname => :property,
            :id => 'property-' + name,
            :name => name,
            :default => "'" + name + "'",
            :type => "String",
            :private => owner[:private],
            :files => cls[:files],
            :owner => cls[:name],
            :doc => "Alias for {@link #{owner[:name]}}.",
          }
        end
      end
    end

    def each_alias(prefix)
      @classes.each_value do |cls|
        if cls[:aliases] && cls[:aliases][prefix]
          cls[:aliases][prefix].each {|name| yield(name, cls) }
        end
      end
    end

    # Remove the auto-inserted inheritdoc tag so the auto-detected enum
    # values default to being public.
    def strip_inheritdoc(cls)
      cls[:members].each do |p|
        p[:inheritdoc] = nil if p[:autodetected]
      end
    end
  end

end

lib/jsduck/ext4_events.rb

deleted100644 → 0
+0 −41
Original line number Diff line number Diff line
module JsDuck

  # Appends Ext4 options parameter to the parameter list of each event
  # in each class.
  #
  # But only does so when :ext4_events option is set to true or the
  # code itself is detected as being writted in Ext4 style.
  class Ext4Events
    def initialize(classes, opts={})
      @classes = classes
      @opts = opts
    end

    def process_all!
      if @opts[:ext4_events] == true || (@opts[:ext4_events] == nil && ext4_style_code?)
        @classes.each_value {|cls| process(cls) }
      end
    end

    # Are we dealing with code looking like ExtJS 4?
    # True if any of the classes is defined with Ext.define()
    def ext4_style_code?
      @classes.values.any? {|cls| cls[:code_type] == :ext_define }
    end

    def process(cls)
      cls[:members].each do |m|
        m[:params] << OPTIONS if m[:tagname] == :event
      end
    end

    OPTIONS = {
      :tagname => :param,
      :name => "eOpts",
      :type => "Object",
      :doc => "The options object passed to {@link Ext.util.Observable#addListener}."
    }

  end

end
Loading