Module: Coradoc::AsciiDoc::Parser::RuleDispatcher

Defined in:
lib/coradoc/asciidoc/parser/rule_dispatcher.rb

Overview

Wraps every parser rule for Parslet memoization.

Parameterized rules (e.g., ‘block_style(n_deep, delimiter, repeater)`) cannot be memoized by Parslet directly because their result depends on the args. This module aliases each rule to a per-args dispatch rule so Parslet sees a memoizable, parameterless rule for every (rule_name, args) combination. Parameterless rules get a single memoized alias.

Also warns when a parser method is defined in more than one parser module — duplicate definitions are usually a refactoring mistake and produce confusing “last one wins” behavior at include time.

Invoked once at Parser::Base load time.

Constant Summary collapse

DISPATCH_CONFIG =
{
  add_dispatch: true,
  with_params: true
}.freeze

Class Method Summary collapse

Class Method Details

.apply(parser_class) ⇒ Object

Parameters:

  • parser_class (Class)

    Parser::Base or a subclass



28
29
30
31
32
# File 'lib/coradoc/asciidoc/parser/rule_dispatcher.rb', line 28

def apply(parser_class)
  parser_methods = collect_rule_names
  warn_on_duplicates(parser_methods)
  wrap_rules(parser_class, parser_methods)
end

.dispatch(parser_instance, alias_name, *args, **kwargs) ⇒ Object

Per-instance dispatch invoked from the parameterized rule wrappers.

Parameters:

  • parser_instance (Parser::Base)
  • alias_name (Symbol)

    The alias created at wrap time

  • args (Array)
  • kwargs (Hash)


39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/coradoc/asciidoc/parser/rule_dispatcher.rb', line 39

def dispatch(parser_instance, alias_name, *args, **kwargs)
  cache = dispatch_cache(parser_instance)
  key = dispatch_key(alias_name, args, kwargs)
  unless cache.key?(key)
    rule_name = dispatch_rule_name(alias_name, key)
    unless parser_instance.respond_to?(rule_name)
      build_dispatch_rule(parser_instance.class, alias_name,
                          rule_name, args, kwargs)
    end
    cache[key] = rule_name
  end
  parser_instance.public_send(cache[key])
end