// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`base_class.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
// @flow

class Base {
  unannotatedField;
  annotatedField: number;
  initializedField = 42;
  initializedFieldWithThis = this.initializedField;
  annotatedInitializedFieldValid: ?number = 42;
  annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number

  static unannotatedField;
  static annotatedField: number;
  static initializedField = 'asdf';
  static initializedFieldWithThis = this.initializedField;
  static annotatedInitializedFieldValid: ?number = 42;
  static annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number
}

var o = new Base();

/**
 * Unannotated fields are open.
 */
(o.unannotatedField: string);
(o.unannotatedField: number);
(Base.unannotatedField: string);
(Base.unannotatedField: number);

/**
 * Annotated (but uninitialized) fields still have a type.
 */
(o.annotatedField: number);
(o.annotatedField: string); // Error: number ~> string
(Base.annotatedField: number);
(Base.annotatedField: string); // Error: number ~> string

/**
 * Initialized (but unannotated) fields assume the type of their initializer.
 */
(o.initializedField: number);
(o.initializedField: string); // Error: number ~> string
(Base.initializedField: string);
(Base.initializedField: number); // Error: string ~> number

/**
 * Initialized fields can reference \`this\`.
 */
(o.initializedFieldWithThis: number);
(o.initializedFieldWithThis: string); // Error: number ~> string
(Base.initializedFieldWithThis: string);
(Base.initializedFieldWithThis: number); // Error: string ~> number

/**
 * Initialized + annotated fields take the type of the annotation.
 * (Note that this matters when the annotation is more general than the type of
 *  the initializer)
 */
(o.annotatedInitializedFieldValid: ?number);
(o.annotatedInitializedFieldValid: number); // Error: ?number ~> number
(Base.annotatedInitializedFieldValid: ?number);
(Base.annotatedInitializedFieldValid: number); // Error: ?number ~> number

/**
 * Initialized + annotated fields where the init/annot combo is a mismatch
 * should assume the type of the annotation.
 *
 * (This happens in addition to erroring at the site of initialization)
 */
(o.annotatedInitializedFieldInvalid: number);
(o.annotatedInitializedFieldInvalid: string); // Error: number ~> string
(Base.annotatedInitializedFieldInvalid: number);
(Base.annotatedInitializedFieldInvalid: string); // Error: number ~> string

=====================================output=====================================
// @flow

class Base {
  unannotatedField;
  annotatedField: number;
  initializedField = 42;
  initializedFieldWithThis = this.initializedField;
  annotatedInitializedFieldValid: ?number = 42;
  annotatedInitializedFieldInvalid: number = "asdf"; // Error: string ~> number

  static unannotatedField;
  static annotatedField: number;
  static initializedField = "asdf";
  static initializedFieldWithThis = this.initializedField;
  static annotatedInitializedFieldValid: ?number = 42;
  static annotatedInitializedFieldInvalid: number = "asdf"; // Error: string ~> number
}

var o = new Base();

/**
 * Unannotated fields are open.
 */
(o.unannotatedField: string);
(o.unannotatedField: number);
(Base.unannotatedField: string);
(Base.unannotatedField: number);

/**
 * Annotated (but uninitialized) fields still have a type.
 */
(o.annotatedField: number);
(o.annotatedField: string); // Error: number ~> string
(Base.annotatedField: number);
(Base.annotatedField: string); // Error: number ~> string

/**
 * Initialized (but unannotated) fields assume the type of their initializer.
 */
(o.initializedField: number);
(o.initializedField: string); // Error: number ~> string
(Base.initializedField: string);
(Base.initializedField: number); // Error: string ~> number

/**
 * Initialized fields can reference \`this\`.
 */
(o.initializedFieldWithThis: number);
(o.initializedFieldWithThis: string); // Error: number ~> string
(Base.initializedFieldWithThis: string);
(Base.initializedFieldWithThis: number); // Error: string ~> number

/**
 * Initialized + annotated fields take the type of the annotation.
 * (Note that this matters when the annotation is more general than the type of
 *  the initializer)
 */
(o.annotatedInitializedFieldValid: ?number);
(o.annotatedInitializedFieldValid: number); // Error: ?number ~> number
(Base.annotatedInitializedFieldValid: ?number);
(Base.annotatedInitializedFieldValid: number); // Error: ?number ~> number

/**
 * Initialized + annotated fields where the init/annot combo is a mismatch
 * should assume the type of the annotation.
 *
 * (This happens in addition to erroring at the site of initialization)
 */
(o.annotatedInitializedFieldInvalid: number);
(o.annotatedInitializedFieldInvalid: string); // Error: number ~> string
(Base.annotatedInitializedFieldInvalid: number);
(Base.annotatedInitializedFieldInvalid: string); // Error: number ~> string

