Module: Trepan::CmdParser
- Defined in:
- app/cmd_parse.rb
Class Method Summary collapse
-
.meth_for_parse_struct(parse_struct, start_binding) ⇒ Object
Return the method by evaluating parse_struct.
-
.meth_for_string(str, start_binding) ⇒ Object
Parse str and return the method associated with that.
- .parse_breakpoint(str, opts = {}) ⇒ Object
- .parse_breakpoint_no_condition(str, opts = {}) ⇒ Object
- .parse_list(str, opts = {}) ⇒ Object
- .parse_location(loc_str, opts = {}) ⇒ Object
- .parse_terminal(terminal_name, loc_str, opts = {}) ⇒ Object
-
.resolve_method(m, bind, parent_class = nil) ⇒ Object
Given a KPeg parse object, return the method of that parse or raise a Name error if we can’t find a method.
Class Method Details
.meth_for_parse_struct(parse_struct, start_binding) ⇒ Object
Return the method by evaluating parse_struct. nil is returned if we can’t parse str
90 91 92 |
# File 'app/cmd_parse.rb', line 90 def meth_for_parse_struct(parse_struct, start_binding) resolve_method(parse_struct, start_binding) end |
.meth_for_string(str, start_binding) ⇒ Object
Parse str and return the method associated with that. nil is returned if we can’t parse str
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
# File 'app/cmd_parse.rb', line 96 def meth_for_string(str, start_binding) @cp ? @cp.setup_parser(str) : @cp = CmdParse.new(str) begin if @cp._class_module_chain # Did we match all of it? if @cp.result.name == str.strip meth_for_parse_struct(@cp.result, start_binding) else nil end else # FIXME: change to raise ParseError? nil end rescue NameError return nil end end |
.parse_breakpoint(str, opts = {}) ⇒ Object
125 126 127 128 |
# File 'app/cmd_parse.rb', line 125 def parse_breakpoint(str, opts={}) parse = parse_terminal(:_breakpoint_stmt, str, opts) parse ? parse.result : nil end |
.parse_breakpoint_no_condition(str, opts = {}) ⇒ Object
130 131 132 133 |
# File 'app/cmd_parse.rb', line 130 def parse_breakpoint_no_condition(str, opts={}) parse = parse_terminal(:_breakpoint_stmt_no_condition, str, opts) parse ? parse.result : nil end |
.parse_list(str, opts = {}) ⇒ Object
135 136 137 138 |
# File 'app/cmd_parse.rb', line 135 def parse_list(str, opts={}) parse = parse_terminal(:_list_stmt, str, opts) parse ? parse.result : nil end |
.parse_location(loc_str, opts = {}) ⇒ Object
120 121 122 123 |
# File 'app/cmd_parse.rb', line 120 def parse_location(loc_str, opts={}) parse = parse_terminal(:_location, loc_str, opts) parse ? parse.result : nil end |
.parse_terminal(terminal_name, loc_str, opts = {}) ⇒ Object
115 116 117 118 |
# File 'app/cmd_parse.rb', line 115 def parse_terminal(terminal_name, loc_str, opts={}) @cp ? @cp.setup_parser(loc_str) : @cp = CmdParse.new(loc_str, opts) @cp.send(terminal_name) ? @cp : nil end |
.resolve_method(m, bind, parent_class = nil) ⇒ Object
Given a KPeg parse object, return the method of that parse or raise a Name error if we can’t find a method. parent_class is the parent class of the object we’ve found so far and “binding” is used if we need to use eval to find the method.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'app/cmd_parse.rb', line 13 def resolve_method(m, bind, parent_class = nil) name = m.name # DEBUG p name errmsg = nil if m.type == :constant begin if parent_class klass = parent_class.const_get(m.chain[0].name) else errmsg = "Constant #{m} is not a class or module" raise NameError, errmsg unless m.chain[0] klass = eval(m.chain[0].name, bind) end errmsg = "Constant #{klass} is not a class or module" unless raise NameError, errmsg unless klass.kind_of?(Class) or klass.kind_of?(Module) m = m.chain[1] if klass.instance_methods.member?(:binding) bind = klass.bind elsif klass.private_instance_methods.member?(:binding) bind = klass.send(:binding) else bind = nil end resolve_method(m, bind, klass) rescue NameError errmsg ||= "Can't resolve constant #{name}" raise NameError, errmsg end else is_class = begin m.chain && m.chain[0] && Class == eval("#{m.chain[0].name}.class", bind) rescue false end if is_class # Handles stuff like: # x = File # x.basename # Above, we tested we get a class back when we evalate m.chain[0] # below. So it is safe to run the eval. klass = eval("#{m.chain[0].name}", bind) resolve_method(m.chain[1], klass.send(:binding), klass) else begin errmsg = "Can't get method for #{name.inspect}" if m.chain && m.chain[0] parent_obj = eval("#{m.chain[0].name}", bind) if !parent_class && bind end parent = parent_class || parent_obj meth = if parent errmsg << "in #{parent}" lookup_name = m.chain && m.chain[1] ? m.chain[1].name : name if parent.respond_to?('instance_methods') && parent.instance_methods.member?(lookup_name.to_sym) parent.instance_method(lookup_name.to_sym) elsif parent.respond_to?('methods') parent.method(lookup_name.to_sym) end elsif m.chain && m.chain[1] eval("#{m.chain[0].name}.method(#{lookup_name.name.inspect})", bind) else eval("self.method(#{name.inspect})", bind) end return meth rescue raise NameError, errmsg end end end end |