Move flow node to flow.js (#10449)
This commit is contained in:
1 parent
d3b777dd7d
commit
40cd8c9d7e
3 files changed
+278
-259
No files matched your search
@@ -1,7 +1,21 @@
|
||||
"use strict";
|
||||
|
||||
/** @typedef {import("../../document").Doc} Doc */
|
||||
|
||||
const assert = require("assert");
|
||||
const { getParentExportDeclaration } = require("../utils");
|
||||
const { printDanglingComments } = require("../../main/comments");
|
||||
const { printString, printNumber } = require("../../common/util");
|
||||
const {
|
||||
builders: { hardline, softline, group, indent },
|
||||
} = require("../../document");
|
||||
const {
|
||||
getParentExportDeclaration,
|
||||
isFunctionNotation,
|
||||
isGetterOrSetter,
|
||||
rawText,
|
||||
shouldPrintComma,
|
||||
} = require("../utils");
|
||||
const { locStart, locEnd } = require("../loc");
|
||||
const { printClass } = require("./class");
|
||||
const {
|
||||
printOpaqueType,
|
||||
@@ -21,10 +35,20 @@ const {
|
||||
printExportDeclaration,
|
||||
printExportAllDeclaration,
|
||||
} = require("./module");
|
||||
const { printArrayItems } = require("./array");
|
||||
const { printObject } = require("./object");
|
||||
const { printPropertyKey } = require("./property");
|
||||
const {
|
||||
printOptionalToken,
|
||||
printTypeAnnotation,
|
||||
printRestSpread,
|
||||
} = require("./misc");
|
||||
|
||||
function printFlow(path, options, print) {
|
||||
const node = path.getValue();
|
||||
const semi = options.semi ? ";" : "";
|
||||
/** @type{Doc[]} */
|
||||
const parts = [];
|
||||
switch (node.type) {
|
||||
case "DeclareClass":
|
||||
return printFlowDeclaration(path, printClass(path, options, print));
|
||||
@@ -96,6 +120,249 @@ function printFlow(path, options, print) {
|
||||
return printTypeParameter(path, options, print);
|
||||
case "TypeofTypeAnnotation":
|
||||
return ["typeof ", print("argument")];
|
||||
case "ExistsTypeAnnotation":
|
||||
return "*";
|
||||
case "EmptyTypeAnnotation":
|
||||
return "empty";
|
||||
case "MixedTypeAnnotation":
|
||||
return "mixed";
|
||||
case "ArrayTypeAnnotation":
|
||||
return [print("elementType"), "[]"];
|
||||
case "BooleanLiteralTypeAnnotation":
|
||||
return String(node.value);
|
||||
case "EnumDeclaration":
|
||||
return ["enum ", print("id"), " ", print("body")];
|
||||
case "EnumBooleanBody":
|
||||
case "EnumNumberBody":
|
||||
case "EnumStringBody":
|
||||
case "EnumSymbolBody": {
|
||||
if (node.type === "EnumSymbolBody" || node.explicitType) {
|
||||
let type = null;
|
||||
switch (node.type) {
|
||||
case "EnumBooleanBody":
|
||||
type = "boolean";
|
||||
break;
|
||||
case "EnumNumberBody":
|
||||
type = "number";
|
||||
break;
|
||||
case "EnumStringBody":
|
||||
type = "string";
|
||||
break;
|
||||
case "EnumSymbolBody":
|
||||
type = "symbol";
|
||||
break;
|
||||
}
|
||||
parts.push("of ", type, " ");
|
||||
}
|
||||
if (node.members.length === 0 && !node.hasUnknownMembers) {
|
||||
parts.push(
|
||||
group(["{", printDanglingComments(path, options), softline, "}"])
|
||||
);
|
||||
} else {
|
||||
const members =
|
||||
node.members.length > 0
|
||||
? [
|
||||
hardline,
|
||||
printArrayItems(path, options, "members", print),
|
||||
node.hasUnknownMembers || shouldPrintComma(options) ? "," : "",
|
||||
]
|
||||
: [];
|
||||
|
||||
parts.push(
|
||||
group([
|
||||
"{",
|
||||
indent([
|
||||
...members,
|
||||
...(node.hasUnknownMembers ? [hardline, "..."] : []),
|
||||
]),
|
||||
printDanglingComments(path, options, /* sameIndent */ true),
|
||||
hardline,
|
||||
"}",
|
||||
])
|
||||
);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
case "EnumBooleanMember":
|
||||
case "EnumNumberMember":
|
||||
case "EnumStringMember":
|
||||
return [
|
||||
print("id"),
|
||||
" = ",
|
||||
typeof node.init === "object" ? print("init") : String(node.init),
|
||||
];
|
||||
case "EnumDefaultedMember":
|
||||
return print("id");
|
||||
case "FunctionTypeParam": {
|
||||
const name = node.name
|
||||
? print("name")
|
||||
: path.getParentNode().this === node
|
||||
? "this"
|
||||
: "";
|
||||
return [
|
||||
name,
|
||||
printOptionalToken(path),
|
||||
name ? ": " : "",
|
||||
print("typeAnnotation"),
|
||||
];
|
||||
}
|
||||
|
||||
case "InterfaceDeclaration":
|
||||
case "InterfaceTypeAnnotation":
|
||||
return printInterface(path, options, print);
|
||||
case "ClassImplements":
|
||||
case "InterfaceExtends":
|
||||
return [print("id"), print("typeParameters")];
|
||||
case "NullableTypeAnnotation":
|
||||
return ["?", print("typeAnnotation")];
|
||||
case "Variance": {
|
||||
const { kind } = node;
|
||||
assert.ok(kind === "plus" || kind === "minus");
|
||||
return kind === "plus" ? "+" : "-";
|
||||
}
|
||||
case "ObjectTypeCallProperty":
|
||||
if (node.static) {
|
||||
parts.push("static ");
|
||||
}
|
||||
|
||||
parts.push(print("value"));
|
||||
|
||||
return parts;
|
||||
case "ObjectTypeIndexer": {
|
||||
return [
|
||||
node.variance ? print("variance") : "",
|
||||
"[",
|
||||
print("id"),
|
||||
node.id ? ": " : "",
|
||||
print("key"),
|
||||
"]: ",
|
||||
print("value"),
|
||||
];
|
||||
}
|
||||
case "ObjectTypeProperty": {
|
||||
let modifier = "";
|
||||
|
||||
if (node.proto) {
|
||||
modifier = "proto ";
|
||||
} else if (node.static) {
|
||||
modifier = "static ";
|
||||
}
|
||||
|
||||
return [
|
||||
modifier,
|
||||
isGetterOrSetter(node) ? node.kind + " " : "",
|
||||
node.variance ? print("variance") : "",
|
||||
printPropertyKey(path, options, print),
|
||||
printOptionalToken(path),
|
||||
isFunctionNotation(node) ? "" : ": ",
|
||||
print("value"),
|
||||
];
|
||||
}
|
||||
case "ObjectTypeAnnotation":
|
||||
return printObject(path, options, print);
|
||||
case "ObjectTypeInternalSlot":
|
||||
return [
|
||||
node.static ? "static " : "",
|
||||
"[[",
|
||||
print("id"),
|
||||
"]]",
|
||||
printOptionalToken(path),
|
||||
node.method ? "" : ": ",
|
||||
print("value"),
|
||||
];
|
||||
// Same as `RestElement`
|
||||
case "ObjectTypeSpreadProperty":
|
||||
return printRestSpread(path, options, print);
|
||||
case "QualifiedTypeIdentifier":
|
||||
return [print("qualification"), ".", print("id")];
|
||||
case "StringLiteralTypeAnnotation":
|
||||
return printString(rawText(node), options);
|
||||
case "NumberLiteralTypeAnnotation":
|
||||
assert.strictEqual(typeof node.value, "number");
|
||||
// fall through
|
||||
case "BigIntLiteralTypeAnnotation":
|
||||
if (node.extra) {
|
||||
return printNumber(node.extra.raw);
|
||||
}
|
||||
return printNumber(node.raw);
|
||||
case "TypeCastExpression": {
|
||||
return [
|
||||
"(",
|
||||
print("expression"),
|
||||
printTypeAnnotation(path, options, print),
|
||||
")",
|
||||
];
|
||||
}
|
||||
|
||||
case "TypeParameterDeclaration":
|
||||
case "TypeParameterInstantiation": {
|
||||
const printed = printTypeParameters(path, options, print, "params");
|
||||
|
||||
if (options.parser === "flow") {
|
||||
const start = locStart(node);
|
||||
const end = locEnd(node);
|
||||
const commentStartIndex = options.originalText.lastIndexOf("/*", start);
|
||||
const commentEndIndex = options.originalText.indexOf("*/", end);
|
||||
if (commentStartIndex !== -1 && commentEndIndex !== -1) {
|
||||
const comment = options.originalText
|
||||
.slice(commentStartIndex + 2, commentEndIndex)
|
||||
.trim();
|
||||
if (
|
||||
comment.startsWith("::") &&
|
||||
!comment.includes("/*") &&
|
||||
!comment.includes("*/")
|
||||
) {
|
||||
return ["/*:: ", printed, " */"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return printed;
|
||||
}
|
||||
|
||||
case "InferredPredicate":
|
||||
return "%checks";
|
||||
// Unhandled types below. If encountered, nodes of these types should
|
||||
// be either left alone or desugared into AST types that are fully
|
||||
// supported by the pretty-printer.
|
||||
case "DeclaredPredicate":
|
||||
return ["%checks(", print("value"), ")"];
|
||||
case "AnyTypeAnnotation":
|
||||
return "any";
|
||||
case "BooleanTypeAnnotation":
|
||||
return "boolean";
|
||||
case "BigIntTypeAnnotation":
|
||||
return "bigint";
|
||||
case "NullLiteralTypeAnnotation":
|
||||
return "null";
|
||||
case "NumberTypeAnnotation":
|
||||
return "number";
|
||||
case "SymbolTypeAnnotation":
|
||||
return "symbol";
|
||||
case "StringTypeAnnotation":
|
||||
return "string";
|
||||
case "VoidTypeAnnotation":
|
||||
return "void";
|
||||
case "ThisTypeAnnotation":
|
||||
return "this";
|
||||
// These types are unprintable because they serve as abstract
|
||||
// supertypes for other (printable) types.
|
||||
case "Node":
|
||||
case "Printable":
|
||||
case "SourceLocation":
|
||||
case "Position":
|
||||
case "Statement":
|
||||
case "Function":
|
||||
case "Pattern":
|
||||
case "Expression":
|
||||
case "Declaration":
|
||||
case "Specifier":
|
||||
case "NamedSpecifier":
|
||||
case "Comment":
|
||||
case "MemberTypeAnnotation": // Flow
|
||||
case "Type":
|
||||
/* istanbul ignore next */
|
||||
throw new Error("unprintable type: " + JSON.stringify(node.type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -86,11 +86,16 @@ function adjustClause(node, clause, forceSpace) {
|
||||
return indent([line, clause]);
|
||||
}
|
||||
|
||||
function printRestSpread(path, options, print) {
|
||||
return ["...", print("argument"), printTypeAnnotation(path, options, print)];
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
printOptionalToken,
|
||||
printFunctionTypeParameters,
|
||||
printBindExpressionCallee,
|
||||
printTypeScriptModifiers,
|
||||
printTypeAnnotation,
|
||||
printRestSpread,
|
||||
adjustClause,
|
||||
};
|
||||
@@ -2,12 +2,9 @@
|
||||
|
||||
/** @typedef {import("../document").Doc} Doc */
|
||||
|
||||
/** @type {import("assert")} */
|
||||
const assert = require("assert");
|
||||
|
||||
// TODO(azz): anything that imports from main shouldn't be in a `language-*` dir.
|
||||
const { printDanglingComments } = require("../main/comments");
|
||||
const { hasNewline, printString, printNumber } = require("../common/util");
|
||||
const { hasNewline } = require("../common/util");
|
||||
const {
|
||||
builders: { join, line, hardline, softline, group, indent },
|
||||
utils: { replaceNewlinesWithLiterallines },
|
||||
@@ -23,15 +20,12 @@ const {
|
||||
hasFlowShorthandAnnotationComment,
|
||||
hasComment,
|
||||
CommentCheckFlags,
|
||||
isFunctionNotation,
|
||||
isGetterOrSetter,
|
||||
isTheOnlyJsxElementInMarkdown,
|
||||
isBlockComment,
|
||||
isLineComment,
|
||||
isNextLineEmpty,
|
||||
needsHardlineAfterDanglingComment,
|
||||
rawText,
|
||||
shouldPrintComma,
|
||||
hasIgnoreComment,
|
||||
isCallExpression,
|
||||
isMemberExpression,
|
||||
@@ -51,6 +45,7 @@ const {
|
||||
printBindExpressionCallee,
|
||||
printTypeAnnotation,
|
||||
adjustClause,
|
||||
printRestSpread,
|
||||
} = require("./print/misc");
|
||||
const {
|
||||
printImportDeclaration,
|
||||
@@ -60,15 +55,14 @@ const {
|
||||
} = require("./print/module");
|
||||
const { printTernary } = require("./print/ternary");
|
||||
const { printTemplateLiteral } = require("./print/template-literal");
|
||||
const { printArray, printArrayItems } = require("./print/array");
|
||||
const { printArray } = require("./print/array");
|
||||
const { printObject } = require("./print/object");
|
||||
const {
|
||||
printClass,
|
||||
printClassMethod,
|
||||
printClassProperty,
|
||||
} = require("./print/class");
|
||||
const { printTypeParameters } = require("./print/type-parameters");
|
||||
const { printPropertyKey, printProperty } = require("./print/property");
|
||||
const { printProperty } = require("./print/property");
|
||||
const {
|
||||
printFunctionDeclaration,
|
||||
printArrowFunctionExpression,
|
||||
@@ -77,7 +71,6 @@ const {
|
||||
printThrowStatement,
|
||||
} = require("./print/function");
|
||||
const { printCallExpression } = require("./print/call-expression");
|
||||
const { printInterface } = require("./print/interface");
|
||||
const {
|
||||
printVariableDeclarator,
|
||||
printAssignmentExpression,
|
||||
@@ -270,12 +263,7 @@ function printPathNoParens(path, options, print, args) {
|
||||
case "SpreadProperty":
|
||||
case "SpreadPropertyPattern":
|
||||
case "RestElement":
|
||||
case "ObjectTypeSpreadProperty":
|
||||
return [
|
||||
"...",
|
||||
print("argument"),
|
||||
printTypeAnnotation(path, options, print),
|
||||
];
|
||||
return printRestSpread(path, options, print);
|
||||
case "FunctionDeclaration":
|
||||
case "FunctionExpression": {
|
||||
let expandArg = false;
|
||||
@@ -355,20 +343,9 @@ function printPathNoParens(path, options, print, args) {
|
||||
case "OptionalCallExpression":
|
||||
case "CallExpression":
|
||||
return printCallExpression(path, options, print);
|
||||
case "ObjectTypeInternalSlot":
|
||||
return [
|
||||
node.static ? "static " : "",
|
||||
"[[",
|
||||
print("id"),
|
||||
"]]",
|
||||
printOptionalToken(path),
|
||||
node.method ? "" : ": ",
|
||||
print("value"),
|
||||
];
|
||||
|
||||
case "ObjectExpression":
|
||||
case "ObjectPattern":
|
||||
case "ObjectTypeAnnotation":
|
||||
case "RecordExpression":
|
||||
return printObject(path, options, print);
|
||||
// Babel 6
|
||||
@@ -755,236 +732,6 @@ function printPathNoParens(path, options, print, args) {
|
||||
return printTemplateLiteral(path, print, options);
|
||||
case "TaggedTemplateExpression":
|
||||
return [print("tag"), print("typeParameters"), print("quasi")];
|
||||
// These types are unprintable because they serve as abstract
|
||||
// supertypes for other (printable) types.
|
||||
case "Node":
|
||||
case "Printable":
|
||||
case "SourceLocation":
|
||||
case "Position":
|
||||
case "Statement":
|
||||
case "Function":
|
||||
case "Pattern":
|
||||
case "Expression":
|
||||
case "Declaration":
|
||||
case "Specifier":
|
||||
case "NamedSpecifier":
|
||||
case "Comment":
|
||||
case "MemberTypeAnnotation": // Flow
|
||||
case "Type":
|
||||
/* istanbul ignore next */
|
||||
throw new Error("unprintable type: " + JSON.stringify(node.type));
|
||||
case "ExistsTypeAnnotation":
|
||||
return "*";
|
||||
case "EmptyTypeAnnotation":
|
||||
return "empty";
|
||||
case "MixedTypeAnnotation":
|
||||
return "mixed";
|
||||
case "ArrayTypeAnnotation":
|
||||
return [print("elementType"), "[]"];
|
||||
case "BooleanLiteralTypeAnnotation":
|
||||
return String(node.value);
|
||||
|
||||
case "EnumDeclaration":
|
||||
return ["enum ", print("id"), " ", print("body")];
|
||||
case "EnumBooleanBody":
|
||||
case "EnumNumberBody":
|
||||
case "EnumStringBody":
|
||||
case "EnumSymbolBody": {
|
||||
if (node.type === "EnumSymbolBody" || node.explicitType) {
|
||||
let type = null;
|
||||
switch (node.type) {
|
||||
case "EnumBooleanBody":
|
||||
type = "boolean";
|
||||
break;
|
||||
case "EnumNumberBody":
|
||||
type = "number";
|
||||
break;
|
||||
case "EnumStringBody":
|
||||
type = "string";
|
||||
break;
|
||||
case "EnumSymbolBody":
|
||||
type = "symbol";
|
||||
break;
|
||||
}
|
||||
parts.push("of ", type, " ");
|
||||
}
|
||||
if (node.members.length === 0 && !node.hasUnknownMembers) {
|
||||
parts.push(
|
||||
group(["{", printDanglingComments(path, options), softline, "}"])
|
||||
);
|
||||
} else {
|
||||
const members =
|
||||
node.members.length > 0
|
||||
? [
|
||||
hardline,
|
||||
printArrayItems(path, options, "members", print),
|
||||
node.hasUnknownMembers || shouldPrintComma(options) ? "," : "",
|
||||
]
|
||||
: [];
|
||||
|
||||
parts.push(
|
||||
group([
|
||||
"{",
|
||||
indent([
|
||||
...members,
|
||||
...(node.hasUnknownMembers ? [hardline, "..."] : []),
|
||||
]),
|
||||
printDanglingComments(path, options, /* sameIndent */ true),
|
||||
hardline,
|
||||
"}",
|
||||
])
|
||||
);
|
||||
}
|
||||
return parts;
|
||||
}
|
||||
case "EnumBooleanMember":
|
||||
case "EnumNumberMember":
|
||||
case "EnumStringMember":
|
||||
return [
|
||||
print("id"),
|
||||
" = ",
|
||||
typeof node.init === "object" ? print("init") : String(node.init),
|
||||
];
|
||||
case "EnumDefaultedMember":
|
||||
return print("id");
|
||||
case "FunctionTypeParam": {
|
||||
const name = node.name
|
||||
? print("name")
|
||||
: path.getParentNode().this === node
|
||||
? "this"
|
||||
: "";
|
||||
return [
|
||||
name,
|
||||
printOptionalToken(path),
|
||||
name ? ": " : "",
|
||||
print("typeAnnotation"),
|
||||
];
|
||||
}
|
||||
|
||||
case "InterfaceDeclaration":
|
||||
case "InterfaceTypeAnnotation":
|
||||
return printInterface(path, options, print);
|
||||
case "ClassImplements":
|
||||
case "InterfaceExtends":
|
||||
return [print("id"), print("typeParameters")];
|
||||
case "NullableTypeAnnotation":
|
||||
return ["?", print("typeAnnotation")];
|
||||
case "Variance": {
|
||||
const { kind } = node;
|
||||
assert.ok(kind === "plus" || kind === "minus");
|
||||
return kind === "plus" ? "+" : "-";
|
||||
}
|
||||
case "ObjectTypeCallProperty":
|
||||
if (node.static) {
|
||||
parts.push("static ");
|
||||
}
|
||||
|
||||
parts.push(print("value"));
|
||||
|
||||
return parts;
|
||||
case "ObjectTypeIndexer": {
|
||||
return [
|
||||
node.variance ? print("variance") : "",
|
||||
"[",
|
||||
print("id"),
|
||||
node.id ? ": " : "",
|
||||
print("key"),
|
||||
"]: ",
|
||||
print("value"),
|
||||
];
|
||||
}
|
||||
case "ObjectTypeProperty": {
|
||||
let modifier = "";
|
||||
|
||||
if (node.proto) {
|
||||
modifier = "proto ";
|
||||
} else if (node.static) {
|
||||
modifier = "static ";
|
||||
}
|
||||
|
||||
return [
|
||||
modifier,
|
||||
isGetterOrSetter(node) ? node.kind + " " : "",
|
||||
node.variance ? print("variance") : "",
|
||||
printPropertyKey(path, options, print),
|
||||
printOptionalToken(path),
|
||||
isFunctionNotation(node) ? "" : ": ",
|
||||
print("value"),
|
||||
];
|
||||
}
|
||||
case "QualifiedTypeIdentifier":
|
||||
return [print("qualification"), ".", print("id")];
|
||||
case "StringLiteralTypeAnnotation":
|
||||
return printString(rawText(node), options);
|
||||
case "NumberLiteralTypeAnnotation":
|
||||
assert.strictEqual(typeof node.value, "number");
|
||||
// fall through
|
||||
case "BigIntLiteralTypeAnnotation":
|
||||
if (node.extra) {
|
||||
return printNumber(node.extra.raw);
|
||||
}
|
||||
return printNumber(node.raw);
|
||||
case "TypeCastExpression": {
|
||||
return [
|
||||
"(",
|
||||
print("expression"),
|
||||
printTypeAnnotation(path, options, print),
|
||||
")",
|
||||
];
|
||||
}
|
||||
|
||||
case "TypeParameterDeclaration":
|
||||
case "TypeParameterInstantiation": {
|
||||
const printed = printTypeParameters(path, options, print, "params");
|
||||
|
||||
if (options.parser === "flow") {
|
||||
const start = locStart(node);
|
||||
const end = locEnd(node);
|
||||
const commentStartIndex = options.originalText.lastIndexOf("/*", start);
|
||||
const commentEndIndex = options.originalText.indexOf("*/", end);
|
||||
if (commentStartIndex !== -1 && commentEndIndex !== -1) {
|
||||
const comment = options.originalText
|
||||
.slice(commentStartIndex + 2, commentEndIndex)
|
||||
.trim();
|
||||
if (
|
||||
comment.startsWith("::") &&
|
||||
!comment.includes("/*") &&
|
||||
!comment.includes("*/")
|
||||
) {
|
||||
return ["/*:: ", printed, " */"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return printed;
|
||||
}
|
||||
|
||||
case "InferredPredicate":
|
||||
return "%checks";
|
||||
// Unhandled types below. If encountered, nodes of these types should
|
||||
// be either left alone or desugared into AST types that are fully
|
||||
// supported by the pretty-printer.
|
||||
case "DeclaredPredicate":
|
||||
return ["%checks(", print("value"), ")"];
|
||||
case "AnyTypeAnnotation":
|
||||
return "any";
|
||||
case "BooleanTypeAnnotation":
|
||||
return "boolean";
|
||||
case "BigIntTypeAnnotation":
|
||||
return "bigint";
|
||||
case "NullLiteralTypeAnnotation":
|
||||
return "null";
|
||||
case "NumberTypeAnnotation":
|
||||
return "number";
|
||||
case "SymbolTypeAnnotation":
|
||||
return "symbol";
|
||||
case "StringTypeAnnotation":
|
||||
return "string";
|
||||
case "VoidTypeAnnotation":
|
||||
return "void";
|
||||
case "ThisTypeAnnotation":
|
||||
return "this";
|
||||
|
||||
case "PrivateIdentifier":
|
||||
return ["#", print("name")];
|
||||
case "PrivateName":
|
||||
|
||||
Reference in new issue
Block a user