Print flow type annotation comments as comments (#3449)

master
Lucas Duailibe 2017-12-15 05:11:48 -02:00 committed by GitHub
parent 57e821a28c
commit 4d23e9081d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 112 additions and 103 deletions

View File

@ -933,7 +933,10 @@ function printComment(commentPath, options) {
return printJsDocComment(comment); return printJsDocComment(comment);
} }
return "/*" + comment.value + "*/"; const isInsideFlowComment =
options.originalText.substr(util.locEnd(comment) - 3, 3) === "*-/";
return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/");
} }
case "CommentLine": case "CommentLine":
case "Line": case "Line":

View File

@ -445,15 +445,10 @@ function genericPrintNoParens(path, options, print, args) {
return concat(parts); return concat(parts);
case "Identifier": { case "Identifier": {
const parentNode = path.getParentNode();
const isFunctionDeclarationIdentifier =
parentNode.type === "DeclareFunction" && parentNode.id === n;
return concat([ return concat([
n.name, n.name,
printOptionalToken(path), printOptionalToken(path),
n.typeAnnotation && !isFunctionDeclarationIdentifier ? ": " : "", printTypeAnnotation(path, options, print)
path.call(print, "typeAnnotation")
]); ]);
} }
case "SpreadElement": case "SpreadElement":
@ -468,8 +463,7 @@ function genericPrintNoParens(path, options, print, args) {
return concat([ return concat([
"...", "...",
path.call(print, "argument"), path.call(print, "argument"),
n.typeAnnotation ? ": " : "", printTypeAnnotation(path, options, print)
path.call(print, "typeAnnotation")
]); ]);
case "FunctionDeclaration": case "FunctionDeclaration":
case "FunctionExpression": case "FunctionExpression":
@ -500,7 +494,7 @@ function genericPrintNoParens(path, options, print, args) {
(args.expandLastArg || args.expandFirstArg), (args.expandLastArg || args.expandFirstArg),
/* printTypeParams */ true /* printTypeParams */ true
), ),
printReturnType(path, print) printReturnType(path, print, options)
]) ])
) )
); );
@ -773,7 +767,7 @@ function genericPrintNoParens(path, options, print, args) {
if ( if (
!hasContent && !hasContent &&
!hasDirectives && !hasDirectives &&
!n.comments && !hasDanglingComments(n) &&
(parent.type === "ArrowFunctionExpression" || (parent.type === "ArrowFunctionExpression" ||
parent.type === "FunctionExpression" || parent.type === "FunctionExpression" ||
parent.type === "FunctionDeclaration" || parent.type === "FunctionDeclaration" ||
@ -1042,8 +1036,7 @@ function genericPrintNoParens(path, options, print, args) {
), ),
concat([options.bracketSpacing ? line : softline, rightBrace]), concat([options.bracketSpacing ? line : softline, rightBrace]),
printOptionalToken(path), printOptionalToken(path),
n.typeAnnotation ? ": " : "", printTypeAnnotation(path, options, print)
path.call(print, "typeAnnotation")
]); ]);
} }
@ -1173,11 +1166,10 @@ function genericPrintNoParens(path, options, print, args) {
); );
} }
parts.push(printOptionalToken(path)); parts.push(
printOptionalToken(path),
if (n.typeAnnotation) { printTypeAnnotation(path, options, print)
parts.push(": ", path.call(print, "typeAnnotation")); );
}
return concat(parts); return concat(parts);
case "SequenceExpression": { case "SequenceExpression": {
@ -1940,9 +1932,7 @@ function genericPrintNoParens(path, options, print, args) {
} else { } else {
parts.push(printPropertyKey(path, options, print)); parts.push(printPropertyKey(path, options, print));
} }
if (n.typeAnnotation) { parts.push(printTypeAnnotation(path, options, print));
parts.push(": ", path.call(print, "typeAnnotation"));
}
if (n.value) { if (n.value) {
parts.push( parts.push(
" =", " =",
@ -3010,7 +3000,7 @@ function printMethod(path, options, print) {
group( group(
concat([ concat([
printFunctionParams(valuePath, print, options), printFunctionParams(valuePath, print, options),
printReturnType(valuePath, print) printReturnType(valuePath, print, options)
]) ])
) )
], ],
@ -3204,6 +3194,26 @@ function printArgumentsList(path, options, print) {
); );
} }
function printTypeAnnotation(path, options, print) {
const node = path.getValue();
if (!node.typeAnnotation) {
return "";
}
const parentNode = path.getParentNode();
const isFunctionDeclarationIdentifier =
parentNode.type === "DeclareFunction" && parentNode.id === node;
if (isFlowAnnotationComment(options.originalText, node.typeAnnotation)) {
return concat([" /*: ", path.call(print, "typeAnnotation"), " */"]);
}
return concat([
isFunctionDeclarationIdentifier ? "" : ": ",
path.call(print, "typeAnnotation")
]);
}
function printFunctionTypeParameters(path, options, print) { function printFunctionTypeParameters(path, options, print) {
const fun = path.getValue(); const fun = path.getValue();
if (fun.typeParameters) { if (fun.typeParameters) {
@ -3396,7 +3406,7 @@ function printFunctionDeclaration(path, print, options) {
group( group(
concat([ concat([
printFunctionParams(path, print, options), printFunctionParams(path, print, options),
printReturnType(path, print) printReturnType(path, print, options)
]) ])
), ),
n.body ? " " : "", n.body ? " " : "",
@ -3437,7 +3447,7 @@ function printObjectMethod(path, options, print) {
group( group(
concat([ concat([
printFunctionParams(path, print, options), printFunctionParams(path, print, options),
printReturnType(path, print) printReturnType(path, print, options)
]) ])
), ),
" ", " ",
@ -3447,9 +3457,18 @@ function printObjectMethod(path, options, print) {
return concat(parts); return concat(parts);
} }
function printReturnType(path, print) { function printReturnType(path, print, options) {
const n = path.getValue(); const n = path.getValue();
const parts = [path.call(print, "returnType")]; const returnType = path.call(print, "returnType");
if (
n.returnType &&
isFlowAnnotationComment(options.originalText, n.returnType)
) {
return concat([" /*: ", returnType, " */"]);
}
const parts = [returnType];
// prepend colon to TypeScript type annotation // prepend colon to TypeScript type annotation
if (n.returnType && n.returnType.typeAnnotation) { if (n.returnType && n.returnType.typeAnnotation) {
@ -4770,6 +4789,12 @@ function hasNakedLeftSide(node) {
); );
} }
function isFlowAnnotationComment(text, typeAnnotation) {
const start = util.locStart(typeAnnotation);
const end = util.skipWhitespace(text, util.locEnd(typeAnnotation));
return text.substr(start, 2) === "/*" && text.substr(end, 2) === "*/";
}
function getLeftSide(node) { function getLeftSide(node) {
if (node.expressions) { if (node.expressions) {
return node.expressions[0]; return node.expressions[0];

View File

@ -339,31 +339,24 @@ KEYPAD_NUMBERS.map((
function f /* f */() {} function f /* f */() {}
function f(/* args */) {} function f(/* args */) {}
function f() /* returns */ { function f() /* returns */ {}
} function f /* f */(/* args */) /* returns */ {}
function f /* f */(/* args */) /* returns */ {
}
function f /* f */(/* a */ a) {} function f /* f */(/* a */ a) {}
function f /* f */(a /* a */) {} function f /* f */(a /* a */) {}
function f /* f */(/* a */ a) /* returns */ { function f /* f */(/* a */ a) /* returns */ {}
}
const obj = { const obj = {
f1 /* f */() {}, f1 /* f */() {},
f2(/* args */) {}, f2(/* args */) {},
f3() /* returns */ { f3() /* returns */ {},
}, f4 /* f */(/* args */) /* returns */ {}
f4 /* f */(/* args */) /* returns */ {
}
}; };
(function f /* f */() {})(); (function f /* f */() {})();
(function f(/* args */) {})(); (function f(/* args */) {})();
(function f() /* returns */ { (function f() /* returns */ {})();
})(); (function f /* f */(/* args */) /* returns */ {})();
(function f /* f */(/* args */) /* returns */ {
})();
class C { class C {
f /* f */() {} f /* f */() {}
@ -372,12 +365,10 @@ class C {
f(/* args */) {} f(/* args */) {}
} }
class C { class C {
f() /* returns */ { f() /* returns */ {}
}
} }
class C { class C {
f /* f */(/* args */) /* returns */ { f /* f */(/* args */) /* returns */ {}
}
} }
`; `;
@ -1133,8 +1124,7 @@ class Foo {
lol2 /*string*/, lol2 /*string*/,
lol3 /*string*/, lol3 /*string*/,
lol4 /*string*/ lol4 /*string*/
) /*string*/ { ) /*string*/ {}
}
// prettier-ignore // prettier-ignore
c(lol /*string*/ c(lol /*string*/

View File

@ -61,8 +61,7 @@ const obj = {
class Foo { class Foo {
f(/* ... */) {} f(/* ... */) {}
f() /* ... */ { f() /* ... */ {}
}
f = (/* ... */) => {}; f = (/* ... */) => {};
static f(/* ... */) {} static f(/* ... */) {}
static f = (/* ... */) => {}; static f = (/* ... */) => {};

View File

@ -38,7 +38,7 @@ type Children = Array<Child>;
class Thunk {} class Thunk {}
class VirtualNode { class VirtualNode {
children: Child | Children; children: Child | Children;
constructor(type, children: Children) { constructor(type, children /*: Children */) {
this.children = children.length === 1 ? children[0] : children; this.children = children.length === 1 ? children[0] : children;
} }
} }

View File

@ -7,24 +7,7 @@ const beep = (data/*: Object*/) => {}
// OK // OK
const beep = (data/*: Object */, secondData/*: Object */) => {} const beep = (data/*: Object */, secondData/*: Object */) => {}
const run = (cmd /*: string */) /*: Promise<void> */ => {} const beep = (data/*: /* this is an object *-/ Object */) => {};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Error
const beep = (data: Object) => {};
// OK
const beep = (data: Object, secondData: Object) => {};
const run = (cmd: string): Promise<void> => {};
`;
exports[`arrow.js 2`] = `
// Error
const beep = (data/*: Object*/) => {}
// OK
const beep = (data/*: Object*/, secondData/*: Object*/) => {}
const run = (cmd /*: string */) /*: Promise<void> */ => {} const run = (cmd /*: string */) /*: Promise<void> */ => {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -34,10 +17,43 @@ const beep = (data /*: Object*/) => {};
// OK // OK
const beep = (data /*: Object */, secondData /*: Object */) => {}; const beep = (data /*: Object */, secondData /*: Object */) => {};
const beep = (data /*: /* this is an object *-/ Object */) => {};
const run = (cmd /*: string */) /*: Promise<void> */ => {}; const run = (cmd /*: string */) /*: Promise<void> */ => {};
`; `;
exports[`class.js 1`] = `
class A {
x /*: string */;
method(a /*: T */, b /*: T */) /*: T */ {}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
class A {
x /*: string */;
method(a /*: T */, b /*: T */) /*: T */ {}
}
`;
exports[`functions.js 1`] = `
function foo<T>(bar /*: T[] */, baz /*: T */) /*: S */ {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function foo<T>(bar /*: T[] */, baz /*: T */) /*: S */ {}
`;
exports[`let.js 1`] = `
let foo /*: Groups<T> */;
let foo /*: string */ = 'a';
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let foo /*: Groups<T> */;
let foo /*: string */ = "a";
`;
exports[`object_type_annotation.js 1`] = ` exports[`object_type_annotation.js 1`] = `
type Props = // (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!! type Props = // (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
{ {
@ -69,35 +85,3 @@ type Props = {
}; };
`; `;
exports[`object_type_annotation.js 2`] = `
type Props = // (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
{
isPlaying: boolean,
};
type Props = { // (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
isPlaying: boolean
};
type Props = {
// (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
isPlaying: boolean
};
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
type Props = {
isPlaying: boolean
};
type Props = {
// (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
isPlaying: boolean
};
type Props = {
// (DispatchProps & StateProps); WHY DON'T YOU WORK FLOW!!!!!!!!!
isPlaying: boolean
};
`;

View File

@ -4,4 +4,6 @@ const beep = (data/*: Object*/) => {}
// OK // OK
const beep = (data/*: Object */, secondData/*: Object */) => {} const beep = (data/*: Object */, secondData/*: Object */) => {}
const beep = (data/*: /* this is an object *-/ Object */) => {};
const run = (cmd /*: string */) /*: Promise<void> */ => {} const run = (cmd /*: string */) /*: Promise<void> */ => {}

View File

@ -0,0 +1,5 @@
class A {
x /*: string */;
method(a /*: T */, b /*: T */) /*: T */ {}
}

View File

@ -0,0 +1 @@
function foo<T>(bar /*: T[] */, baz /*: T */) /*: S */ {}

View File

@ -1,3 +1 @@
run_spec(__dirname, ["flow"]); run_spec(__dirname, ["flow", "babylon"]);
// FIXME arrow.js flow != babylon output
run_spec(__dirname, ["babylon"]);

View File

@ -0,0 +1,2 @@
let foo /*: Groups<T> */;
let foo /*: string */ = 'a';