================================================================================
`;

exports[`derived_class.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
// @flow

class Base {
  base_unannotatedField;
  base_annotatedField: number;
  base_initializedField = 42;
  base_initializedFieldWithThis = this.base_initializedField;
  base_annotatedInitializedFieldValid: ?number = 42;
  base_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number

  static base_unannotatedField;
  static base_annotatedField: number;
  static base_initializedField = 'asdf';
  static base_initializedFieldWithThis = this.base_initializedField;
  static base_annotatedInitializedFieldValid: ?number = 42;
  static base_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number

  inherited_initializer = 42;
  static inherited_initializer = 42;
}

class Child extends Base {
  child_unannotatedField;
  child_annotatedField: number;
  child_initializedField = 42;
  child_initializedFieldWithThis = this.child_initializedField;
  child_annotatedInitializedFieldValid: ?number = 42;
  child_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number

  static child_unannotatedField;
  static child_annotatedField: number;
  static child_initializedField = 'asdf';
  static child_initializedFieldWithThis = this.child_initializedField;
  static child_annotatedInitializedFieldValid: ?number = 42;
  static child_annotatedInitializedFieldInvalid: number = 'asdf'; // Error: string ~> number

  inherited_initializer;
  static inherited_initializer;
}

var o = new Child();

/**
 * Unannotated fields are open.
 */
(o.base_unannotatedField: string);
(o.base_unannotatedField: number);
(Child.base_unannotatedField: string);
(Child.base_unannotatedField: number);

(o.child_unannotatedField: string);
(o.child_unannotatedField: number);
(Child.child_unannotatedField: string);
(Child.child_unannotatedField: number);


/**
 * Annotated (but uninitialized) fields still have a type.
 */
(o.base_annotatedField: number);
(o.base_annotatedField: string); // Error: number ~> string
(Child.base_annotatedField: number);
(Child.base_annotatedField: string); // Error: number ~> string

(o.child_annotatedField: number);
(o.child_annotatedField: string); // Error: number ~> string
(Child.child_annotatedField: number);
(Child.child_annotatedField: string); // Error: number ~> string

/**
 * Initialized (but unannotated) fields assume the type of their initializer.
 */
(o.base_initializedField: number);
(o.base_initializedField: string); // Error: number ~> string
(Child.base_initializedField: string);
(Child.base_initializedField: number); // Error: string ~> number

(o.child_initializedField: number);
(o.child_initializedField: string); // Error: number ~> string
(Child.child_initializedField: string);
(Child.child_initializedField: number); // Error: string ~> number

/**
 * Initialized fields can reference \`this\`.
 */
(o.base_initializedFieldWithThis: number);
(o.base_initializedFieldWithThis: string); // Error: number ~> string
(Child.base_initializedFieldWithThis: string);
(Child.base_initializedFieldWithThis: number); // Error: string ~> number

(o.child_initializedFieldWithThis: number);
(o.child_initializedFieldWithThis: string); // Error: number ~> string
(Child.child_initializedFieldWithThis: string);
(Child.child_initializedFieldWithThis: number); // Error: string ~> number

/**
 * Initialized + annotated fields take the type of the annotation.
 * (Note that this matters when the annotation is more general than the type of
 *  the initializer)
 */
(o.base_annotatedInitializedFieldValid: ?number);
(o.base_annotatedInitializedFieldValid: number); // Error: ?number ~> number
(Child.base_annotatedInitializedFieldValid: ?number);
(Child.base_annotatedInitializedFieldValid: number); // Error: ?number ~> number

(o.child_annotatedInitializedFieldValid: ?number);
(o.child_annotatedInitializedFieldValid: number); // Error: ?number ~> number
(Child.child_annotatedInitializedFieldValid: ?number);
(Child.child_annotatedInitializedFieldValid: number); // Error: ?number ~> number

/**
 * Initialized + annotated fields where the init/annot combo is a mismatch
 * should assume the type of the annotation.
 *
 * (This happens in addition to erroring at the site of initialization)
 */
(o.base_annotatedInitializedFieldInvalid: number);
(o.base_annotatedInitializedFieldInvalid: string); // Error: number ~> string
(Child.base_annotatedInitializedFieldInvalid: number);
(Child.base_annotatedInitializedFieldInvalid: string); // Error: number ~> string

(o.child_annotatedInitializedFieldInvalid: number);
(o.child_annotatedInitializedFieldInvalid: string); // Error: number ~> string
(Child.child_annotatedInitializedFieldInvalid: number);
(Child.child_annotatedInitializedFieldInvalid: string); // Error: number ~> string

/**
 * Derived fields without an initializer that shadow base fields *with* an
 * initializer should have the type of the base field.
 */
