# Class: YARD::Handlers::Processor

Inherits:
  Object
  - Object
  - YARD::Handlers::Processor
  show all

Defined in:
  lib/yard/handlers/processor.rb

## Overview

Iterates over all statements in a file and delegates them to the Base objects that are registered to handle the statement.

This class is passed to each handler and keeps overall processing state. For example, if the #visibility is set in a handler, all following statements will have access to this state. This allows “public”, “protected” and “private” statements to be handled in classes and modules. In addition, the #namespace can be set during parsing to control where objects are being created from. You can also access extra stateful properties that any handler can set during the duration of the post processing of a file from #extra_state. If you need to access state across different files, look at #globals.

See Also:

- Base

## Instance Attribute Summary collapse

- #extra_state ⇒ OpenStruct

  Share state across different handlers inside of a file.

- #file ⇒ String

  The filename.

- #globals ⇒ OpenStruct

  Handlers can share state for the entire post processing stage through this attribute.

- #namespace ⇒ CodeObjects::NamespaceObject

  The current namespace.

- #owner ⇒ CodeObjects::Base?

  Unlike the namespace, the owner is a non-namespace object that should be stored between statements.

- #parser_type ⇒ Symbol

  The parser type (:ruby, :ruby18, :c).

- #scope ⇒ Symbol

  The current scope (class, instance).

- #visibility ⇒ Symbol

  The current visibility (public, private, protected).

## Class Method Summary collapse

- .register_handler_namespace(type, ns) ⇒ Object

  Registers a new namespace for handlers of the given type.

## Instance Method Summary collapse

- #find_handlers(statement) ⇒ Array<Base>

  Searches for all handlers in Base.subclasses that match the `statement`.

- #initialize(parser) ⇒ Processor constructor

  Creates a new Processor for a `file`.

- #parse_remaining_files ⇒ void

  Continue parsing the remainder of the files in the `globals.ordered_parser` object.

- #process(statements) ⇒ void

  Processes a list of statements by finding handlers to process each one.

## Constructor Details

### #initialize(parser) ⇒ `Processor`

Creates a new Processor for a `file`.

Parameters:

- parser (`Parser::SourceParser`) —

  the parser used to initialize the processor

    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102

    # File 'lib/yard/handlers/processor.rb', line 91

    def initialize(parser)
      @file = parser.file || "(stdin)"
      @namespace = YARD::Registry.root
      @visibility = :public
      @scope = :instance
      @owner = @namespace
      @parser_type = parser.parser_type
      @handlers_loaded = {}
      @globals = parser.globals || OpenStruct.new
      @extra_state = OpenStruct.new
      load_handlers
    end

## Instance Attribute Details

### #extra_state ⇒ `OpenStruct`

Share state across different handlers inside of a file. This attribute is similar to #visibility, #scope, #namespace and #owner, in that they all maintain state across all handlers for the entire source file. Use this attribute to store any data your handler might need to save during the parsing of a file. If you need to save state across files, see #globals.

Returns:

- (`OpenStruct`) —

  an open structure that can store arbitrary data

See Also:

- #globals

    87
    88
    89

    # File 'lib/yard/handlers/processor.rb', line 87

    def extra_state
      @extra_state
    end

### #file ⇒ `String`

Returns the filename.

Returns:

- (`String`) —

  the filename

    40
    41
    42

    # File 'lib/yard/handlers/processor.rb', line 40

    def file
      @file
    end

### #globals ⇒ `OpenStruct`

Handlers can share state for the entire post processing stage through this attribute. Note that post processing stage spans multiple files. To share state only within a single file, use #extra_state

#### Examples:

#####

Sharing state among two handlers

    class Handler1 < YARD::Handlers::Ruby::Base
      handles :class
      process { globals.foo = :bar }
    end

    class Handler2 < YARD::Handlers::Ruby::Base
      handles :method
      process { puts globals.foo }
    end

Returns:

- (`OpenStruct`) —

  global shared state for post-processing stage

See Also:

- #extra_state

    76
    77
    78

    # File 'lib/yard/handlers/processor.rb', line 76

    def globals
      @globals
    end

### #namespace ⇒ `CodeObjects::NamespaceObject`

Returns the current namespace.

Returns:

- (`CodeObjects::NamespaceObject`) —

  the current namespace

    43
    44
    45

    # File 'lib/yard/handlers/processor.rb', line 43

    def namespace
      @namespace
    end

