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