============
empty method
============

def foo
end

def foo?
end

def foo!
end

---

(program
  (method (identifier))
  (method (identifier))
  (method (identifier)))

=====================
method with body
=====================

def foo
  bar
end

---

(program (method (identifier) (identifier)))

=====================
"end"-less method
=====================

def foo = bar
def foo() = bar
def foo(x) = bar
def Object.foo = bar
def Object.foo (x) = bar
def foo() = bar rescue (print "error")

---

(program 
  (method (identifier) (identifier))
  (method (identifier) (method_parameters) (identifier))
  (method (identifier) (method_parameters (identifier)) (identifier))
  (singleton_method (constant) (identifier) (identifier))
  (singleton_method (constant) (identifier) (method_parameters (identifier)) (identifier))
  (method (identifier) (method_parameters)
    (rescue_modifier 
      (identifier)
      (parenthesized_statements (call (identifier) (argument_list (string (string_content)))))
    )
  )
)

===========================
method as attribute setter
===========================

def foo=
end

---

(program (method (setter (identifier))))

==============================
method definition of operators
==============================

def `(a)
  "`"
end

def -@(a)
end

def %(a)
end

def ..(a)
end

def !~(a)
end

---

(program
  (method (operator) (method_parameters (identifier)) (string (string_content)))
  (method (operator) (method_parameters (identifier)))
  (method (operator) (method_parameters (identifier)))
  (method (operator) (method_parameters (identifier)))
  (method (operator) (method_parameters (identifier))))

===================================================
method with forward slash name and regex ambiguity
===================================================

