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 "/*" + comment.value + "*/";
const isInsideFlowComment =
options.originalText.substr(util.locEnd(comment) - 3, 3) === "*-/";
return "/*" + comment.value + (isInsideFlowComment ? "*-/" : "*/");
}
case "CommentLine":
case "Line":

View File

@ -445,15 +445,10 @@ function genericPrintNoParens(path, options, print, args) {
return concat(parts);
case "Identifier": {
const parentNode = path.getParentNode();
const isFunctionDeclarationIdentifier =
parentNode.type === "DeclareFunction" && parentNode.id === n;
return concat([
n.name,
printOptionalToken(path),
n.typeAnnotation && !isFunctionDeclarationIdentifier ? ": " : "",
path.call(print, "typeAnnotation")
printTypeAnnotation(path, options, print)
]);
}
case "SpreadElement":
@ -468,8 +463,7 @@ function genericPrintNoParens(path, options, print, args) {
return concat([
"...",
path.call(print, "argument"),
n.typeAnnotation ? ": " : "",
path.call(print, "typeAnnotation")
printTypeAnnotation(path, options, print)
]);
case "FunctionDeclaration":
case "FunctionExpression":
@ -500,7 +494,7 @@ function genericPrintNoParens(path, options, print, args) {
(args.expandLastArg || args.expandFirstArg),
/* printTypeParams */ true
),
printReturnType(path, print)
printReturnType(path, print, options)
])
)
);
@ -773,7 +767,7 @@ function genericPrintNoParens(path, options, print, args) {
if (
!hasContent &&
!hasDirectives &&
!n.comments &&
!hasDanglingComments(n) &&
(parent.type === "ArrowFunctionExpression" ||
parent.type === "FunctionExpression" ||
parent.type === "FunctionDeclaration" ||
@ -1042,8 +1036,7 @@ function genericPrintNoParens(path, options, print, args) {
),
concat([options.bracketSpacing ? line : softline, rightBrace]),
printOptionalToken(path),
n.typeAnnotation ? ": " : "",
path.call(print, "typeAnnotation")
printTypeAnnotation(path, options, print)
]);
}
@ -1173,11 +1166,10 @@ function genericPrintNoParens(path, options, print, args) {
);
}
parts.push(printOptionalToken(path));
if (n.typeAnnotation) {
parts.push(": ", path.call(print, "typeAnnotation"));
}
parts.push(
printOptionalToken(path),
printTypeAnnotation(path, options, print)
);
return concat(parts);
case "SequenceExpression": {
@ -1940,9 +1932,7 @@ function genericPrintNoParens(path, options, print, args) {
} else {
parts.push(printPropertyKey(path, options, print));
}
if (n.typeAnnotation) {
parts.push(": ", path.call(print, "typeAnnotation"));
}
parts.push(printTypeAnnotation(path, options, print));
if (n.value) {
parts.push(
" =",
@ -3010,7 +3000,7 @@ function printMethod(path, options, print) {
group(
concat([
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) {
const fun = path.getValue();
if (fun.typeParameters) {
@ -3396,7 +3406,7 @@ function printFunctionDeclaration(path, print, options) {
group(
concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
printReturnType(path, print, options)
])
),
n.body ? " " : "",
@ -3437,7 +3447,7 @@ function printObjectMethod(path, options, print) {
group(
concat([
printFunctionParams(path, print, options),
printReturnType(path, print)
printReturnType(path, print, options)
])
),
" ",
@ -3447,9 +3457,18 @@ function printObjectMethod(path, options, print) {
return concat(parts);
}
function printReturnType(path, print) {
function printReturnType(path, print, options) {
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
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) {
if (node.expressions) {
return node.expressions[0];

View File

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

View File

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

View File

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

View File

@ -2,39 +2,55 @@
exports[`arrow.js 1`] = `
// Error
const beep = (data/*: Object*/) => {}
const beep = (data/*: Object */) => {}
// 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> */ => {}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Error
const beep = (data: Object) => {};
const beep = (data /*: Object */) => {};
// 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 */) => {};
const run = (cmd /*: string */) /*: Promise<void> */ => {};
`;
exports[`arrow.js 2`] = `
// Error
const beep = (data/*: Object*/) => {}
exports[`class.js 1`] = `
class A {
x /*: string */;
// OK
const beep = (data/*: Object*/, secondData/*: Object*/) => {}
const run = (cmd /*: string */) /*: Promise<void> */ => {}
method(a /*: T */, b /*: T */) /*: T */ {}
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Error
const beep = (data /*: Object*/) => {};
class A {
x /*: string */;
// OK
const beep = (data /*: Object*/, secondData /*: Object*/) => {};
method(a /*: T */, b /*: T */) /*: T */ {}
}
const run = (cmd /*: string */) /*: Promise<void> */ => {};
`;
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";
`;
@ -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

@ -1,7 +1,9 @@
// Error
const beep = (data/*: Object*/) => {}
const beep = (data/*: Object */) => {}
// 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> */ => {}

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"]);
// FIXME arrow.js flow != babylon output
run_spec(__dirname, ["babylon"]);
run_spec(__dirname, ["flow", "babylon"]);

View File

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