class Noraneko::Processor
Constants
- ParseError
Attributes
context_stack[W]
filepath[W]
registry[W]
Public Class Methods
init_with(registry:, filepath: nil)
click to toggle source
# File lib/noraneko/processor.rb, line 17 def self.init_with(registry:, filepath: nil) new.tap do |instance| instance.registry = registry instance.filepath = filepath instance.context_stack = [] end end
Public Instance Methods
process(node)
click to toggle source
Calls superclass method
# File lib/noraneko/processor.rb, line 25 def process(node) return nil unless node context_generated = false begin case node.type when :class, :sclass nclass = process_class(node) context_generated = true when :module nmodule = process_module(node) context_generated = true when :def process_def(node) context_generated = true when :defs process_defs(node) context_generated = true when :send process_send(node) when :block_pass process_block_pass(node) end rescue StandardError line = node.loc.line message = "Fail to parse. location: #{@filepath}:#{line}" raise ParseError.new(message) end super if node.type == :sclass @registry.find(nclass.parent_name).merge_singleton(nclass) @registry.delete(nclass) end if context_generated @public_scope = true unless sent_in_method? @context_stack.pop end end
Private Instance Methods
current_context()
click to toggle source
# File lib/noraneko/processor.rb, line 262 def current_context @context_stack.last || global_const end
extract_view_name(param)
click to toggle source
# File lib/noraneko/processor.rb, line 239 def extract_view_name(param) value = if param.type == :hash hash = convert_to_hash(param) hash[:action] || hash[:template] else param.children.last end # Inline render return nil unless value view_path = value.to_s.split('.').first if view_path.split('/').size == 1 parent_context.rel_path_from_controller + view_path else view_path end end
global_const()
click to toggle source
# File lib/noraneko/processor.rb, line 270 def global_const return @_global_nconst if @_global_nconst @_global_nconst = NModule.new('', @filepath, 0) @registry.put(@_global_nconst) end
parent_context()
click to toggle source
# File lib/noraneko/processor.rb, line 258 def parent_context @context_stack[-2] || global_const end
process_alias_method(node)
click to toggle source
# File lib/noraneko/processor.rb, line 134 def process_alias_method(node) aliased = node.children[2].children.last line = node.loc.line nmethod = current_context.add_method(aliased, line) end
process_block_pass(node)
click to toggle source
# File lib/noraneko/processor.rb, line 218 def process_block_pass(node) sym = node.children.first current_method_name = current_context.name called_method_name = sym.children.last parent_context.register_send(current_method_name, called_method_name) end
process_callback_register(node)
click to toggle source
# File lib/noraneko/processor.rb, line 192 def process_callback_register(node) return if node.children.size < 3 || !node.children.first.nil? name = node.children[1] syms = node.children.drop(2).select { |n| n.type == :sym } return if syms.empty? current_context.registered_callbacks += extract_syms(syms) end
process_class(node)
click to toggle source
# File lib/noraneko/processor.rb, line 68 def process_class(node) names = if singleton_class?(node) %w[Self] else extract_consts(node.children.first) end qualified_name = current_context.child_qualified_name(names) line = node.loc.line nclass = NClass.new(qualified_name, @filepath, line) @context_stack << nclass @registry.put(nclass) end
process_def(node)
click to toggle source
# File lib/noraneko/processor.rb, line 90 def process_def(node) method_name = node.children.first line = node.loc.line nmethod = current_context.add_method(method_name, line) @context_stack << nmethod end
process_defs(node)
click to toggle source
# File lib/noraneko/processor.rb, line 97 def process_defs(node) context = current_context method_name = node.children[1] line = node.loc.line nmethod = if sent_in_method? receiver = node.children[0].children.first context = NModule.new("#{context.qualified_name}##{receiver}", @filepath, 0) @registry.put(context) context.add_method(method_name, line) else context.add_cmethod(method_name, line) end @context_stack << nmethod end
process_explicit_send(node)
click to toggle source
# File lib/noraneko/processor.rb, line 200 def process_explicit_send(node) target_node= node.children[2] return unless [:str, :sym].include?(target_node.type) called_method_name = target_node.children.last.to_sym current_method_name = current_context.name parent_context.register_send(current_method_name, called_method_name) end
process_extend(node)
click to toggle source
# File lib/noraneko/processor.rb, line 153 def process_extend(node) current_context.extended_module_names += process_external_import(node) end
process_external_import(node)
click to toggle source
# File lib/noraneko/processor.rb, line 140 def process_external_import(node) node.children.drop(2).each_with_object([]) do |target, consts| if target.type == :const const_name = extract_consts(target).join('::') consts << const_name end end end
process_include(node)
click to toggle source
# File lib/noraneko/processor.rb, line 149 def process_include(node) current_context.included_module_names += process_external_import(node) end
process_layout(node)
click to toggle source
# File lib/noraneko/processor.rb, line 184 def process_layout(node) param = node.children[2] if [:str, :sym].include?(param.type) layout = param.children.last.to_s current_context.called_view('layouts/' + layout) end end
process_module(node)
click to toggle source
# File lib/noraneko/processor.rb, line 81 def process_module(node) names = extract_consts(node.children.first) qualified_name = current_context.child_qualified_name(names) line = node.loc.line nmodule = NModule.new(qualified_name, @filepath, line) @context_stack << nmodule @registry.put(nmodule) end
process_private(node)
click to toggle source
# File lib/noraneko/processor.rb, line 157 def process_private(node) if node.children.size == 2 current_context.private! else extract_syms(node.children.drop(2)).each do |method_name| current_context.make_method_private(method_name) end end end
process_render(node)
click to toggle source
# File lib/noraneko/processor.rb, line 225 def process_render(node) params = node.children.drop(2).first return unless params view_name = extract_view_name(params) return unless view_name parent_context.called_view(view_name) end
process_send(node)
click to toggle source
# File lib/noraneko/processor.rb, line 113 def process_send(node) case node.children[1] when :private process_private(node) when :include process_include(node) when :extend process_extend(node) when :alias_method process_alias_method(node) when :send process_explicit_send(node) else if sent_in_method? process_send_message(node) else process_send_nconst(node) end end end
process_send_message(node)
click to toggle source
# File lib/noraneko/processor.rb, line 208 def process_send_message(node) if parent_context.controller? && node.children[1] == :render process_render(node) else current_method_name = current_context.name called_method_name = node.children[1] parent_context.register_send(current_method_name, called_method_name) end end
process_send_nconst(node)
click to toggle source
# File lib/noraneko/processor.rb, line 167 def process_send_nconst(node) case node.children[1] when :module_function syms = extract_syms(node.children[2..-1]) if syms.empty? current_context.method_default_as_class! else syms.each { |sym| current_context.find_method(sym).class_method! } end when :layout process_layout(node) else current_context.register_csend(node.children[1]) process_callback_register(node) end end
rel_path_from_controller(controller)
click to toggle source
# File lib/noraneko/processor.rb, line 233 def rel_path_from_controller(controller) controller.path .split('/controllers/').drop(1).join('') .split('_controller.rb').first + '/' end
sent_in_method?()
click to toggle source
# File lib/noraneko/processor.rb, line 266 def sent_in_method? current_context.is_a? Noraneko::NMethod end