/**
 * @flow
 */

'use strict';

/*
 * Flow types for the Babylon AST.
 */

// Abstract types. Something must extend these.

export type Comment = {
  type: 'CommentLine',
  _CommentLine?: void,
  value: string,
  end: number,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
} | {
  type: 'CommentBlock',
  _CommentBlock?: void,
  value: string,
  end: number,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
};

export type Declaration = {
  type: 'ClassBody',
  _ClassBody?: void,
  body: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassDeclaration',
  _ClassDeclaration?: void,
  body: ClassBody,
  id: ?Identifier,
  superClass: ?Expression,
  decorators: any,
  superTypeParameters: any,
  typeParameters: any,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'FunctionDeclaration',
  _FunctionDeclaration?: void,
  body: BlockStatement,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'MethodDefinition',
  _MethodDefinition?: void,
  computed: boolean,
  key: Node,
  kind: 'constructor' | 'method' | 'get' | 'set',
  static: boolean,
  value: FunctionExpression,
  decorators: ?Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'VariableDeclaration',
  _VariableDeclaration?: void,
  declarations: Array<VariableDeclarator>,
  kind: 'var' | 'let' | 'const',
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassProperty',
  _ClassProperty?: void,
  computed: boolean,
  key: Node,
  static: boolean,
  typeAnnotation: ?TypeAnnotation,
  value: ?Expression,
  decorators: Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Expression = {
  type: 'ArrayExpression',
  _ArrayExpression?: void,
  elements: Array<?Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'AssignmentExpression',
  _AssignmentExpression?: void,
  left: Pattern,
  operator: AssignmentOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'AwaitExpression',
  _AwaitExpression?: void,
  all: boolean,
  argument: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BinaryExpression',
  _BinaryExpression?: void,
  left: Expression,
  operator: BinaryOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BindExpression',
  _BindExpression?: void,
  callee: Node,
  object: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'CallExpression',
  _CallExpression?: void,
  arguments: Array<Node>,
  callee: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassExpression',
  _ClassExpression?: void,
  body: ClassBody,
  id: ?Identifier,
  superClass: ?Expression,
  decorators: any,
  superTypeParameters: any,
  typeParameters: any,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ComprehensionExpression',
  _ComprehensionExpression?: void,
  body: Expression,
  blocks: Array<ComprehensionBlock>,
  filter: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ConditionalExpression',
  _ConditionalExpression?: void,
  alternate: Expression,
  consequent: Expression,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DoExpression',
  _DoExpression?: void,
  body: Statement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'FunctionExpression',
  _FunctionExpression?: void,
  body: BlockStatement,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'Identifier',
  _Identifier?: void,
  name: string,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Literal',
  _Literal?: void,
  raw: string,
  regex: ?{pattern: string, flags: string},
  value: ?(string | boolean | number | RegExp),
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'LogicalExpression',
  _LogicalExpression?: void,
  left: Expression,
  operator: LogicalOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'MemberExpression',
  _MemberExpression?: void,
  computed: boolean,
  object: Expression,
  property: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NewExpression',
  _NewExpression?: void,
  arguments: Array<Node>,
  callee: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectExpression',
  _ObjectExpression?: void,
  properties: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SequenceExpression',
  _SequenceExpression?: void,
  expression: Array<Expression>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TaggedTemplateExpression',
  _TaggedTemplateExpression?: void,
  quasi: TemplateLiteral,
  tag: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TemplateLiteral',
  _TemplateLiteral?: void,
  expressions: Array<Expression>,
  quasis: Array<TemplateElement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ThisExpression',
  _ThisExpression?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'UnaryExpression',
  _UnaryExpression?: void,
  argument: Expression,
  operator: UnaryOperator,
  prefix: true,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'UpdateExpression',
  _UpdateExpression?: void,
  argument: Expression,
  operator: UpdateOperator,
  prefix: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'YieldExpression',
  _YieldExpression?: void,
  argument: ?Expression,
  delegate: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeCastExpression',
  _TypeCastExpression?: void,
  expression: Expression,
  typeAnnotation: TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXElement',
  _JSXElement?: void,
  children: Array<Node>,
  closingElement: ?JSXClosingElement,
  openingElement: JSXOpeningElement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXEmptyExpression',
  _JSXEmptyExpression?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXExpressionContainer',
  _JSXExpressionContainer?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXMemberExpression',
  _JSXMemberExpression?: void,
  computed: boolean,
  object: Node,
  property: JSXIdentifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Function = {
  type: 'ArrowFunctionExpression',
  _ArrowFunctionExpression?: void,
  body: Node,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'FunctionDeclaration',
  _FunctionDeclaration?: void,
  body: BlockStatement,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'FunctionExpression',
  _FunctionExpression?: void,
  body: BlockStatement,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
};

export type Node = {
  type: 'ArrayExpression',
  _ArrayExpression?: void,
  elements: Array<?Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ArrayPattern',
  _ArrayPattern?: void,
  elements: Array<?Node>,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ArrowFunctionExpression',
  _ArrowFunctionExpression?: void,
  body: Node,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'AssignmentExpression',
  _AssignmentExpression?: void,
  left: Pattern,
  operator: AssignmentOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'AssignmentPattern',
  _AssignmentPattern?: void,
  left: Pattern,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'AwaitExpression',
  _AwaitExpression?: void,
  all: boolean,
  argument: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BinaryExpression',
  _BinaryExpression?: void,
  left: Expression,
  operator: BinaryOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BindExpression',
  _BindExpression?: void,
  callee: Node,
  object: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BlockStatement',
  _BlockStatement?: void,
  body: Array<Statement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BreakStatement',
  _BreakStatement?: void,
  label: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'CallExpression',
  _CallExpression?: void,
  arguments: Array<Node>,
  callee: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'CatchClause',
  _CatchClause?: void,
  body: BlockStatement,
  param: Pattern,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassBody',
  _ClassBody?: void,
  body: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassDeclaration',
  _ClassDeclaration?: void,
  body: ClassBody,
  id: ?Identifier,
  superClass: ?Expression,
  decorators: any,
  superTypeParameters: any,
  typeParameters: any,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassExpression',
  _ClassExpression?: void,
  body: ClassBody,
  id: ?Identifier,
  superClass: ?Expression,
  decorators: any,
  superTypeParameters: any,
  typeParameters: any,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ComprehensionBlock',
  _ComprehensionBlock?: void,
  each: boolean,
  left: Pattern,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ComprehensionExpression',
  _ComprehensionExpression?: void,
  body: Expression,
  blocks: Array<ComprehensionBlock>,
  filter: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ConditionalExpression',
  _ConditionalExpression?: void,
  alternate: Expression,
  consequent: Expression,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ContinueStatement',
  _ContinueStatement?: void,
  label: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Decorator',
  _Decorator?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DebuggerStatement',
  _DebuggerStatement?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DoWhileStatement',
  _DoWhileStatement?: void,
  body: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DoExpression',
  _DoExpression?: void,
  body: Statement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'EmptyStatement',
  _EmptyStatement?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExpressionStatement',
  _ExpressionStatement?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'File',
  _File?: void,
  program: Program,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ForInStatement',
  _ForInStatement?: void,
  body: Statement,
  left: Node,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ForOfStatement',
  _ForOfStatement?: void,
  body: Statement,
  left: Node,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ForStatement',
  _ForStatement?: void,
  init: ?Node,
  test: ?Expression,
  update: ?Expression,
  body: Statement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'FunctionDeclaration',
  _FunctionDeclaration?: void,
  body: BlockStatement,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'FunctionExpression',
  _FunctionExpression?: void,
  body: BlockStatement,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
} | {
  type: 'Identifier',
  _Identifier?: void,
  name: string,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'IfStatement',
  _IfStatement?: void,
  alternate: ?Statement,
  consequent: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ImportDefaultSpecifier',
  _ImportDefaultSpecifier?: void,
  local: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ImportNamespaceSpecifier',
  _ImportNamespaceSpecifier?: void,
  local: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ImportDeclaration',
  _ImportDeclaration?: void,
  specifiers: Array<Node>,
  source: Literal,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ImportSpecifier',
  _ImportSpecifier?: void,
  imported: Node,
  local: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'LabeledStatement',
  _LabeledStatement?: void,
  body: Statement,
  label: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Literal',
  _Literal?: void,
  raw: string,
  regex: ?{pattern: string, flags: string},
  value: ?(string | boolean | number | RegExp),
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'LogicalExpression',
  _LogicalExpression?: void,
  left: Expression,
  operator: LogicalOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'MemberExpression',
  _MemberExpression?: void,
  computed: boolean,
  object: Expression,
  property: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'MetaProperty',
  _MetaProperty?: void,
  meta: Node,
  property: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'MethodDefinition',
  _MethodDefinition?: void,
  computed: boolean,
  key: Node,
  kind: 'constructor' | 'method' | 'get' | 'set',
  static: boolean,
  value: FunctionExpression,
  decorators: ?Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NewExpression',
  _NewExpression?: void,
  arguments: Array<Node>,
  callee: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Noop',
  _Noop?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectExpression',
  _ObjectExpression?: void,
  properties: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectPattern',
  _ObjectPattern?: void,
  properties: Array<Node>,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Program',
  _Program?: void,
  body: Array<Statement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Property',
  _Property?: void,
  computed: boolean,
  key: Node,
  kind: 'init' | 'get' | 'set',
  method: boolean,
  shorthand: boolean,
  value: Node,
  decorators: ?Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'RestElement',
  _RestElement?: void,
  argument: Pattern,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ReturnStatement',
  _ReturnStatement?: void,
  argument: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SequenceExpression',
  _SequenceExpression?: void,
  expression: Array<Expression>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SpreadElement',
  _SpreadElement?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SpreadProperty',
  _SpreadProperty?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Super',
  _Super?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SwitchCase',
  _SwitchCase?: void,
  consequent: Array<Statement>,
  test: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SwitchStatement',
  _SwitchStatement?: void,
  cases: Array<SwitchCase>,
  discriminant: Expression,
  lexical: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TaggedTemplateExpression',
  _TaggedTemplateExpression?: void,
  quasi: TemplateLiteral,
  tag: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TemplateElement',
  _TemplateElement?: void,
  tail: boolean,
  value: {cooked: string, raw: string},
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TemplateLiteral',
  _TemplateLiteral?: void,
  expressions: Array<Expression>,
  quasis: Array<TemplateElement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ThisExpression',
  _ThisExpression?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ThrowStatement',
  _ThrowStatement?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TryStatement',
  _TryStatement?: void,
  block: BlockStatement,
  finalizer: ?BlockStatement,
  guardedHandlers: Array<CatchClause>,
  handler: ?CatchClause,
  handlers: ?Array<CatchClause>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'UnaryExpression',
  _UnaryExpression?: void,
  argument: Expression,
  operator: UnaryOperator,
  prefix: true,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'UpdateExpression',
  _UpdateExpression?: void,
  argument: Expression,
  operator: UpdateOperator,
  prefix: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'VariableDeclaration',
  _VariableDeclaration?: void,
  declarations: Array<VariableDeclarator>,
  kind: 'var' | 'let' | 'const',
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'VariableDeclarator',
  _VariableDeclarator?: void,
  id: Pattern,
  init: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'WhileStatement',
  _WhileStatement?: void,
  body: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'WithStatement',
  _WithStatement?: void,
  body: Statement,
  object: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'YieldExpression',
  _YieldExpression?: void,
  argument: ?Expression,
  delegate: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExportAllDeclaration',
  _ExportAllDeclaration?: void,
  exported: Node,
  source: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExportDefaultDeclaration',
  _ExportDefaultDeclaration?: void,
  declaration: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExportNamedDeclaration',
  _ExportNamedDeclaration?: void,
  declaration: Node,
  source: Literal,
  specifiers: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExportDefaultSpecifier',
  _ExportDefaultSpecifier?: void,
  exported: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExportNamespaceSpecifier',
  _ExportNamespaceSpecifier?: void,
  exported: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExportSpecifier',
  _ExportSpecifier?: void,
  local: Node,
  exported: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'AnyTypeAnnotation',
  _AnyTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ArrayTypeAnnotation',
  _ArrayTypeAnnotation?: void,
  elementType: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BooleanLiteralTypeAnnotation',
  _BooleanLiteralTypeAnnotation?: void,
  raw: string,
  value: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BooleanTypeAnnotation',
  _BooleanTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassImplements',
  _ClassImplements?: void,
  id: Identifier,
  typeParameters: ?TypeParameterInstantiation,
  superClass: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ClassProperty',
  _ClassProperty?: void,
  computed: boolean,
  key: Node,
  static: boolean,
  typeAnnotation: ?TypeAnnotation,
  value: ?Expression,
  decorators: Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareClass',
  _DeclareClass?: void,
  body: ObjectTypeAnnotation,
  extends: Array<InterfaceExtends>,
  id: Identifier,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareFunction',
  _DeclareFunction?: void,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareModule',
  _DeclareModule?: void,
  body: BlockStatement,
  id: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareVariable',
  _DeclareVariable?: void,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'FunctionTypeAnnotation',
  _FunctionTypeAnnotation?: void,
  params: Array<FunctionTypeParam>,
  rest: ?FunctionTypeParam,
  returnType: Type,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'FunctionTypeParam',
  _FunctionTypeParam?: void,
  name: Identifier,
  optional: boolean,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'GenericTypeAnnotation',
  _GenericTypeAnnotation?: void,
  id: Node,
  typeParameters: ?TypeParameterInstantiation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'InterfaceExtends',
  _InterfaceExtends?: void,
  id: Identifier,
  typeParameters: ?TypeParameterInstantiation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'InterfaceDeclaration',
  _InterfaceDeclaration?: void,
  body: ObjectTypeAnnotation,
  extends: Array<InterfaceExtends>,
  id: Identifier,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'IntersectionTypeAnnotation',
  _IntersectionTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'MixedTypeAnnotation',
  _MixedTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NullableTypeAnnotation',
  _NullableTypeAnnotation?: void,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NumberLiteralTypeAnnotation',
  _NumberLiteralTypeAnnotation?: void,
  raw: string,
  value: number,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NumberTypeAnnotation',
  _NumberTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'StringLiteralTypeAnnotation',
  _StringLiteralTypeAnnotation?: void,
  raw: string,
  value: string,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'StringTypeAnnotation',
  _StringTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TupleTypeAnnotation',
  _TupleTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeofTypeAnnotation',
  _TypeofTypeAnnotation?: void,
  argument: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeAlias',
  _TypeAlias?: void,
  id: Identifier,
  right: Type,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeAnnotation',
  _TypeAnnotation?: void,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeCastExpression',
  _TypeCastExpression?: void,
  expression: Expression,
  typeAnnotation: TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeParameterDeclaration',
  _TypeParameterDeclaration?: void,
  params: Array<Identifier>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeParameterInstantiation',
  _TypeParameterInstantiation?: void,
  params: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectTypeAnnotation',
  _ObjectTypeAnnotation?: void,
  callProperties: Array<ObjectTypeCallProperty>,
  indexers: Array<ObjectTypeIndexer>,
  properties: Array<ObjectTypeProperty>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectTypeCallProperty',
  _ObjectTypeCallProperty?: void,
  static: boolean,
  value: FunctionTypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectTypeIndexer',
  _ObjectTypeIndexer?: void,
  id: Identifier,
  key: Type,
  value: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectTypeProperty',
  _ObjectTypeProperty?: void,
  key: Node,
  optional: boolean,
  value: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'QualifiedTypeIdentifier',
  _QualifiedTypeIdentifier?: void,
  id: Identifier,
  qualification: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'UnionTypeAnnotation',
  _UnionTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'VoidTypeAnnotation',
  _VoidTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXAttribute',
  _JSXAttribute?: void,
  name: Node,
  value: ?Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXClosingElement',
  _JSXClosingElement?: void,
  name: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXElement',
  _JSXElement?: void,
  children: Array<Node>,
  closingElement: ?JSXClosingElement,
  openingElement: JSXOpeningElement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXEmptyExpression',
  _JSXEmptyExpression?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXExpressionContainer',
  _JSXExpressionContainer?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXIdentifier',
  _JSXIdentifier?: void,
  name: string,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXMemberExpression',
  _JSXMemberExpression?: void,
  computed: boolean,
  object: Node,
  property: JSXIdentifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXNamespacedName',
  _JSXNamespacedName?: void,
  name: JSXIdentifier,
  namespace: JSXIdentifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXOpeningElement',
  _JSXOpeningElement?: void,
  attributes: Array<Node>,
  name: Array<Node>,
  selfClosing: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'JSXSpreadAttribute',
  _JSXSpreadAttribute?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Pattern = {
  type: 'ArrayPattern',
  _ArrayPattern?: void,
  elements: Array<?Node>,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'AssignmentPattern',
  _AssignmentPattern?: void,
  left: Pattern,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'Identifier',
  _Identifier?: void,
  name: string,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectPattern',
  _ObjectPattern?: void,
  properties: Array<Node>,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'RestElement',
  _RestElement?: void,
  argument: Pattern,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Statement = {
  type: 'BlockStatement',
  _BlockStatement?: void,
  body: Array<Statement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BreakStatement',
  _BreakStatement?: void,
  label: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ContinueStatement',
  _ContinueStatement?: void,
  label: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DoWhileStatement',
  _DoWhileStatement?: void,
  body: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'EmptyStatement',
  _EmptyStatement?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ExpressionStatement',
  _ExpressionStatement?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ForInStatement',
  _ForInStatement?: void,
  body: Statement,
  left: Node,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ForOfStatement',
  _ForOfStatement?: void,
  body: Statement,
  left: Node,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ForStatement',
  _ForStatement?: void,
  init: ?Node,
  test: ?Expression,
  update: ?Expression,
  body: Statement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'IfStatement',
  _IfStatement?: void,
  alternate: ?Statement,
  consequent: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'LabeledStatement',
  _LabeledStatement?: void,
  body: Statement,
  label: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ReturnStatement',
  _ReturnStatement?: void,
  argument: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'SwitchStatement',
  _SwitchStatement?: void,
  cases: Array<SwitchCase>,
  discriminant: Expression,
  lexical: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ThrowStatement',
  _ThrowStatement?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TryStatement',
  _TryStatement?: void,
  block: BlockStatement,
  finalizer: ?BlockStatement,
  guardedHandlers: Array<CatchClause>,
  handler: ?CatchClause,
  handlers: ?Array<CatchClause>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'WhileStatement',
  _WhileStatement?: void,
  body: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'WithStatement',
  _WithStatement?: void,
  body: Statement,
  object: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareClass',
  _DeclareClass?: void,
  body: ObjectTypeAnnotation,
  extends: Array<InterfaceExtends>,
  id: Identifier,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareFunction',
  _DeclareFunction?: void,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareModule',
  _DeclareModule?: void,
  body: BlockStatement,
  id: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'DeclareVariable',
  _DeclareVariable?: void,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'InterfaceDeclaration',
  _InterfaceDeclaration?: void,
  body: ObjectTypeAnnotation,
  extends: Array<InterfaceExtends>,
  id: Identifier,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TypeAlias',
  _TypeAlias?: void,
  id: Identifier,
  right: Type,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Type = {
  type: 'AnyTypeAnnotation',
  _AnyTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ArrayTypeAnnotation',
  _ArrayTypeAnnotation?: void,
  elementType: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BooleanLiteralTypeAnnotation',
  _BooleanLiteralTypeAnnotation?: void,
  raw: string,
  value: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'BooleanTypeAnnotation',
  _BooleanTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'FunctionTypeAnnotation',
  _FunctionTypeAnnotation?: void,
  params: Array<FunctionTypeParam>,
  rest: ?FunctionTypeParam,
  returnType: Type,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'GenericTypeAnnotation',
  _GenericTypeAnnotation?: void,
  id: Node,
  typeParameters: ?TypeParameterInstantiation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'IntersectionTypeAnnotation',
  _IntersectionTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'MixedTypeAnnotation',
  _MixedTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NullableTypeAnnotation',
  _NullableTypeAnnotation?: void,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NumberLiteralTypeAnnotation',
  _NumberLiteralTypeAnnotation?: void,
  raw: string,
  value: number,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'NumberTypeAnnotation',
  _NumberTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'StringLiteralTypeAnnotation',
  _StringLiteralTypeAnnotation?: void,
  raw: string,
  value: string,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'StringTypeAnnotation',
  _StringTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'TupleTypeAnnotation',
  _TupleTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'ObjectTypeAnnotation',
  _ObjectTypeAnnotation?: void,
  callProperties: Array<ObjectTypeCallProperty>,
  indexers: Array<ObjectTypeIndexer>,
  properties: Array<ObjectTypeProperty>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'UnionTypeAnnotation',
  _UnionTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
} | {
  type: 'VoidTypeAnnotation',
  _VoidTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// Concrete Types. Nothing can extend these.

export type CommentLine = {
  type: 'CommentLine',
  _CommentLine?: void,
  value: string,
  end: number,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
};

export type CommentBlock = {
  type: 'CommentBlock',
  _CommentBlock?: void,
  value: string,
  end: number,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
};

// Babel concrete types.

export type ArrayExpression = {
  type: 'ArrayExpression',
  _ArrayExpression?: void,
  elements: Array<?Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ArrayPattern = {
  type: 'ArrayPattern',
  _ArrayPattern?: void,
  elements: Array<?Node>,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ArrowFunctionExpression = {
  type: 'ArrowFunctionExpression',
  _ArrowFunctionExpression?: void,
  body: Node,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
};

type AssignmentOperator =
  '=' |
  '+=' |
  '-=' |
  '*=' |
  '/=' |
  '%=' |
  '<<=' |
  '>>=' |
  '>>>=' |
  '|=' |
  '^=' |
  '&=';

export type AssignmentExpression = {
  type: 'AssignmentExpression',
  _AssignmentExpression?: void,
  left: Pattern,
  operator: AssignmentOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type AssignmentPattern = {
  type: 'AssignmentPattern',
  _AssignmentPattern?: void,
  left: Pattern,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type AwaitExpression = {
  type: 'AwaitExpression',
  _AwaitExpression?: void,
  all: boolean,
  argument: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

type BinaryOperator =
  '==' |
  '!=' |
  '===' |
  '!==' |
  '<' |
  '<=' |
  '>' |
  '>=' |
  '<<' |
  '>>' |
  '>>>' |
  '+' |
  '-' |
  '*' |
  '/' |
  '%' |
  '&' |
  '|' |
  '^' |
  'in' |
  'instanceof' |
  '..';

export type BinaryExpression = {
  type: 'BinaryExpression',
  _BinaryExpression?: void,
  left: Expression,
  operator: BinaryOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: What is this?
export type BindExpression = {
  type: 'BindExpression',
  _BindExpression?: void,
  callee: Node,
  object: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type BlockStatement = {
  type: 'BlockStatement',
  _BlockStatement?: void,
  body: Array<Statement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type BreakStatement = {
  type: 'BreakStatement',
  _BreakStatement?: void,
  label: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type CallExpression = {
  type: 'CallExpression',
  _CallExpression?: void,
  arguments: Array<Node>,
  callee: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type CatchClause = {
  type: 'CatchClause',
  _CatchClause?: void,
  body: BlockStatement,
  param: Pattern,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ClassBody = {
  type: 'ClassBody',
  _ClassBody?: void,
  body: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ClassDeclaration = {
  type: 'ClassDeclaration',
  _ClassDeclaration?: void,
  body: ClassBody,
  id: ?Identifier,
  superClass: ?Expression,
  decorators: any,
  superTypeParameters: any,
  typeParameters: any,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ClassExpression = {
  type: 'ClassExpression',
  _ClassExpression?: void,
  body: ClassBody,
  id: ?Identifier,
  superClass: ?Expression,
  decorators: any,
  superTypeParameters: any,
  typeParameters: any,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ComprehensionBlock = {
  type: 'ComprehensionBlock',
  _ComprehensionBlock?: void,
  each: boolean,
  left: Pattern,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ComprehensionExpression = {
  type: 'ComprehensionExpression',
  _ComprehensionExpression?: void,
  body: Expression,
  blocks: Array<ComprehensionBlock>,
  filter: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ConditionalExpression = {
  type: 'ConditionalExpression',
  _ConditionalExpression?: void,
  alternate: Expression,
  consequent: Expression,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ContinueStatement = {
  type: 'ContinueStatement',
  _ContinueStatement?: void,
  label: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type Decorator = {
  type: 'Decorator',
  _Decorator?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type DebuggerStatement = {
  type: 'DebuggerStatement',
  _DebuggerStatement?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type DoWhileStatement = {
  type: 'DoWhileStatement',
  _DoWhileStatement?: void,
  body: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type DoExpression = {
  type: 'DoExpression',
  _DoExpression?: void,
  body: Statement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type EmptyStatement = {
  type: 'EmptyStatement',
  _EmptyStatement?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ExpressionStatement = {
  type: 'ExpressionStatement',
  _ExpressionStatement?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type File = {
  type: 'File',
  _File?: void,
  program: Program,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ForInStatement = {
  type: 'ForInStatement',
  _ForInStatement?: void,
  body: Statement,
  left: Node,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ForOfStatement = {
  type: 'ForOfStatement',
  _ForOfStatement?: void,
  body: Statement,
  left: Node,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ForStatement = {
  type: 'ForStatement',
  _ForStatement?: void,
  init: ?Node,
  test: ?Expression,
  update: ?Expression,
  body: Statement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type FunctionDeclaration = {
  type: 'FunctionDeclaration',
  _FunctionDeclaration?: void,
  body: BlockStatement,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
};

export type FunctionExpression = {
  type: 'FunctionExpression',
  _FunctionExpression?: void,
  body: BlockStatement,
  id: ?Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
  async: boolean,
  defaults: Array<?Expression>,
  expression: boolean,
  generator: boolean,
  params: Array<Pattern>,
  rest: ?Identifier,
  returnType: ?TypeAnnotation,
  typeParameters: ?TypeParameterDeclaration,
};

export type Identifier = {
  type: 'Identifier',
  _Identifier?: void,
  name: string,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type IfStatement = {
  type: 'IfStatement',
  _IfStatement?: void,
  alternate: ?Statement,
  consequent: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ImportDefaultSpecifier = {
  type: 'ImportDefaultSpecifier',
  _ImportDefaultSpecifier?: void,
  local: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ImportNamespaceSpecifier = {
  type: 'ImportNamespaceSpecifier',
  _ImportNamespaceSpecifier?: void,
  local: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ImportDeclaration = {
  type: 'ImportDeclaration',
  _ImportDeclaration?: void,
  specifiers: Array<Node>,
  source: Literal,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ImportSpecifier = {
  type: 'ImportSpecifier',
  _ImportSpecifier?: void,
  imported: Node,
  local: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type LabeledStatement = {
  type: 'LabeledStatement',
  _LabeledStatement?: void,
  body: Statement,
  label: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Literal = {
  type: 'Literal',
  _Literal?: void,
  raw: string,
  regex: ?{pattern: string, flags: string},
  value: ?(string | boolean | number | RegExp),
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

type LogicalOperator = '||' | '&&';

export type LogicalExpression = {
  type: 'LogicalExpression',
  _LogicalExpression?: void,
  left: Expression,
  operator: LogicalOperator,
  right: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type MemberExpression = {
  type: 'MemberExpression',
  _MemberExpression?: void,
  computed: boolean,
  object: Expression,
  property: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type MetaProperty = {
  type: 'MetaProperty',
  _MetaProperty?: void,
  meta: Node,
  property: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type MethodDefinition = {
  type: 'MethodDefinition',
  _MethodDefinition?: void,
  computed: boolean,
  key: Node,
  kind: 'constructor' | 'method' | 'get' | 'set',
  static: boolean,
  value: FunctionExpression,
  decorators: ?Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type NewExpression = {
  type: 'NewExpression',
  _NewExpression?: void,
  arguments: Array<Node>,
  callee: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Noop = {
  type: 'Noop',
  _Noop?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ObjectExpression = {
  type: 'ObjectExpression',
  _ObjectExpression?: void,
  properties: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ObjectPattern = {
  type: 'ObjectPattern',
  _ObjectPattern?: void,
  properties: Array<Node>,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Program = {
  type: 'Program',
  _Program?: void,
  body: Array<Statement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Property = {
  type: 'Property',
  _Property?: void,
  computed: boolean,
  key: Node,
  kind: 'init' | 'get' | 'set',
  method: boolean,
  shorthand: boolean,
  value: Node,
  decorators: ?Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type RestElement = {
  type: 'RestElement',
  _RestElement?: void,
  argument: Pattern,
  typeAnnotation: ?TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ReturnStatement = {
  type: 'ReturnStatement',
  _ReturnStatement?: void,
  argument: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type SequenceExpression = {
  type: 'SequenceExpression',
  _SequenceExpression?: void,
  expression: Array<Expression>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type SpreadElement = {
  type: 'SpreadElement',
  _SpreadElement?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type SpreadProperty = {
  type: 'SpreadProperty',
  _SpreadProperty?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type Super = {
  type: 'Super',
  _Super?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type SwitchCase = {
  type: 'SwitchCase',
  _SwitchCase?: void,
  consequent: Array<Statement>,
  test: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type SwitchStatement = {
  type: 'SwitchStatement',
  _SwitchStatement?: void,
  cases: Array<SwitchCase>,
  discriminant: Expression,
  lexical: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TaggedTemplateExpression = {
  type: 'TaggedTemplateExpression',
  _TaggedTemplateExpression?: void,
  quasi: TemplateLiteral,
  tag: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TemplateElement = {
  type: 'TemplateElement',
  _TemplateElement?: void,
  tail: boolean,
  value: {cooked: string, raw: string},
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TemplateLiteral = {
  type: 'TemplateLiteral',
  _TemplateLiteral?: void,
  expressions: Array<Expression>,
  quasis: Array<TemplateElement>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ThisExpression = {
  type: 'ThisExpression',
  _ThisExpression?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ThrowStatement = {
  type: 'ThrowStatement',
  _ThrowStatement?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TryStatement = {
  type: 'TryStatement',
  _TryStatement?: void,
  block: BlockStatement,
  finalizer: ?BlockStatement,
  guardedHandlers: Array<CatchClause>,
  handler: ?CatchClause,
  handlers: ?Array<CatchClause>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

type UnaryOperator = '-' | '+' | '!' | '~' | 'typeof' | 'void' | 'delete';

export type UnaryExpression = {
  type: 'UnaryExpression',
  _UnaryExpression?: void,
  argument: Expression,
  operator: UnaryOperator,
  prefix: true,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

type UpdateOperator = '++' | '--';

export type UpdateExpression = {
  type: 'UpdateExpression',
  _UpdateExpression?: void,
  argument: Expression,
  operator: UpdateOperator,
  prefix: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type VariableDeclaration = {
  type: 'VariableDeclaration',
  _VariableDeclaration?: void,
  declarations: Array<VariableDeclarator>,
  kind: 'var' | 'let' | 'const',
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type VariableDeclarator = {
  type: 'VariableDeclarator',
  _VariableDeclarator?: void,
  id: Pattern,
  init: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type WhileStatement = {
  type: 'WhileStatement',
  _WhileStatement?: void,
  body: Statement,
  test: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type WithStatement = {
  type: 'WithStatement',
  _WithStatement?: void,
  body: Statement,
  object: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type YieldExpression = {
  type: 'YieldExpression',
  _YieldExpression?: void,
  argument: ?Expression,
  delegate: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ExportAllDeclaration = {
  type: 'ExportAllDeclaration',
  _ExportAllDeclaration?: void,
  exported: Node,
  source: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ExportDefaultDeclaration = {
  type: 'ExportDefaultDeclaration',
  _ExportDefaultDeclaration?: void,
  declaration: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ExportNamedDeclaration = {
  type: 'ExportNamedDeclaration',
  _ExportNamedDeclaration?: void,
  declaration: Node,
  source: Literal,
  specifiers: Array<Node>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ExportDefaultSpecifier = {
  type: 'ExportDefaultSpecifier',
  _ExportDefaultSpecifier?: void,
  exported: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ExportNamespaceSpecifier = {
  type: 'ExportNamespaceSpecifier',
  _ExportNamespaceSpecifier?: void,
  exported: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type ExportSpecifier = {
  type: 'ExportSpecifier',
  _ExportSpecifier?: void,
  local: Node,
  exported: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type AnyTypeAnnotation = {
  type: 'AnyTypeAnnotation',
  _AnyTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ArrayTypeAnnotation = {
  type: 'ArrayTypeAnnotation',
  _ArrayTypeAnnotation?: void,
  elementType: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type BooleanLiteralTypeAnnotation = {
  type: 'BooleanLiteralTypeAnnotation',
  _BooleanLiteralTypeAnnotation?: void,
  raw: string,
  value: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type BooleanTypeAnnotation = {
  type: 'BooleanTypeAnnotation',
  _BooleanTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ClassImplements = {
  type: 'ClassImplements',
  _ClassImplements?: void,
  id: Identifier,
  typeParameters: ?TypeParameterInstantiation,
  superClass: ?Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ClassProperty = {
  type: 'ClassProperty',
  _ClassProperty?: void,
  computed: boolean,
  key: Node,
  static: boolean,
  typeAnnotation: ?TypeAnnotation,
  value: ?Expression,
  decorators: Array<Decorator>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type DeclareClass = {
  type: 'DeclareClass',
  _DeclareClass?: void,
  body: ObjectTypeAnnotation,
  extends: Array<InterfaceExtends>,
  id: Identifier,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type DeclareFunction = {
  type: 'DeclareFunction',
  _DeclareFunction?: void,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type DeclareModule = {
  type: 'DeclareModule',
  _DeclareModule?: void,
  body: BlockStatement,
  id: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

// TODO: Make this correct.
export type DeclareVariable = {
  type: 'DeclareVariable',
  _DeclareVariable?: void,
  id: Identifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type FunctionTypeAnnotation = {
  type: 'FunctionTypeAnnotation',
  _FunctionTypeAnnotation?: void,
  params: Array<FunctionTypeParam>,
  rest: ?FunctionTypeParam,
  returnType: Type,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type FunctionTypeParam = {
  type: 'FunctionTypeParam',
  _FunctionTypeParam?: void,
  name: Identifier,
  optional: boolean,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type GenericTypeAnnotation = {
  type: 'GenericTypeAnnotation',
  _GenericTypeAnnotation?: void,
  id: Node,
  typeParameters: ?TypeParameterInstantiation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type InterfaceExtends = {
  type: 'InterfaceExtends',
  _InterfaceExtends?: void,
  id: Identifier,
  typeParameters: ?TypeParameterInstantiation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type InterfaceDeclaration = {
  type: 'InterfaceDeclaration',
  _InterfaceDeclaration?: void,
  body: ObjectTypeAnnotation,
  extends: Array<InterfaceExtends>,
  id: Identifier,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type IntersectionTypeAnnotation = {
  type: 'IntersectionTypeAnnotation',
  _IntersectionTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type MixedTypeAnnotation = {
  type: 'MixedTypeAnnotation',
  _MixedTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type NullableTypeAnnotation = {
  type: 'NullableTypeAnnotation',
  _NullableTypeAnnotation?: void,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type NumberLiteralTypeAnnotation = {
  type: 'NumberLiteralTypeAnnotation',
  _NumberLiteralTypeAnnotation?: void,
  raw: string,
  value: number,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type NumberTypeAnnotation = {
  type: 'NumberTypeAnnotation',
  _NumberTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type StringLiteralTypeAnnotation = {
  type: 'StringLiteralTypeAnnotation',
  _StringLiteralTypeAnnotation?: void,
  raw: string,
  value: string,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type StringTypeAnnotation = {
  type: 'StringTypeAnnotation',
  _StringTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TupleTypeAnnotation = {
  type: 'TupleTypeAnnotation',
  _TupleTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TypeofTypeAnnotation = {
  type: 'TypeofTypeAnnotation',
  _TypeofTypeAnnotation?: void,
  argument: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TypeAlias = {
  type: 'TypeAlias',
  _TypeAlias?: void,
  id: Identifier,
  right: Type,
  typeParameters: ?TypeParameterDeclaration,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TypeAnnotation = {
  type: 'TypeAnnotation',
  _TypeAnnotation?: void,
  typeAnnotation: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TypeCastExpression = {
  type: 'TypeCastExpression',
  _TypeCastExpression?: void,
  expression: Expression,
  typeAnnotation: TypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TypeParameterDeclaration = {
  type: 'TypeParameterDeclaration',
  _TypeParameterDeclaration?: void,
  params: Array<Identifier>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type TypeParameterInstantiation = {
  type: 'TypeParameterInstantiation',
  _TypeParameterInstantiation?: void,
  params: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ObjectTypeAnnotation = {
  type: 'ObjectTypeAnnotation',
  _ObjectTypeAnnotation?: void,
  callProperties: Array<ObjectTypeCallProperty>,
  indexers: Array<ObjectTypeIndexer>,
  properties: Array<ObjectTypeProperty>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ObjectTypeCallProperty = {
  type: 'ObjectTypeCallProperty',
  _ObjectTypeCallProperty?: void,
  static: boolean,
  value: FunctionTypeAnnotation,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ObjectTypeIndexer = {
  type: 'ObjectTypeIndexer',
  _ObjectTypeIndexer?: void,
  id: Identifier,
  key: Type,
  value: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type ObjectTypeProperty = {
  type: 'ObjectTypeProperty',
  _ObjectTypeProperty?: void,
  key: Node,
  optional: boolean,
  value: Type,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type QualifiedTypeIdentifier = {
  type: 'QualifiedTypeIdentifier',
  _QualifiedTypeIdentifier?: void,
  id: Identifier,
  qualification: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type UnionTypeAnnotation = {
  type: 'UnionTypeAnnotation',
  _UnionTypeAnnotation?: void,
  types: Array<Type>,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type VoidTypeAnnotation = {
  type: 'VoidTypeAnnotation',
  _VoidTypeAnnotation?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXAttribute = {
  type: 'JSXAttribute',
  _JSXAttribute?: void,
  name: Node,
  value: ?Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXClosingElement = {
  type: 'JSXClosingElement',
  _JSXClosingElement?: void,
  name: Node,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXElement = {
  type: 'JSXElement',
  _JSXElement?: void,
  children: Array<Node>,
  closingElement: ?JSXClosingElement,
  openingElement: JSXOpeningElement,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXEmptyExpression = {
  type: 'JSXEmptyExpression',
  _JSXEmptyExpression?: void,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXExpressionContainer = {
  type: 'JSXExpressionContainer',
  _JSXExpressionContainer?: void,
  expression: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXIdentifier = {
  type: 'JSXIdentifier',
  _JSXIdentifier?: void,
  name: string,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXMemberExpression = {
  type: 'JSXMemberExpression',
  _JSXMemberExpression?: void,
  computed: boolean,
  object: Node,
  property: JSXIdentifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXNamespacedName = {
  type: 'JSXNamespacedName',
  _JSXNamespacedName?: void,
  name: JSXIdentifier,
  namespace: JSXIdentifier,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXOpeningElement = {
  type: 'JSXOpeningElement',
  _JSXOpeningElement?: void,
  attributes: Array<Node>,
  name: Array<Node>,
  selfClosing: boolean,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};

export type JSXSpreadAttribute = {
  type: 'JSXSpreadAttribute',
  _JSXSpreadAttribute?: void,
  argument: Expression,
  end: number,
  innerComments: ?Array<Comment>,
  leadingComments: ?Array<Comment>,
  loc: {
    end: {column: number, line: number},
    start: {column: number, line: number},
  },
  start: number,
  trailingComments: ?Array<Comment>,
};
