Class: Sexp
- Inherits:
-
Object
- Object
- Sexp
- Defined in:
- lib/ruby_parser/bm_sexp.rb
Overview
Sexp changes from ruby_parser and some changes for caching hash value and tracking ‘original’ line number of a Sexp.
Constant Summary collapse
- ASSIGNMENT_BOOL =
[:gasgn, :iasgn, :lasgn, :cvdecl, :cvasgn, :cdecl, :or, :and, :colon2, :op_asgn_or]
- CALLS =
[:call, :attrasgn, :safe_call, :safe_attrasgn]
Instance Attribute Summary collapse
-
#or_depth ⇒ Object
Returns the value of attribute or_depth.
-
#original_line ⇒ Object
Returns the value of attribute original_line.
Instance Method Summary collapse
- #<<(arg) ⇒ Object
-
#arglist ⇒ Object
Returns arglist for method call.
-
#arglist=(exp) ⇒ Object
Sets the arglist in a method call.
-
#args ⇒ Object
Returns arguments of a method call.
-
#block(delete = nil) ⇒ Object
Returns block of a call with a block.
-
#block_args ⇒ Object
Returns parameters for a block.
-
#block_call ⇒ Object
Method call associated with a block:.
-
#body ⇒ Object
Returns body of a method definition, class, or module.
-
#body=(exp) ⇒ Object
Sets body, which is now a complicated process because the body is no longer a separate Sexp, but just a list of Sexps.
-
#body_list ⇒ Object
Like Sexp#body, except the returned Sexp is of type :rlist instead of untyped.
-
#call ⇒ Object
Returns the call Sexp in a result returned from FindCall.
- #call_chain ⇒ Object
- #class_name ⇒ Object (also: #module_name)
-
#combine(exp, line = nil) ⇒ Object
Join self and exp into an :or Sexp.
- #compact ⇒ Object
-
#condition ⇒ Object
Returns condition of an if expression:.
- #condition=(exp) ⇒ Object
-
#deep_clone(line = nil) ⇒ Object
Create clone of Sexp and nested Sexps but not their non-Sexp contents.
- #each_arg(replace = false) ⇒ Object
- #each_arg!(&block) ⇒ Object
-
#else_clause ⇒ Object
Returns ‘else’ clause of an if expression:.
-
#expect(*types) ⇒ Object
Raise a WrongSexpError if the nodes type does not match one of the expected types.
- #find_and_replace_all(*args) ⇒ Object
- #find_node(*args) ⇒ Object
-
#first_arg ⇒ Object
Returns first argument of a method call.
-
#first_arg=(exp) ⇒ Object
Sets first argument of a method call.
- #first_param ⇒ Object
- #formal_args ⇒ Object
- #hash ⇒ Object
- #inspect(seen = Set.new) ⇒ Object
- #last_arg ⇒ Object
-
#lhs ⇒ Object
Returns the left hand side of assignment or boolean:.
-
#lhs=(exp) ⇒ Object
Sets the left hand side of assignment or boolean.
-
#method ⇒ Object
Returns method of a method call:.
- #method=(name) ⇒ Object
- #method_missing(name, *args) ⇒ Object
-
#method_name ⇒ Object
Returns name of method being defined in a method definition.
-
#module ⇒ Object
Returns the module the call is inside.
- #node_type=(type) ⇒ Object
- #old_compact ⇒ Object
- #old_fara ⇒ Object
- #old_find_node ⇒ Object
- #old_push ⇒ Object
- #paren ⇒ Object
- #parent_name ⇒ Object
- #render_type ⇒ Object
-
#result_class ⇒ Object
Return the class the call is inside.
-
#rhs ⇒ Object
Returns right side (value) of assignment or boolean:.
-
#rhs=(exp) ⇒ Object
Sets the right hand side of assignment or boolean.
- #second ⇒ Object
-
#second_arg ⇒ Object
Returns second argument of a method call.
-
#second_arg=(exp) ⇒ Object
Sets second argument of a method call.
- #set_args(*exp) ⇒ Object
-
#target ⇒ Object
Returns target of a method call:.
-
#target=(exp) ⇒ Object
Sets the target of a method call:.
-
#then_clause ⇒ Object
Returns ‘then’ clause of an if expression:.
- #third_arg ⇒ Object
- #third_arg=(exp) ⇒ Object
- #to_sym ⇒ Object
- #value ⇒ Object
- #value=(exp) ⇒ Object
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(name, *args) ⇒ Object
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/ruby_parser/bm_sexp.rb', line 9 def method_missing name, *args #Brakeman does not use this functionality, #so overriding it to raise a NoMethodError. # #The original functionality calls find_node and optionally #deletes the node if found. # #Defining a method named "return" seems like a bad idea, so we have to #check for it here instead if name == :return find_node name, *args else raise NoMethodError.new("No method '#{name}' for Sexp", name, args) end end |
Instance Attribute Details
#or_depth ⇒ Object
Returns the value of attribute or_depth.
5 6 7 |
# File 'lib/ruby_parser/bm_sexp.rb', line 5 def or_depth @or_depth end |
#original_line ⇒ Object
Returns the value of attribute original_line.
5 6 7 |
# File 'lib/ruby_parser/bm_sexp.rb', line 5 def original_line @original_line end |
Instance Method Details
#<<(arg) ⇒ Object
96 97 98 99 |
# File 'lib/ruby_parser/bm_sexp.rb', line 96 def << arg @my_hash_value = nil old_push arg end |
#arglist ⇒ Object
Returns arglist for method call. This differs from Sexp#args, as Sexp#args does not return a ‘real’ Sexp (it does not have a node type) but Sexp#arglist returns a s(:arglist, …)
s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1), s(:lit, 2)))
^------------ arglist ------------^
196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/ruby_parser/bm_sexp.rb', line 196 def arglist expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper case self.node_type when :call, :attrasgn, :safe_call, :safe_attrasgn self[3..-1].unshift :arglist when :super, :zsuper if self[1] self[1..-1].unshift :arglist else Sexp.new(:arglist) end end end |
#arglist=(exp) ⇒ Object
Sets the arglist in a method call.
172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/ruby_parser/bm_sexp.rb', line 172 def arglist= exp expect :call, :attrasgn, :safe_call, :safe_attrasgn @my_hash_value = nil start_index = 3 if exp.is_a? Sexp and exp.node_type == :arglist exp = exp[1..-1] end exp.each_with_index do |e, i| self[start_index + i] = e end end |
#args ⇒ Object
Returns arguments of a method call. This will be an ‘untyped’ Sexp.
s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1), s(:lit, 2)))
^--------args--------^
215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 |
# File 'lib/ruby_parser/bm_sexp.rb', line 215 def args expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper case self.node_type when :call, :attrasgn, :safe_call, :safe_attrasgn if self[3] self[3..-1] else Sexp.new end when :super, :zsuper if self[1] self[1..-1] else Sexp.new end end end |
#block(delete = nil) ⇒ Object
Returns block of a call with a block. Could be a single expression or a block:
s(:iter,
s(:call, nil, :x, s(:arglist)),
s(:lasgn, :y),
s(:block, s(:lvar, :y), s(:call, nil, :z, s(:arglist))))
^-------------------- block --------------------------^
390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 |
# File 'lib/ruby_parser/bm_sexp.rb', line 390 def block delete = nil unless delete.nil? #this is from RubyParser return find_node :block, delete end expect :iter, :scope, :resbody case self.node_type when :iter self[3] when :scope self[1] when :resbody #This is for Ruby2Ruby ONLY find_node :block end end |
#block_args ⇒ Object
Returns parameters for a block
s(:iter,
s(:call, nil, :x, s(:arglist)),
s(:lasgn, :y), <- block_args
s(:call, nil, :p, s(:arglist, s(:lvar, :y))))
414 415 416 417 418 419 420 421 |
# File 'lib/ruby_parser/bm_sexp.rb', line 414 def block_args expect :iter if self[2] == 0 # ?! See https://github.com/presidentbeef/brakeman/issues/331 return Sexp.new(:args) else self[2] end end |
#block_call ⇒ Object
Method call associated with a block:
s(:iter,
s(:call, nil, :x, s(:arglist)), <- block_call
s(:lasgn, :y),
s(:block, s(:lvar, :y), s(:call, nil, :z, s(:arglist))))
372 373 374 375 376 377 378 379 380 |
# File 'lib/ruby_parser/bm_sexp.rb', line 372 def block_call expect :iter if self[1].node_type == :lambda s(:call, nil, :lambda).line(self.line) else self[1] end end |
#body ⇒ Object
Returns body of a method definition, class, or module. This will be an untyped Sexp containing a list of Sexps from the body.
527 528 529 530 531 532 533 534 535 536 537 538 |
# File 'lib/ruby_parser/bm_sexp.rb', line 527 def body expect :defn, :defs, :class, :module case self.node_type when :defn, :class self[3..-1] when :defs self[4..-1] when :module self[2..-1] end end |
#body=(exp) ⇒ Object
Sets body, which is now a complicated process because the body is no longer a separate Sexp, but just a list of Sexps.
499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 |
# File 'lib/ruby_parser/bm_sexp.rb', line 499 def body= exp expect :defn, :defs, :class, :module @my_hash_value = nil case self.node_type when :defn, :class index = 3 when :defs index = 4 when :module index = 2 end self.slice!(index..-1) #Remove old body if exp.first == :rlist exp = exp[1..-1] end #Insert new body exp.each do |e| self[index] = e index += 1 end end |
#body_list ⇒ Object
Like Sexp#body, except the returned Sexp is of type :rlist instead of untyped.
542 543 544 |
# File 'lib/ruby_parser/bm_sexp.rb', line 542 def body_list self.body.unshift :rlist end |
#call ⇒ Object
Returns the call Sexp in a result returned from FindCall
564 565 566 567 568 |
# File 'lib/ruby_parser/bm_sexp.rb', line 564 def call expect :result self.last end |
#call_chain ⇒ Object
311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
# File 'lib/ruby_parser/bm_sexp.rb', line 311 def call_chain expect :call, :attrasgn, :safe_call, :safe_attrasgn chain = [] call = self while call.class == Sexp and CALLS.include? call.first chain << call.method call = call.target end chain.reverse! chain end |
#class_name ⇒ Object Also known as: module_name
551 552 553 554 |
# File 'lib/ruby_parser/bm_sexp.rb', line 551 def class_name expect :class, :module self[1] end |
#combine(exp, line = nil) ⇒ Object
Join self and exp into an :or Sexp. Sets or_depth. Used for combining “branched” values in AliasProcessor.
80 81 82 83 84 85 86 |
# File 'lib/ruby_parser/bm_sexp.rb', line 80 def combine exp, line = nil combined = Sexp.new(:or, self, exp).line(line || -2) combined.or_depth = [self.or_depth, exp.or_depth].compact.reduce(0, :+) + 1 combined end |
#compact ⇒ Object
109 110 111 112 |
# File 'lib/ruby_parser/bm_sexp.rb', line 109 def compact @my_hash_value = nil old_compact end |
#condition ⇒ Object
Returns condition of an if expression:
s(:if,
s(:lvar, :condition), <-- condition
s(:lvar, :then_val),
s(:lvar, :else_val)))
332 333 334 335 |
# File 'lib/ruby_parser/bm_sexp.rb', line 332 def condition expect :if self[1] end |
#condition=(exp) ⇒ Object
337 338 339 340 |
# File 'lib/ruby_parser/bm_sexp.rb', line 337 def condition= exp expect :if self[1] = exp end |
#deep_clone(line = nil) ⇒ Object
Create clone of Sexp and nested Sexps but not their non-Sexp contents. If a line number is provided, also sets line/original_line on all Sexps.
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/ruby_parser/bm_sexp.rb', line 27 def deep_clone line = nil s = Sexp.new self.each do |e| if e.is_a? Sexp s << e.deep_clone(line) else s << e end end if line s.original_line = self.original_line || self.line s.line(line) else s.original_line = self.original_line s.line(self.line) if self.line end s end |
#each_arg(replace = false) ⇒ Object
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 |
# File 'lib/ruby_parser/bm_sexp.rb', line 234 def each_arg replace = false expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper range = nil case self.node_type when :call, :attrasgn, :safe_call, :safe_attrasgn if self[3] range = (3...self.length) end when :super, :zsuper if self[1] range = (1...self.length) end end if range range.each do |i| res = yield self[i] self[i] = res if replace end end self end |
#each_arg!(&block) ⇒ Object
259 260 261 262 |
# File 'lib/ruby_parser/bm_sexp.rb', line 259 def each_arg! &block @my_hash_value = nil self.each_arg true, &block end |
#else_clause ⇒ Object
Returns ‘else’ clause of an if expression:
s(:if,
s(:lvar, :condition),
s(:lvar, :then_val),
s(:lvar, :else_val)))
^---else caluse---^
361 362 363 364 |
# File 'lib/ruby_parser/bm_sexp.rb', line 361 def else_clause expect :if self[3] end |
#expect(*types) ⇒ Object
Raise a WrongSexpError if the nodes type does not match one of the expected types.
126 127 128 129 130 |
# File 'lib/ruby_parser/bm_sexp.rb', line 126 def expect *types unless types.include? self.node_type raise WrongSexpError, "Expected #{types.join ' or '} but given #{self.inspect}", caller[1..-1] end end |
#find_and_replace_all(*args) ⇒ Object
114 115 116 117 |
# File 'lib/ruby_parser/bm_sexp.rb', line 114 def find_and_replace_all *args @my_hash_value = nil old_fara(*args) end |
#find_node(*args) ⇒ Object
119 120 121 122 |
# File 'lib/ruby_parser/bm_sexp.rb', line 119 def find_node *args @my_hash_value = nil old_find_node(*args) end |
#first_arg ⇒ Object
Returns first argument of a method call.
265 266 267 268 |
# File 'lib/ruby_parser/bm_sexp.rb', line 265 def first_arg expect :call, :attrasgn, :safe_call, :safe_attrasgn self[3] end |
#first_arg=(exp) ⇒ Object
Sets first argument of a method call.
271 272 273 274 275 |
# File 'lib/ruby_parser/bm_sexp.rb', line 271 def first_arg= exp expect :call, :attrasgn, :safe_call, :safe_attrasgn @my_hash_value = nil self[3] = exp end |
#first_param ⇒ Object
423 424 425 426 |
# File 'lib/ruby_parser/bm_sexp.rb', line 423 def first_param expect :args self[1] end |
#formal_args ⇒ Object
486 487 488 489 490 491 492 493 494 495 |
# File 'lib/ruby_parser/bm_sexp.rb', line 486 def formal_args expect :defn, :defs case self.node_type when :defn self[2] when :defs self[3] end end |
#hash ⇒ Object
101 102 103 104 105 106 107 |
# File 'lib/ruby_parser/bm_sexp.rb', line 101 def hash #There still seems to be some instances in which the hash of the #Sexp changes, but I have not found what method call is doing it. #Of course, Sexp is subclasses from Array, so who knows what might #be going on. @my_hash_value ||= super end |
#inspect(seen = Set.new) ⇒ Object
585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 |
# File 'lib/ruby_parser/bm_sexp.rb', line 585 def inspect seen = Set.new if seen.include? self.object_id 's(...)' else seen << self.object_id sexp_str = self.map do |x| if x.is_a? Sexp x.inspect seen else x.inspect end end.join(', ') "s(#{sexp_str})" end end |
#last_arg ⇒ Object
301 302 303 304 305 306 307 308 309 |
# File 'lib/ruby_parser/bm_sexp.rb', line 301 def last_arg expect :call, :attrasgn, :safe_call, :safe_attrasgn if self[3] self[-1] else nil end end |
#lhs ⇒ Object
Returns the left hand side of assignment or boolean:
s(:lasgn, :x, s(:lit, 1))
^--lhs
432 433 434 435 |
# File 'lib/ruby_parser/bm_sexp.rb', line 432 def lhs expect(*ASSIGNMENT_BOOL) self[1] end |
#lhs=(exp) ⇒ Object
Sets the left hand side of assignment or boolean.
438 439 440 441 442 |
# File 'lib/ruby_parser/bm_sexp.rb', line 438 def lhs= exp expect(*ASSIGNMENT_BOOL) @my_hash_value = nil self[1] = exp end |
#method ⇒ Object
Returns method of a method call:
s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1)))
^- method
152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/ruby_parser/bm_sexp.rb', line 152 def method expect :call, :attrasgn, :safe_call, :safe_attrasgn, :super, :zsuper, :result case self.node_type when :call, :attrasgn, :safe_call, :safe_attrasgn self[2] when :super, :zsuper :super when :result self.last end end |
#method=(name) ⇒ Object
165 166 167 168 169 |
# File 'lib/ruby_parser/bm_sexp.rb', line 165 def method= name expect :call, :safe_call self[2] = name end |
#method_name ⇒ Object
Returns name of method being defined in a method definition.
475 476 477 478 479 480 481 482 483 484 |
# File 'lib/ruby_parser/bm_sexp.rb', line 475 def method_name expect :defn, :defs case self.node_type when :defn self[1] when :defs self[2] end end |
#module ⇒ Object
Returns the module the call is inside
571 572 573 574 575 |
# File 'lib/ruby_parser/bm_sexp.rb', line 571 def module expect :result self[1] end |
#node_type=(type) ⇒ Object
72 73 74 75 |
# File 'lib/ruby_parser/bm_sexp.rb', line 72 def node_type= type @my_hash_value = nil self[0] = type end |
#old_compact ⇒ Object
92 |
# File 'lib/ruby_parser/bm_sexp.rb', line 92 alias :old_compact :compact |
#old_fara ⇒ Object
93 |
# File 'lib/ruby_parser/bm_sexp.rb', line 93 alias :old_fara :find_and_replace_all |
#old_find_node ⇒ Object
94 |
# File 'lib/ruby_parser/bm_sexp.rb', line 94 alias :old_find_node :find_node |
#old_push ⇒ Object
91 |
# File 'lib/ruby_parser/bm_sexp.rb', line 91 alias :old_push :<< |
#paren ⇒ Object
49 50 51 |
# File 'lib/ruby_parser/bm_sexp.rb', line 49 def paren @paren ||= false end |
#parent_name ⇒ Object
558 559 560 561 |
# File 'lib/ruby_parser/bm_sexp.rb', line 558 def parent_name expect :class self[2] end |
#render_type ⇒ Object
546 547 548 549 |
# File 'lib/ruby_parser/bm_sexp.rb', line 546 def render_type expect :render self[1] end |
#result_class ⇒ Object
Return the class the call is inside
578 579 580 581 582 |
# File 'lib/ruby_parser/bm_sexp.rb', line 578 def result_class expect :result self[2] end |
#rhs ⇒ Object
Returns right side (value) of assignment or boolean:
s(:lasgn, :x, s(:lit, 1))
^--rhs---^
448 449 450 451 452 453 454 455 456 457 458 459 460 |
# File 'lib/ruby_parser/bm_sexp.rb', line 448 def rhs expect :attrasgn, :safe_attrasgn, *ASSIGNMENT_BOOL if self.node_type == :attrasgn or self.node_type == :safe_attrasgn if self[2] == :[]= self[4] else self[3] end else self[2] end end |
#rhs=(exp) ⇒ Object
Sets the right hand side of assignment or boolean.
463 464 465 466 467 468 469 470 471 472 |
# File 'lib/ruby_parser/bm_sexp.rb', line 463 def rhs= exp expect :attrasgn, :safe_attrasgn, *ASSIGNMENT_BOOL @my_hash_value = nil if self.node_type == :attrasgn or self.node_type == :safe_attrasgn self[3] = exp else self[2] = exp end end |
#second ⇒ Object
64 65 66 |
# File 'lib/ruby_parser/bm_sexp.rb', line 64 def second self[1] end |
#second_arg ⇒ Object
Returns second argument of a method call.
278 279 280 281 |
# File 'lib/ruby_parser/bm_sexp.rb', line 278 def second_arg expect :call, :attrasgn, :safe_call, :safe_attrasgn self[4] end |
#second_arg=(exp) ⇒ Object
Sets second argument of a method call.
284 285 286 287 288 |
# File 'lib/ruby_parser/bm_sexp.rb', line 284 def second_arg= exp expect :call, :attrasgn, :safe_call, :safe_attrasgn @my_hash_value = nil self[4] = exp end |
#set_args(*exp) ⇒ Object
186 187 188 |
# File 'lib/ruby_parser/bm_sexp.rb', line 186 def set_args *exp self.arglist = exp end |
#target ⇒ Object
Returns target of a method call:
s(:call, s(:call, nil, :x, s(:arglist)), :y, s(:arglist, s(:lit, 1)))
^-----------target-----------^
136 137 138 139 |
# File 'lib/ruby_parser/bm_sexp.rb', line 136 def target expect :call, :attrasgn, :safe_call, :safe_attrasgn self[1] end |
#target=(exp) ⇒ Object
Sets the target of a method call:
142 143 144 145 146 |
# File 'lib/ruby_parser/bm_sexp.rb', line 142 def target= exp expect :call, :attrasgn, :safe_call, :safe_attrasgn @my_hash_value = nil self[1] = exp end |
#then_clause ⇒ Object
Returns ‘then’ clause of an if expression:
s(:if,
s(:lvar, :condition),
s(:lvar, :then_val), <-- then clause
s(:lvar, :else_val)))
349 350 351 352 |
# File 'lib/ruby_parser/bm_sexp.rb', line 349 def then_clause expect :if self[2] end |
#third_arg ⇒ Object
290 291 292 293 |
# File 'lib/ruby_parser/bm_sexp.rb', line 290 def third_arg expect :call, :attrasgn, :safe_call, :safe_attrasgn self[5] end |
#third_arg=(exp) ⇒ Object
295 296 297 298 299 |
# File 'lib/ruby_parser/bm_sexp.rb', line 295 def third_arg= exp expect :call, :attrasgn, :safe_call, :safe_attrasgn @my_hash_value = nil self[5] = exp end |
#to_sym ⇒ Object
68 69 70 |
# File 'lib/ruby_parser/bm_sexp.rb', line 68 def to_sym self.value.to_sym end |
#value ⇒ Object
53 54 55 56 |
# File 'lib/ruby_parser/bm_sexp.rb', line 53 def value raise WrongSexpError, "Sexp#value called on multi-item Sexp: `#{self.inspect}`" if size > 2 self[1] end |
#value=(exp) ⇒ Object
58 59 60 61 62 |
# File 'lib/ruby_parser/bm_sexp.rb', line 58 def value= exp raise WrongSexpError, "Sexp#value= called on multi-item Sexp: `#{self.inspect}`" if size > 2 @my_hash_value = nil self[1] = exp end |