==================================
Functions with typed parameters
==================================

function greeter(person: string) {
  return "Hello, " + person;
}

function foo<T>(x: T): T {

}

function foo<T, U>(a: T[], f: (x: T) => U): U[] {

}

function foo<T, U>(this: T[]): U[] {
  return []
}

---

(program
  (function_declaration
    name: (identifier)
    parameters: (formal_parameters (required_parameter (identifier) (type_annotation (predefined_type))))
    body: (statement_block
      (return_statement (binary_expression
        left: (string)
        right: (identifier)))))
  (function_declaration
    name: (identifier)
    type_parameters: (type_parameters (type_parameter (type_identifier)))
    parameters: (formal_parameters (required_parameter (identifier) (type_annotation (type_identifier))))
    return_type: (type_annotation (type_identifier))
    body: (statement_block))
  (function_declaration
    name: (identifier)
    type_parameters: (type_parameters (type_parameter (type_identifier)) (type_parameter (type_identifier)))
    parameters: (formal_parameters
      (required_parameter
        (identifier)
        (type_annotation (array_type (type_identifier))))
      (required_parameter
        (identifier)
        (type_annotation
          (function_type
            (formal_parameters (required_parameter (identifier) (type_annotation (type_identifier))))
            (type_identifier)))))
    return_type: (type_annotation (array_type (type_identifier)))
    body: (statement_block))
  (function_declaration
    name: (identifier)
    type_parameters: (type_parameters (type_parameter (type_identifier)) (type_parameter (type_identifier)))
    parameters: (formal_parameters
      (required_parameter (this) (type_annotation (array_type (type_identifier)))))
    return_type: (type_annotation (array_type (type_identifier)))
    body: (statement_block (return_statement (array)))))

==================================
Function calls with type arguments
==================================

const lines = new Array<DiffLine>()

---

(program
  (lexical_declaration
    (variable_declarator
      (identifier)
      (new_expression (identifier) (type_arguments (type_identifier)) (arguments)))))

==================================
Arrow functions and generators with call signatures
==================================

<A>(amount, interestRate, duration): number => 2

function* foo<A>(amount, interestRate, duration): number {
	yield amount * interestRate * duration / 12
}

(module: any): number => 2

---

(program
  (expression_statement
    (arrow_function
      (type_parameters (type_parameter (type_identifier)))
      (formal_parameters
        (required_parameter (identifier))
        (required_parameter (identifier))
        (required_parameter (identifier)))
      (type_annotation (predefined_type))
      (number)))
    (generator_function_declaration
      (identifier)
      (type_parameters (type_parameter (type_identifier)))
      (formal_parameters
        (required_parameter (identifier))
        (required_parameter (identifier))
        (required_parameter (identifier)))
      (type_annotation (predefined_type))
      (statement_block
        (expression_statement (yield_expression (binary_expression
          (binary_expression (binary_expression (identifier) (identifier)) (identifier))
          (number))))))
  (expression_statement
    (arrow_function
      (formal_parameters (required_parameter (identifier) (type_annotation (predefined_type))))
      (type_annotation (predefined_type))
      (number))))

==================================
Arrow function with parameter named async
==================================

const x = async => async;

---

(program
  (lexical_declaration (variable_declarator (identifier) (arrow_function (identifier) (identifier)))))

==================================
Super
==================================

class A extends B {
    constructor(x: number, y: number) {
        super(x);
    }
    public toString() {
        return super.toString() + " y=" + this.y;
    }
}

---

(program
  (class_declaration
    name: (type_identifier)
    (class_heritage (extends_clause (type_identifier)))
    body: (class_body
      (method_definition
        name: (property_identifier)
        parameters: (formal_parameters
          (required_parameter (identifier) (type_annotation (predefined_type)))
          (required_parameter (identifier) (type_annotation (predefined_type))))
        body: (statement_block
          (expression_statement (call_expression
            function: (super)
            arguments: (arguments (identifier))))))
      (method_definition
        (accessibility_modifier)
        name: (property_identifier)
        parameters: (formal_parameters)
        body: (statement_block
          (return_statement
            (binary_expression
              left: (binary_expression
                left: (call_expression
                  function: (member_expression
                    object: (super)
                    property: (property_identifier))
                  arguments: (arguments))
                right: (string))
              right: (member_expression
                object: (this)
                property: (property_identifier)))))))))
