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
93 94 95 |
# File 'app/cmd_parse.rb', line 93 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
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'app/cmd_parse.rb', line 99 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
128 129 130 131 |
# File 'app/cmd_parse.rb', line 128 def parse_breakpoint(str, opts={}) parse = parse_terminal(:_breakpoint_stmt, str, opts) parse ? parse.result : nil end |
.parse_breakpoint_no_condition(str, opts = {}) ⇒ Object
133 134 135 136 |
# File 'app/cmd_parse.rb', line 133 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
138 139 140 141 |
# File 'app/cmd_parse.rb', line 138 def parse_list(str, opts={}) parse = parse_terminal(:_list_stmt, str, opts) parse ? parse.result : nil end |
.parse_location(loc_str, opts = {}) ⇒ Object
123 124 125 126 |
# File 'app/cmd_parse.rb', line 123 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
118 119 120 121 |
# File 'app/cmd_parse.rb', line 118 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.
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 87 88 89 |
# File 'app/cmd_parse.rb', line 14 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) || parent.instance_methods.member?(lookup_name.to_sym)) parent.instance_method(lookup_name) || parent.instance_method(lookup_name.to_sym) elsif parent.respond_to?('methods') parent.method(lookup_name) 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 |