lib/unparser/emitter.rb in unparser-0.0.18 vs lib/unparser/emitter.rb in unparser-0.1.0
- old
+ new
@@ -1,11 +1,11 @@
module Unparser
# Emitter base class
class Emitter
include Adamantium::Flat, AbstractType, Constants
- include Equalizer.new(:node, :buffer, :parent)
+ include Concord.new(:node, :parent)
# Registry for node emitters
REGISTRY = {}
NOINDENT = [:rescue, :ensure].to_set
@@ -75,53 +75,44 @@
REGISTRY[type] = self
end
end
private_class_method :handle
- # Emit node into buffer
+ # Trigger write to buffer
#
# @return [self]
#
# @api private
#
- def self.emit(*arguments)
- new(*arguments)
+ def write_to_buffer
+ dispatch
self
end
+ memoize :write_to_buffer
- # Initialize object
+ # Emit node
#
- # @param [Parser::AST::Node] node
- # @param [Buffer] buffer
+ # @return [self]
#
- # @return [undefined]
- #
# @api private
#
- def initialize(node, buffer, parent)
- @node, @buffer, @parent = node, buffer, parent
- dispatch
+ def self.emit(*arguments)
+ new(*arguments).write_to_buffer
end
- private_class_method :new
-
- # Visit node
+ # Return emitter
#
- # @param [Parser::AST::Node] node
- # @param [Buffer] buffer
- #
# @return [Emitter]
#
# @api private
#
- def self.visit(node, buffer, parent = Root)
+ def self.emitter(node, parent)
type = node.type
- emitter = REGISTRY.fetch(type) do
+ klass = REGISTRY.fetch(type) do
raise ArgumentError, "No emitter for node: #{type.inspect}"
end
- emitter.emit(node, buffer, parent)
- self
+ klass.new(node, parent)
end
# Dispatch node
#
# @return [undefined]
@@ -136,27 +127,35 @@
#
# @api private
#
attr_reader :node
- # Return buffer
+ # Test if node is emitted as terminated expression
#
- # @return [Buffer] buffer
+ # @return [false]
+ # if emitted node is unambigous
#
+ # @return [true]
+ #
# @api private
#
- attr_reader :buffer
- protected :buffer
+ def terminated?
+ TERMINATED.include?(node.type)
+ end
- # Return parent emitter
+ protected
+
+ # Return buffer
#
- # @return [Parent]
+ # @return [Buffer] buffer
#
# @api private
#
- attr_reader :parent
- protected :parent
+ def buffer
+ parent.buffer
+ end
+ memoize :buffer, :freezer => :noop
private
# Emit contents of block within parentheses
#
@@ -178,19 +177,49 @@
#
def emit_source_map
SourceMap.emit(node, buffer)
end
- # Dispatch helper
+ # Visit node
#
# @param [Parser::AST::Node] node
#
# @return [undefined]
#
# @api private
#
def visit(node)
- self.class.visit(node, buffer, self)
+ emitter = emitter(node)
+ emitter.write_to_buffer
+ end
+
+ # Visit unambigous node
+ #
+ # @param [Parser::AST::Node] node
+ #
+ # @return [undefined]
+ #
+ # @api private
+ #
+ def visit_terminated(node)
+ emitter = emitter(node)
+ unless emitter.terminated?
+ parentheses { emitter.write_to_buffer }
+ return
+ end
+ emitter.write_to_buffer
+ end
+
+ # Return emitter for node
+ #
+ # @param [Parser::AST::Node] node
+ #
+ # @return [Emitter]
+ #
+ # @api private
+ #
+ def emitter(node)
+ self.class.emitter(node, self)
end
# Emit delimited body
#
# @param [Enumerable<Parser::AST::Node>] nodes