From b3828eaee2f54fc7566bdc70a1d378081b8c77bb Mon Sep 17 00:00:00 2001 From: Joseph Frazier <1212jtraceur@gmail.com> Date: Thu, 11 May 2017 11:04:54 -0400 Subject: [PATCH] (Flow) Preserve getter/setter info on ObjectTypeProperty (#1585) * (Flow) Preserve getter/setter info on ObjectTypeProperty Before: `type T = { get method(): void }` -> `type T = { method: () => void };` Demo: https://prettier.github.io/prettier/#%7B%22content%22%3A%22type%20T%20%3D%20%7B%20get%20method()%3A%20void%20%7D%22%2C%22options%22%3A%7B%22printWidth%22%3A80%2C%22tabWidth%22%3A2%2C%22singleQuote%22%3Afalse%2C%22trailingComma%22%3A%22none%22%2C%22bracketSpacing%22%3Atrue%2C%22jsxBracketSameLine%22%3Afalse%2C%22parser%22%3A%22flow%22%2C%22semi%22%3Atrue%2C%22useTabs%22%3Afalse%2C%22doc%22%3Afalse%7D%7D --- After: `type T = { get method(): void }` -> `type T = { get method(): void };` Demo: `echo 'type T = { get method(): void }' | prettier --stdin --parser flow` Demo: `echo 'type T = { get method(): void }' | prettier --stdin --parser flow --debug-check` --- This passes `AST_COMPARE=1 npm test -- tests/flow/getters_and_setters_* tests/flow/objectTypeProperty/` and fixes https://github.com/prettier/prettier/issues/1557 * (Flow) Make getter/setter parsing more robust Addresses https://github.com/prettier/prettier/pull/1585#discussion_r116008715 --- src/printer.js | 6 ++- .../__snapshots__/jsfmt.spec.js.snap | 8 ++-- .../__snapshots__/jsfmt.spec.js.snap | 48 +++++++++---------- .../__snapshots__/jsfmt.spec.js.snap | 10 +++- .../objectTypeProperty/objectTypeProperty.js | 3 ++ 5 files changed, 43 insertions(+), 32 deletions(-) diff --git a/src/printer.js b/src/printer.js index 846d8b49..126b70dc 100644 --- a/src/printer.js +++ b/src/printer.js @@ -1989,10 +1989,11 @@ function genericPrintNoParens(path, options, print, args) { return concat([ n.static ? "static " : "", + isGetterOrSetter ? n.kind + " " : "", variance || "", path.call(print, "key"), n.optional ? "?" : "", - (isFunctionNotation && !isGetterOrSetter) ? "" : ": ", + isFunctionNotation || isGetterOrSetter ? "" : ": ", path.call(print, "value") ]); case "QualifiedTypeIdentifier": @@ -4125,11 +4126,12 @@ function isMemberExpressionChain(node) { // type T = { method: () => void }; // type T = { method(): void }; function isObjectTypePropertyAFunction(node) { + const isGetterOrSetter = node.kind === 'get' || node.kind === 'set'; return ( node.type === "ObjectTypeProperty" && node.value.type === "FunctionTypeAnnotation" && !node.static && - util.locStart(node.key) !== util.locStart(node.value) + util.locStart(node.key) !== util.locStart(node.value) && !isGetterOrSetter ); } diff --git a/tests/flow/getters_and_setters_disabled/__snapshots__/jsfmt.spec.js.snap b/tests/flow/getters_and_setters_disabled/__snapshots__/jsfmt.spec.js.snap index 727a9576..a13a4e03 100644 --- a/tests/flow/getters_and_setters_disabled/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/getters_and_setters_disabled/__snapshots__/jsfmt.spec.js.snap @@ -52,14 +52,14 @@ var f = { }; type T = { - a: () => number, - b: (x: number) => void, + get a(): number, + set b(x: number): void, c: 10 }; declare class Foo { - a: () => number, - b: (x: number) => void, + get a(): number, + set b(x: number): void, c: 10 } diff --git a/tests/flow/getters_and_setters_enabled/__snapshots__/jsfmt.spec.js.snap b/tests/flow/getters_and_setters_enabled/__snapshots__/jsfmt.spec.js.snap index 217081de..ca123de3 100644 --- a/tests/flow/getters_and_setters_enabled/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/getters_and_setters_enabled/__snapshots__/jsfmt.spec.js.snap @@ -197,28 +197,28 @@ foo.propOverriddenWithSetter = 123; // Error number ~> string var z: number = 123; declare class Foo { - goodGetterWithAnnotation: () => number, - goodSetterWithAnnotation: (x: number) => void, + get goodGetterWithAnnotation(): number, + set goodSetterWithAnnotation(x: number): void, - propWithMatchingGetterAndSetter: () => number, - propWithMatchingGetterAndSetter: (x: number) => void, + get propWithMatchingGetterAndSetter(): number, + set propWithMatchingGetterAndSetter(x: number): void, // The getter and setter need not have the same type - no error - propWithSubtypingGetterAndSetter: () => ?number, - propWithSubtypingGetterAndSetter: (x: number) => void, + get propWithSubtypingGetterAndSetter(): ?number, + set propWithSubtypingGetterAndSetter(x: number): void, // The getter and setter need not have the same type - no error - propWithSubtypingGetterAndSetterReordered: (x: number) => void, - propWithSubtypingGetterAndSetterReordered: () => ?number, + set propWithSubtypingGetterAndSetterReordered(x: number): void, + get propWithSubtypingGetterAndSetterReordered(): ?number, - propWithMismatchingGetterAndSetter: () => number, - propWithMismatchingGetterAndSetter: (x: string) => void, // doesn't match getter (OK) + get propWithMismatchingGetterAndSetter(): number, + set propWithMismatchingGetterAndSetter(x: string): void, // doesn't match getter (OK) propOverriddenWithGetter: number, - propOverriddenWithGetter: () => string, + get propOverriddenWithGetter(): string, propOverriddenWithSetter: number, - propOverriddenWithSetter: (x: string) => void + set propOverriddenWithSetter(x: string): void } var foo = new Foo(); @@ -455,24 +455,24 @@ class B extends A {} class C extends A {} type T = { - goodGetterWithAnnotation: () => number, - goodSetterWithAnnotation: (x: number) => void, + get goodGetterWithAnnotation(): number, + set goodSetterWithAnnotation(x: number): void, - propWithMatchingGetterAndSetter: () => number, - propWithMatchingGetterAndSetter: (x: number) => void, + get propWithMatchingGetterAndSetter(): number, + set propWithMatchingGetterAndSetter(x: number): void, // The getter and setter need not have the same type - propWithSubtypingGetterAndSetter: () => ?number, // OK - propWithSubtypingGetterAndSetter: (x: number) => void, + get propWithSubtypingGetterAndSetter(): ?number, // OK + set propWithSubtypingGetterAndSetter(x: number): void, - propWithSubtypingGetterAndSetterReordered: (x: number) => void, // OK - propWithSubtypingGetterAndSetterReordered: () => ?number, + set propWithSubtypingGetterAndSetterReordered(x: number): void, // OK + get propWithSubtypingGetterAndSetterReordered(): ?number, - exampleOfOrderOfGetterAndSetter: () => A, - exampleOfOrderOfGetterAndSetter: (x: B) => void, + get exampleOfOrderOfGetterAndSetter(): A, + set exampleOfOrderOfGetterAndSetter(x: B): void, - exampleOfOrderOfGetterAndSetterReordered: (x: B) => void, - exampleOfOrderOfGetterAndSetterReordered: () => A + set exampleOfOrderOfGetterAndSetterReordered(x: B): void, + get exampleOfOrderOfGetterAndSetterReordered(): A }; function test(obj: T) { diff --git a/tests/flow/objectTypeProperty/__snapshots__/jsfmt.spec.js.snap b/tests/flow/objectTypeProperty/__snapshots__/jsfmt.spec.js.snap index fdbdf839..9de1f27b 100644 --- a/tests/flow/objectTypeProperty/__snapshots__/jsfmt.spec.js.snap +++ b/tests/flow/objectTypeProperty/__snapshots__/jsfmt.spec.js.snap @@ -15,6 +15,9 @@ let x: { x?: number } type T = { get goodGetterWithAnnotation(): number, set goodSetterWithAnnotation(x: number): void, + + get getterWithMultipleSpacesPrecedingName(): number, + set setterWithMultipleSpacesPrecedingName(x: number): void, } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ /* @flow */ @@ -29,8 +32,11 @@ declare class Foo { let x: { x?: number }; type T = { - goodGetterWithAnnotation: () => number, - goodSetterWithAnnotation: (x: number) => void + get goodGetterWithAnnotation(): number, + set goodSetterWithAnnotation(x: number): void, + + get getterWithMultipleSpacesPrecedingName(): number, + set setterWithMultipleSpacesPrecedingName(x: number): void }; `; diff --git a/tests/flow/objectTypeProperty/objectTypeProperty.js b/tests/flow/objectTypeProperty/objectTypeProperty.js index 411d25e5..1e91cfc8 100644 --- a/tests/flow/objectTypeProperty/objectTypeProperty.js +++ b/tests/flow/objectTypeProperty/objectTypeProperty.js @@ -12,4 +12,7 @@ let x: { x?: number } type T = { get goodGetterWithAnnotation(): number, set goodSetterWithAnnotation(x: number): void, + + get getterWithMultipleSpacesPrecedingName(): number, + set setterWithMultipleSpacesPrecedingName(x: number): void, }