(o.inherited_initializer: number);
(o.inherited_initializer: string); // Error: number ~> string
(Child.inherited_initializer: number);
(Child.inherited_initializer: string); // Error: number ~> string

=====================================output=====================================
// @flow

class Base {
  base_unannotatedField;
  base_annotatedField: number;
  base_initializedField = 42;
  base_initializedFieldWithThis = this.base_initializedField;
  base_annotatedInitializedFieldValid: ?number = 42;
  base_annotatedInitializedFieldInvalid: number = "asdf"; // Error: string ~> number

  static base_unannotatedField;
  static base_annotatedField: number;
  static base_initializedField = "asdf";
  static base_initializedFieldWithThis = this.base_initializedField;
  static base_annotatedInitializedFieldValid: ?number = 42;
  static base_annotatedInitializedFieldInvalid: number = "asdf"; // Error: string ~> number

  inherited_initializer = 42;
  static inherited_initializer = 42;
}

class Child extends Base {
  child_unannotatedField;
  child_annotatedField: number;
  child_initializedField = 42;
  child_initializedFieldWithThis = this.child_initializedField;
  child_annotatedInitializedFieldValid: ?number = 42;
  child_annotatedInitializedFieldInvalid: number = "asdf"; // Error: string ~> number

  static child_unannotatedField;
  static child_annotatedField: number;
  static child_initializedField = "asdf";
  static child_initializedFieldWithThis = this.child_initializedField;
  static child_annotatedInitializedFieldValid: ?number = 42;
  static child_annotatedInitializedFieldInvalid: number = "asdf"; // Error: string ~> number

  inherited_initializer;
  static inherited_initializer;
}

var o = new Child();

/**
 * Unannotated fields are open.
 */
(o.base_unannotatedField: string);
(o.base_unannotatedField: number);
(Child.base_unannotatedField: string);
(Child.base_unannotatedField: number);

(o.child_unannotatedField: string);
(o.child_unannotatedField: number);
(Child.child_unannotatedField: string);
(Child.child_unannotatedField: number);

/**
 * Annotated (but uninitialized) fields still have a type.
 */
(o.base_annotatedField: number);
(o.base_annotatedField: string); // Error: number ~> string
(Child.base_annotatedField: number);
(Child.base_annotatedField: string); // Error: number ~> string

(o.child_annotatedField: number);
(o.child_annotatedField: string); // Error: number ~> string
(Child.child_annotatedField: number);
(Child.child_annotatedField: string); // Error: number ~> string

/**
 * Initialized (but unannotated) fields assume the type of their initializer.
 */
(o.base_initializedField: number);
(o.base_initializedField: string); // Error: number ~> string
(Child.base_initializedField: string);
(Child.base_initializedField: number); // Error: string ~> number

(o.child_initializedField: number);
(o.child_initializedField: string); // Error: number ~> string
(Child.child_initializedField: string);
(Child.child_initializedField: number); // Error: string ~> number

/**
 * Initialized fields can reference \`this\`.
 */
(o.base_initializedFieldWithThis: number);
(o.base_initializedFieldWithThis: string); // Error: number ~> string
(Child.base_initializedFieldWithThis: string);
(Child.base_initializedFieldWithThis: number); // Error: string ~> number

(o.child_initializedFieldWithThis: number);
(o.child_initializedFieldWithThis: string); // Error: number ~> string
(Child.child_initializedFieldWithThis: string);
(Child.child_initializedFieldWithThis: number); // Error: string ~> number

/**
 * Initialized + annotated fields take the type of the annotation.
 * (Note that this matters when the annotation is more general than the type of
 *  the initializer)
 */
(o.base_annotatedInitializedFieldValid: ?number);
(o.base_annotatedInitializedFieldValid: number); // Error: ?number ~> number
(Child.base_annotatedInitializedFieldValid: ?number);
(Child.base_annotatedInitializedFieldValid: number); // Error: ?number ~> number

(o.child_annotatedInitializedFieldValid: ?number);
(o.child_annotatedInitializedFieldValid: number); // Error: ?number ~> number
(Child.child_annotatedInitializedFieldValid: ?number);
(Child.child_annotatedInitializedFieldValid: number); // Error: ?number ~> number

/**
 * Initialized + annotated fields where the init/annot combo is a mismatch
 * should assume the type of the annotation.
 *
 * (This happens in addition to erroring at the site of initialization)
 */
(o.base_annotatedInitializedFieldInvalid: number);
(o.base_annotatedInitializedFieldInvalid: string); // Error: number ~> string
(Child.base_annotatedInitializedFieldInvalid: number);
(Child.base_annotatedInitializedFieldInvalid: string); // Error: number ~> string

