module Overrider
Constants
- VERSION
Public Class Methods
disable=(v)
click to toggle source
# File lib/overrider.rb, line 48 def self.disable=(v) @disable = v end
disabled?()
click to toggle source
# File lib/overrider.rb, line 52 def self.disabled? @disable end
enabled?()
click to toggle source
# File lib/overrider.rb, line 56 def self.enabled? !disabled? end
sexps()
click to toggle source
# File lib/overrider.rb, line 60 def self.sexps @sexps ||= {} end
Private Instance Methods
override(symbol)
click to toggle source
# File lib/overrider.rb, line 124 def override(symbol) return symbol if Overrider.disabled? owner = self override_methods.add(instance_method(symbol)) caller_info = caller_locations(1, 1)[0] unless Overrider.sexps[caller_info.absolute_path] Overrider.sexps[caller_info.absolute_path] ||= Ripper.sexp(File.read(caller_info.absolute_path)) end trace_for_override(owner) symbol end
override_methods()
click to toggle source
# File lib/overrider.rb, line 66 def override_methods @override_methods ||= Set.new end
override_singleton_method(symbol)
click to toggle source
# File lib/overrider.rb, line 140 def override_singleton_method(symbol) return symbol if Overrider.disabled? owner = self override_methods.add(singleton_class.instance_method(symbol)) caller_info = caller_locations(1, 1)[0] unless Overrider.sexps[caller_info.absolute_path] Overrider.sexps[caller_info.absolute_path] ||= Ripper.sexp(File.read(caller_info.absolute_path)) end trace_for_override(owner) symbol end
trace_for_override(owner)
click to toggle source
# File lib/overrider.rb, line 72 def trace_for_override(owner) @__overrider_trace_point ||= TracePoint.trace(:end, :c_return, :return, :raise) do |t| if t.event == :raise @__overrider_trace_point.disable @__overrider_trace_point = nil next end klass = t.self override_at_outer = false if t.event == :return && klass == self && (t.method_id == :override || t.method_id == :override_singleton_method) c = caller_locations(2, 1)[0] traverser = SexpTraverser.new(Overrider.sexps[c.absolute_path]) traverser.traverse do |n, parent| if n[0] == :@ident && (n[1] == "override" || n[1] == "override_singleton_method") && n[2][0] == c.lineno if parent[0] == :command || parent[0] == :fcall # override :foo elsif parent[0] == :command_call || parent[0] == :call if parent[1][0] == :var_ref && parent[1][1][0] == :@kw && parent[1][1][1] == "self" # self.override :foo else # unknown case warn "call `override` method by unknown way" override_at_outer = true end else override_at_outer = true end end end end target_class_end = klass == owner && t.event == :end target_class_new_end = (klass == Class || klass == Module) && t.event == :c_return && t.method_id == :new && t.return_value == owner if target_class_end || target_class_new_end || override_at_outer override_methods.each do |meth| unless meth.super_method @__overrider_trace_point.disable @__overrider_trace_point = nil raise NoSuperMethodError.new(self, meth, caller(4)) end end @__overrider_trace_point.disable @__overrider_trace_point = nil end end end