### #owner ⇒ `CodeObjects::Base`?

Returns unlike the namespace, the owner is a non-namespace object that should be stored between statements. For instance, when parsing a method body, the CodeObjects::MethodObject is set as the owner, in case any extra method information is processed.

Returns:

- (`CodeObjects::Base`, `nil`) —

  unlike the namespace, the owner is a non-namespace object that should be stored between statements. For instance, when parsing a method body, the CodeObjects::MethodObject is set as the owner, in case any extra method information is processed.

    55
    56
    57

    # File 'lib/yard/handlers/processor.rb', line 55

    def owner
      @owner
    end

### #parser_type ⇒ `Symbol`

Returns the parser type (:ruby, :ruby18, :c).

Returns:

- (`Symbol`) —

  the parser type (:ruby, :ruby18, :c)

    58
    59
    60

    # File 'lib/yard/handlers/processor.rb', line 58

    def parser_type
      @parser_type
    end

### #scope ⇒ `Symbol`

Returns the current scope (class, instance).

Returns:

- (`Symbol`) —

  the current scope (class, instance)

    49
    50
    51

    # File 'lib/yard/handlers/processor.rb', line 49

    def scope
      @scope
    end

### #visibility ⇒ `Symbol`

Returns the current visibility (public, private, protected).

Returns:

- (`Symbol`) —

  the current visibility (public, private, protected)

    46
    47
    48

    # File 'lib/yard/handlers/processor.rb', line 46

    def visibility
      @visibility
    end

## Class Method Details

### .register_handler_namespace(type, ns) ⇒ `Object`

Registers a new namespace for handlers of the given type.

Since:

- 0.6.0

    23
    24
    25

    # File 'lib/yard/handlers/processor.rb', line 23

    def register_handler_namespace(type, ns)
      namespace_for_handler[type] = ns
    end

## Instance Method Details

### #find_handlers(statement) ⇒ `Array<Base>`

Searches for all handlers in Base.subclasses that match the `statement`

Parameters:

- statement —

  the statement object to match.

Returns:

- (`Array<Base>`) —

  a list of handlers to process the statement with.

    150
    151
    152
    153
    154
    155
    156

    # File 'lib/yard/handlers/processor.rb', line 150

    def find_handlers(statement)
      Base.subclasses.find_all do |handler|
        handler_base_class > handler &&
          (handler.namespace_only? ? owner.is_a?(CodeObjects::NamespaceObject) : true) &&
          handles?(handler, statement)
      end
    end

### #parse_remaining_files ⇒ `void`

This method returns an undefined value.

Continue parsing the remainder of the files in the `globals.ordered_parser` object. After the remainder of files are parsed, processing will continue on the current file.

See Also:

- Parser::OrderedParser

    139
    140
    141
    142
    143
    144

    # File 'lib/yard/handlers/processor.rb', line 139

    def parse_remaining_files
      if globals.ordered_parser
        globals.ordered_parser.parse
        log.debug("Re-processing #{@file}...")
      end
    end

### #process(statements) ⇒ `void`

This method returns an undefined value.

Processes a list of statements by finding handlers to process each one.

Parameters:

- statements (`Array`) —

  a list of statements

    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131

    # File 'lib/yard/handlers/processor.rb', line 109

    def process(statements)
      statements.each_with_index do |stmt, _index|
        find_handlers(stmt).each do |handler|
          begin
            handler.new(self, stmt).process
          rescue HandlerAborted
            log.debug "#{handler} cancelled from #{caller.last}"
            log.debug "\tin file '#{file}':#{stmt.line}:\n\n" + stmt.show + "\n"
          rescue NamespaceMissingError => missingerr
            log.warn "The #{missingerr.object.type} #{missingerr.object.path} has not yet been recognized.\n" \
                     "If this class/method is part of your source tree, this will affect your documentation results.\n" \
                     "You can correct this issue by loading the source file for this object before `#{file}'\n"
          rescue Parser::UndocumentableError => undocerr
            log.warn "in #{handler}: Undocumentable #{undocerr.message}\n" \
                     "\tin file '#{file}':#{stmt.line}:\n\n" + stmt.show + "\n"
          rescue => e
            log.error "Unhandled exception in #{handler}:\n" \
                      "  in `#{file}`:#{stmt.line}:\n\n#{stmt.show}\n"
            log.backtrace(e)
          end
        end
      end
    end