(o.child_annotatedInitializedFieldInvalid: number);
(o.child_annotatedInitializedFieldInvalid: string); // Error: number ~> string
(Child.child_annotatedInitializedFieldInvalid: number);
(Child.child_annotatedInitializedFieldInvalid: string); // Error: number ~> string

/**
 * Derived fields without an initializer that shadow base fields *with* an
 * initializer should have the type of the base field.
 */
(o.inherited_initializer: number);
(o.inherited_initializer: string); // Error: number ~> string
(Child.inherited_initializer: number);
(Child.inherited_initializer: string); // Error: number ~> string

================================================================================
`;

exports[`generic_class.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
// @flow

/**
 * Fields annotated with a generic should assume a type once the type param
 * is instantiated.
 */
class ClassAnnotated<T> {
  p: T;
  static p: T;
}

var o1 = new ClassAnnotated();
o1.p = 42;
(o1.p: number);
(o1.p: string); // Error: number ~> string
ClassAnnotated.p = 42;
(ClassAnnotated.p: number);
(ClassAnnotated.p: string); // Error: number ~> string


/**
 * It's always an error to initialized a generically-typed field with an
 * expression of any type other than the generic itself.
 */
class ClassGenericInitialized<T, U> {
  invalid: T = 42; // Error: number ~> Generic<T>
  valid: T = ((42:any):T);

  static invalid: T = 42; // Error: number ~> Generic<T>
  static valid: T = ((42:any):T);
}

=====================================output=====================================
// @flow

/**
 * Fields annotated with a generic should assume a type once the type param
 * is instantiated.
 */
class ClassAnnotated<T> {
  p: T;
  static p: T;
}

var o1 = new ClassAnnotated();
o1.p = 42;
(o1.p: number);
(o1.p: string); // Error: number ~> string
ClassAnnotated.p = 42;
(ClassAnnotated.p: number);
(ClassAnnotated.p: string); // Error: number ~> string

/**
 * It's always an error to initialized a generically-typed field with an
 * expression of any type other than the generic itself.
 */
class ClassGenericInitialized<T, U> {
  invalid: T = 42; // Error: number ~> Generic<T>
  valid: T = ((42: any): T);

  static invalid: T = 42; // Error: number ~> Generic<T>
  static valid: T = ((42: any): T);
}

================================================================================
`;

exports[`scoping.js 1`] = `
====================================options=====================================
parsers: ["flow"]
printWidth: 80
                                                                                | printWidth
=====================================input======================================
// @flow

var someVar = 42;

class Foo {
  outer = someVar;
  selfTyped: Foo;
  selfTypedInit = new Foo();

  static outer = someVar;
  static selfTyped: Foo;
  static selfTypedInit = new Foo();

  constructor() {
    var someVar = 'asdf';
  }
}

/**
 * Field initializers execute in a scope immediately under the scope outside the
 * class definition.
 */
(new Foo().outer: number);
(new Foo().outer: string); // Error: number ~> string
(Foo.outer: number);
(Foo.outer: string); // Error: number ~> string

/**
 * Field initializers should be able to refer to the class type in their type
 * annotations.
 */
(new Foo().selfTyped: Foo);
(new Foo().selfTyped: number); // Error: Foo ~> number
(Foo.selfTyped: Foo);
(Foo.selfTyped: number); // Error: Foo ~> number

(new Foo().selfTypedInit: Foo);
(new Foo().selfTypedInit: number); // Error: Foo ~> number
(Foo.selfTypedInit: Foo);
(Foo.selfTypedInit: number); // Error: Foo ~> number

=====================================output=====================================
// @flow

var someVar = 42;

class Foo {
  outer = someVar;
  selfTyped: Foo;
  selfTypedInit = new Foo();

  static outer = someVar;
  static selfTyped: Foo;
  static selfTypedInit = new Foo();

  constructor() {
    var someVar = "asdf";
  }
}

/**
 * Field initializers execute in a scope immediately under the scope outside the
 * class definition.
 */
(new Foo().outer: number);
(new Foo().outer: string); // Error: number ~> string
(Foo.outer: number);
(Foo.outer: string); // Error: number ~> string

/**
 * Field initializers should be able to refer to the class type in their type
 * annotations.
 */
(new Foo().selfTyped: Foo);
(new Foo().selfTyped: number); // Error: Foo ~> number
(Foo.selfTyped: Foo);
(Foo.selfTyped: number); // Error: Foo ~> number

(new Foo().selfTypedInit: Foo);
(new Foo().selfTypedInit: number); // Error: Foo ~> number
(Foo.selfTypedInit: Foo);
(Foo.selfTypedInit: number); // Error: Foo ~> number

================================================================================
`;