puts /(/

def /(name)
end

def / name
end

---

(program
  (call (identifier) (argument_list (regex (string_content))))
  (method (operator) (method_parameters (identifier)))
  (method (operator) (method_parameters (identifier))))


===========================
method with call to super
===========================

def foo
  super
end

def foo
  bar.baz { super }
end

def foo
  super.bar a, b
end

---

(program
  (method (identifier) (super))
  (method
    (identifier)
    (call (identifier) (identifier) (block (super))))
  (method
    (identifier)
    (call (super) (identifier) (argument_list (identifier) (identifier)))))

===========================
method with args
===========================

def foo(bar)
end

def foo(bar); end
def foo(bar) end

---

(program
  (method (identifier) (method_parameters (identifier)))
  (method (identifier) (method_parameters (identifier)))
  (method (identifier) (method_parameters (identifier))))

================================
method with unparenthesized args
================================

def foo bar
end

---

(program (method (identifier) (method_parameters (identifier))))

=========================
method with multiple args
=========================

def foo(bar, quux)
end

---

(program (method (identifier) (method_parameters (identifier) (identifier))))

=========================================
method with multiple unparenthesized args
=========================================

def foo bar, quux
end

---

(program (method (identifier) (method_parameters (identifier) (identifier))))

=========================================
method with keyword parameters
=========================================

def foo(bar: nil, baz:)
end

---

(program
  (method (identifier)
    (method_parameters
      (keyword_parameter (identifier) (nil))
      (keyword_parameter (identifier)))))

=========================================
method with default parameters
=========================================

def foo(bar = nil)
end

def foo(bar=nil)
end

---

(program
  (method (identifier)
    (method_parameters (optional_parameter (identifier) (nil))))
  (method (identifier)
    (method_parameters (optional_parameter (identifier) (nil)))))

=========================================
method with interesting params
=========================================

def foo(*options)
end

def foo(x, *options)
end

def foo(x, *options, y)
end

def foo(**options)
end

def foo(name:, **)
end

def foo(x, **nil)
end

def foo(&block)
end

def foo(...)
  super(...)
end

def foo(a, b, ...)
  bar(b, ...)
end

---

(program
  (method (identifier) (method_parameters (splat_parameter (identifier))))
  (method (identifier) (method_parameters (identifier) (splat_parameter (identifier))))
  (method (identifier) (method_parameters (identifier) (splat_parameter (identifier)) (identifier)))
  (method (identifier) (method_parameters (hash_splat_parameter (identifier))))
  (method (identifier) (method_parameters (keyword_parameter (identifier)) (hash_splat_parameter)))
  (method (identifier) (method_parameters (identifier) (hash_splat_nil)))
  (method (identifier) (method_parameters (block_parameter (identifier))))
  (method (identifier) (method_parameters (forward_parameter))
    (call (super) (argument_list (forward_argument)))
  )  
  (method (identifier) (method_parameters (identifier) (identifier) (forward_parameter))
    (call (identifier) (argument_list (identifier) (forward_argument)))
  )
)

=========================================
singleton method
=========================================

def self.foo
end

---

(program (singleton_method (self) (identifier)))

=========================================
singleton method with body
=========================================

def self.foo
  bar
end

---

(program (singleton_method (self) (identifier) (identifier)))


=========================================
singleton method with arg
=========================================

def self.foo(bar)
end

---

(program (singleton_method (self) (identifier) (method_parameters (identifier))))

=========================================
singleton method with un-parenthesized arg
=========================================

def self.foo bar
end

---

(program (singleton_method (self) (identifier) (method_parameters (identifier))))

=========================================
singleton method with args
=========================================

def self.foo(bar, baz)
end

---

(program (singleton_method (self) (identifier) (method_parameters (identifier) (identifier))))


=========================================
singleton method with un-parenthesized args
=========================================

def self.foo bar, baz
end

---

(program (singleton_method (self) (identifier) (method_parameters (identifier) (identifier))))

===========
empty class
===========

class Foo
end

class Foo; end

class Foo::Bar
end

class ::Foo::Bar
end

class Cß
end

---

(program
  (class (constant))
  (class (constant))
  (class (scope_resolution (constant) (constant)))
  (class (scope_resolution (scope_resolution (constant)) (constant)))
  (class (constant)))

==============
empty subclass
==============

class Foo < Bar
end

---

(program (class (constant) (superclass (constant))))

==================================
empty subclass of namespaced class
==================================

class Foo < Bar::Quux
end

class Foo < ::Bar
end

class Foo < Bar::Baz.new(foo)
end

---

(program
  (class
    (constant)
    (superclass (scope_resolution (constant) (constant))))
  (class
    (constant)
    (superclass (scope_resolution (constant))))
  (class
    (constant)
    (superclass (call (scope_resolution (constant) (constant)) (identifier) (argument_list (identifier))))))

=======================================
unparenthesized call as superclass
=======================================

class A < B.new \
  :c,
  :d
end

---

(program (class
  name: (constant)
  superclass: (superclass (call
    receiver: (constant)
    method: (identifier)
    arguments: (argument_list
      (simple_symbol)
      (simple_symbol))))))

===============
class with body
===============

class Foo
	def bar
	end
end

---

(program (class (constant) (method (identifier))))

=========================================
class within dynamically-computed module
=========================================

class foo()::Bar
end

---

(program (class (scope_resolution (call (identifier) (argument_list)) (constant))))

===============
singleton class
===============

class << self
end

class <<self
end

class << Foo
end

class << Foo::Bar
end

---

(program
  (singleton_class (self))
  (singleton_class (self))
  (singleton_class (constant))
  (singleton_class (scope_resolution (constant) (constant))))


============
empty module
============

module Foo
end

module Foo::Bar
end

---

(program
  (module (constant))
  (module (scope_resolution (constant) (constant))))

================
module with body
================

module Foo
	def bar
	end
end

---

(program (module (constant) (method (identifier))))

========================
module without semicolon
========================

module Foo end

---

(program (module (constant)))

=======
__END__
=======

word
__END__
word
x
ab
d

---

(program (identifier) (uninterpreted))

==============================
module with class with methods
==============================

module A
  class B < C
    include D::E.f.g

    attr_reader :h

    # i
    def j
      k
    end

    def self.l
    end
  end
end

---

(program (module (constant)
  (class (constant) (superclass (constant))
    (call (identifier) (argument_list
      (call
        (call
          (scope_resolution (constant) (constant))
          (identifier))
        (identifier))))

    (call (identifier) (argument_list (simple_symbol)))

    (comment)
    (method (identifier) (identifier))
    (singleton_method (self) (identifier)))))


===========
empty BEGIN block
===========

BEGIN {

}

---

(program (begin_block))

===========
BEGIN block
===========

baz
BEGIN {
foo
}
bar

---

(program (identifier) (begin_block (identifier)) (identifier))

===========
empty END block
===========

END {

}

---

(program (end_block))

===========
END block
===========

baz
END {
foo
}
bar

---

(program (identifier) (end_block (identifier)) (identifier))
