feat: add new parser babel-ts to parse TypeScript syntaxes via Babel (#6400)

* feat: add new parser `babel-ts` to parse TypeScript syntaxes via Babel

* docs: document parser babel-ts

* chore: enable babel-ts in markdown and worker.js

* verify all TS tests against babel-ts except disabled by disableBabelTS

* support for TSDeclareMethod; fix abstract properties and methods

* fix embedded angular templates and styles

* fix TSImportType

* simplify babel options combinations

* fix method decorators

* fix ranges

* work around loc inconsistencies for SequenceExpression

* don't print trailing comma in type parameters (unsupported in TS < 3.3)

* preserve quotes for class properties

* align printing of single-parameter functions

* fix comments in degenerate single-element unions and intersections

* fix comments for methods

* fix comments for mapped types

* edit docs, change 'since' to 2.0.0

* add changelog

* fix code sample on playground

* update snapshots after rebase

Co-authored-by: Georgii Dolzhykov <thorn.mailbox@gmail.com>
This commit is contained in:
JounQinandGeorgii Dolzhykov authored and GitHub committed 2020-01-29 14:11:16 +02:00
1 parent 0c51368d33
commit c1937cb1b8
41 files changed
+375 -147

No files matched your search

@@ -0,0 +1,3 @@
#### Babel as an alternative parser for TypeScript ([#6400](https://github.com/prettier/prettier/pull/6400) by [@JounQin](https://github.com/JounQin) & [@thorn0](https://github.com/thorn0))
A new value for the `parser` option has been added: `babel-ts`, which stands for Babel with its TypeScript support enabled. The `babel-ts` parser supports JavaScript features not yet supported by TypeScript (ECMAScript proposals, e.g. [private methods and accessors](https://github.com/tc39/proposal-private-methods)), but it's less permissive when it comes to error recovery and less battle-tested than the `typescript` parser. While Babel's TypeScript plugin is quite mature, ASTs produced by the two parsers aren't 100% compatible. We tried to take the discrepancies into account, but there still must remain cases where code gets formatted differently or even incorrectly. We call upon the community to help us find such cases. If you see them, please raise issues. In the long run, this will help with [unifying the AST format](https://github.com/typescript-eslint/typescript-eslint/tree/master/packages/typescript-estree#ast-alignment-tests) in future versions of the parsers and thus contribute to a better, more solid JavaScript parser ecosystem.
+3 -2
View File
@@ -196,12 +196,13 @@ Specify which parser to use.
Prettier automatically infers the parser from the input file path, so you shouldn't have to change this setting. Prettier automatically infers the parser from the input file path, so you shouldn't have to change this setting.
Both the `babel` and `flow` parsers support the same set of JavaScript features (including Flow type annotations). They might differ in some edge cases, so if you run into one of those you can try `flow` instead of `babel`. Both the `babel` and `flow` parsers support the same set of JavaScript features (including Flow type annotations). They might differ in some edge cases, so if you run into one of those you can try `flow` instead of `babel`. Almost the same applies to `typescript` and `babel-ts`. `babel-ts` might support JavaScript features (proposals) not yet supported by TypeScript, but it's less permissive when it comes to invalid code and less battle-tested than the `typescript` parser.
Valid options: Valid options:
- `"babel"` (via [@babel/parser](https://github.com/babel/babel/tree/master/packages/babel-parser)) _Named `"babylon"` until v1.16.0_ - `"babel"` (via [@babel/parser](https://github.com/babel/babel/tree/master/packages/babel-parser)) _Named `"babylon"` until v1.16.0_
- `"babel-flow"` (Same as `"babel"` but enables Flow parsing explicitly to avoid ambiguity) _First available in v1.16.0_ - `"babel-flow"` (same as `"babel"` but enables Flow parsing explicitly to avoid ambiguity) _First available in v1.16.0_
- `"babel-ts"` (similar to `"typescript"` but uses Babel and its TypeScript plugin) _First available in v2.0.0_
- `"flow"` (via [flow-parser](https://github.com/facebook/flow/tree/master/src/parser)) - `"flow"` (via [flow-parser](https://github.com/facebook/flow/tree/master/src/parser))
- `"typescript"` (via [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint)) _First available in v1.4.0_ - `"typescript"` (via [@typescript-eslint/typescript-estree](https://github.com/typescript-eslint/typescript-eslint)) _First available in v1.4.0_
- `"css"` (via [postcss-scss](https://github.com/postcss/postcss-scss) and [postcss-less](https://github.com/shellscape/postcss-less), autodetects which to use) _First available in v1.7.1_ - `"css"` (via [postcss-scss](https://github.com/postcss/postcss-scss) and [postcss-less](https://github.com/shellscape/postcss-less), autodetects which to use) _First available in v1.7.1_
+5
View File
@@ -19,6 +19,11 @@ module.exports = [
"babel-flow" "babel-flow"
]; ];
}, },
get "babel-ts"() {
return eval("require")("../language-js/parser-babylon").parsers[
"babel-ts"
];
},
get babylon() { get babylon() {
return eval("require")("../language-js/parser-babylon").parsers.babel; return eval("require")("../language-js/parser-babylon").parsers.babel;
}, },
+1
View File
@@ -7,6 +7,7 @@ function clean(ast, newObj, parent) {
"comments", "comments",
"leadingComments", "leadingComments",
"trailingComments", "trailingComments",
"innerComments",
"extra", "extra",
"start", "start",
"end", "end",
+50 -6
View File
@@ -460,8 +460,9 @@ function handleMethodNameComments(
if ( if (
enclosingNode && enclosingNode &&
precedingNode && precedingNode &&
// "MethodDefinition" is handled in getCommentChildNodes
(enclosingNode.type === "Property" || (enclosingNode.type === "Property" ||
enclosingNode.type === "MethodDefinition" || enclosingNode.type === "TSDeclareMethod" ||
enclosingNode.type === "TSAbstractMethodDefinition") && enclosingNode.type === "TSAbstractMethodDefinition") &&
precedingNode.type === "Identifier" && precedingNode.type === "Identifier" &&
enclosingNode.key === precedingNode && enclosingNode.key === precedingNode &&
@@ -487,6 +488,7 @@ function handleMethodNameComments(
enclosingNode.type === "ClassProperty" || enclosingNode.type === "ClassProperty" ||
enclosingNode.type === "TSAbstractClassProperty" || enclosingNode.type === "TSAbstractClassProperty" ||
enclosingNode.type === "TSAbstractMethodDefinition" || enclosingNode.type === "TSAbstractMethodDefinition" ||
enclosingNode.type === "TSDeclareMethod" ||
enclosingNode.type === "MethodDefinition") enclosingNode.type === "MethodDefinition")
) { ) {
addTrailingComment(precedingNode, comment); addTrailingComment(precedingNode, comment);
@@ -558,7 +560,8 @@ function handleCommentInEmptyParens(text, enclosingNode, comment, options) {
if ( if (
enclosingNode && enclosingNode &&
((isRealFunctionLikeNode(enclosingNode) && ((isRealFunctionLikeNode(enclosingNode) &&
enclosingNode.params.length === 0) || // `params` vs `parameters` - see https://github.com/babel/babel/issues/9231
(enclosingNode.params || enclosingNode.parameters).length === 0) ||
((enclosingNode.type === "CallExpression" || ((enclosingNode.type === "CallExpression" ||
enclosingNode.type === "OptionalCallExpression" || enclosingNode.type === "OptionalCallExpression" ||
enclosingNode.type === "NewExpression") && enclosingNode.type === "NewExpression") &&
@@ -623,10 +626,14 @@ function handleLastFunctionArgComments(
followingNode.type === "BlockStatement" followingNode.type === "BlockStatement"
) { ) {
const functionParamRightParenIndex = (() => { const functionParamRightParenIndex = (() => {
if (enclosingNode.params.length !== 0) { if ((enclosingNode.params || enclosingNode.parameters).length !== 0) {
return privateUtil.getNextNonSpaceNonCommentCharacterIndexWithStartIndex( return privateUtil.getNextNonSpaceNonCommentCharacterIndexWithStartIndex(
text, text,
options.locEnd(privateUtil.getLast(enclosingNode.params)) options.locEnd(
privateUtil.getLast(
enclosingNode.params || enclosingNode.parameters
)
)
); );
} }
const functionParamLeftParenIndex = privateUtil.getNextNonSpaceNonCommentCharacterIndexWithStartIndex( const functionParamLeftParenIndex = privateUtil.getNextNonSpaceNonCommentCharacterIndexWithStartIndex(
@@ -899,14 +906,51 @@ function isRealFunctionLikeNode(node) {
node.type === "TSConstructSignatureDeclaration" || node.type === "TSConstructSignatureDeclaration" ||
node.type === "TSMethodSignature" || node.type === "TSMethodSignature" ||
node.type === "TSConstructorType" || node.type === "TSConstructorType" ||
node.type === "TSFunctionType" node.type === "TSFunctionType" ||
node.type === "TSDeclareMethod"
); );
} }
function getGapRegex(enclosingNode) {
if (
enclosingNode &&
enclosingNode.type !== "BinaryExpression" &&
enclosingNode.type !== "LogicalExpression"
) {
// Support degenerate single-element unions and intersections.
// E.g.: `type A = /* 1 */ & B`
return /^[\s(&|]*$/;
}
}
function getCommentChildNodes(node, options) {
// Prevent attaching comments to FunctionExpression in this case:
// class Foo {
// bar() // comment
// {
// baz();
// }
// }
if (
(options.parser === "typescript" || options.parser === "flow") &&
node.type === "MethodDefinition" &&
node.value &&
node.value.type === "FunctionExpression" &&
node.value.params.length === 0 &&
!node.value.returnType &&
(!node.value.typeParameters || node.value.typeParameters.length === 0) &&
node.value.body
) {
return [...(node.decorators || []), node.key, node.value.body];
}
}
module.exports = { module.exports = {
handleOwnLineComment, handleOwnLineComment,
handleEndOfLineComment, handleEndOfLineComment,
handleRemainingComment, handleRemainingComment,
hasLeadingComment, hasLeadingComment,
isBlockComment isBlockComment,
getGapRegex,
getCommentChildNodes
}; };
+2 -2
View File
@@ -391,7 +391,7 @@ function isAngularComponentStyles(path) {
node => node.type === "TemplateLiteral", node => node.type === "TemplateLiteral",
(node, name) => node.type === "ArrayExpression" && name === "elements", (node, name) => node.type === "ArrayExpression" && name === "elements",
(node, name) => (node, name) =>
node.type === "Property" && (node.type === "Property" || node.type === "ObjectProperty") &&
node.key.type === "Identifier" && node.key.type === "Identifier" &&
node.key.name === "styles" && node.key.name === "styles" &&
name === "value", name === "value",
@@ -402,7 +402,7 @@ function isAngularComponentTemplate(path) {
return path.match( return path.match(
node => node.type === "TemplateLiteral", node => node.type === "TemplateLiteral",
(node, name) => (node, name) =>
node.type === "Property" && (node.type === "Property" || node.type === "ObjectProperty") &&
node.key.type === "Identifier" && node.key.type === "Identifier" &&
node.key.name === "template" && node.key.name === "template" &&
name === "value", name === "value",
+2 -2
View File
@@ -32,13 +32,13 @@ const languages = [
createLanguage(require("linguist-languages/data/TypeScript"), data => ({ createLanguage(require("linguist-languages/data/TypeScript"), data => ({
...data, ...data,
since: "1.4.0", since: "1.4.0",
parsers: ["typescript"], parsers: ["typescript", "babel-ts"],
vscodeLanguageIds: ["typescript"] vscodeLanguageIds: ["typescript"]
})), })),
createLanguage(require("linguist-languages/data/TSX"), data => ({ createLanguage(require("linguist-languages/data/TSX"), data => ({
...data, ...data,
since: "1.4.0", since: "1.4.0",
parsers: ["typescript"], parsers: ["typescript", "babel-ts"],
vscodeLanguageIds: ["typescriptreact"] vscodeLanguageIds: ["typescriptreact"]
})), })),
createLanguage(require("linguist-languages/data/JSON"), data => ({ createLanguage(require("linguist-languages/data/JSON"), data => ({
+16 -13
View File
@@ -59,20 +59,23 @@ function locEnd(node) {
return loc; return loc;
} }
function composeLoc(startNode, endNode = startNode) { function composeLoc(startNode, endNodeOrLength = startNode) {
const loc = {}; const length = typeof endNodeOrLength === "number" ? endNodeOrLength : -1;
if (typeof startNode.start === "number") { const start = locStart(startNode);
loc.start = startNode.start; const end = length !== -1 ? start + length : locEnd(endNodeOrLength);
loc.end = endNode.end; const startLoc = startNode.loc.start;
} return {
if (Array.isArray(startNode.range)) { start,
loc.range = [startNode.range[0], endNode.range[1]]; end,
} range: [start, end],
loc.loc = { loc: {
start: startNode.loc.start, start: startLoc,
end: endNode.loc.end end:
length !== -1
? { line: startLoc.line, column: startLoc.column + length }
: endNodeOrLength.loc.end
}
}; };
return loc;
} }
module.exports = { module.exports = {
+36 -10
View File
@@ -8,7 +8,7 @@ const { hasPragma } = require("./pragma");
const locFns = require("./loc"); const locFns = require("./loc");
const postprocess = require("./postprocess"); const postprocess = require("./postprocess");
function babelOptions(extraOptions, extraPlugins = []) { function babelOptions(extraPlugins = []) {
return { return {
sourceType: "module", sourceType: "module",
allowAwaitOutsideFunction: true, allowAwaitOutsideFunction: true,
@@ -18,7 +18,6 @@ function babelOptions(extraOptions, extraPlugins = []) {
allowUndeclaredExports: true, allowUndeclaredExports: true,
errorRecovery: true, errorRecovery: true,
plugins: [ plugins: [
"jsx",
"doExpressions", "doExpressions",
"objectRestSpread", "objectRestSpread",
"classProperties", "classProperties",
@@ -41,20 +40,23 @@ function babelOptions(extraOptions, extraPlugins = []) {
"classPrivateMethods", "classPrivateMethods",
"v8intrinsic", "v8intrinsic",
"partialApplication", "partialApplication",
["decorators", { decoratorsBeforeExport: false }] ["decorators", { decoratorsBeforeExport: false }],
].concat(extraPlugins), ...extraPlugins
...extraOptions ]
}; };
} }
function createParse(parseMethod, extraPlugins) { function createParse(parseMethod, ...pluginCombinations) {
return (text, parsers, opts) => { return (text, parsers, opts) => {
// Inline the require to avoid loading all the JS if we don't use it // Inline the require to avoid loading all the JS if we don't use it
const babel = require("@babel/parser"); const babel = require("@babel/parser");
let ast; let ast;
try { try {
ast = babel[parseMethod](text, babelOptions({}, extraPlugins)); ast = tryCombinations(
options => babel[parseMethod](text, options),
pluginCombinations.map(babelOptions)
);
} catch (error) { } catch (error) {
throw createError( throw createError(
// babel error prints (l:c) with cols that are zero indexed // babel error prints (l:c) with cols that are zero indexed
@@ -73,9 +75,31 @@ function createParse(parseMethod, extraPlugins) {
}; };
} }
const parse = createParse("parse", ["flow"]); const parse = createParse("parse", ["jsx", "flow"]);
const parseFlow = createParse("parse", [["flow", { all: true, enums: true }]]); const parseFlow = createParse("parse", [
const parseExpression = createParse("parseExpression"); "jsx",
["flow", { all: true, enums: true }]
]);
const parseTypeScript = createParse(
"parse",
["jsx", "typescript"],
["typescript"]
);
const parseExpression = createParse("parseExpression", ["jsx"]);
function tryCombinations(fn, combinations) {
let error;
for (let i = 0; i < combinations.length; i++) {
try {
return fn(combinations[i]);
} catch (_error) {
if (!error) {
error = _error;
}
}
}
throw error;
}
function parseJson(text, parsers, opts) { function parseJson(text, parsers, opts) {
const ast = parseExpression(text, parsers, opts); const ast = parseExpression(text, parsers, opts);
@@ -146,6 +170,7 @@ function assertJsonNode(node, parent) {
const babel = { parse, astFormat: "estree", hasPragma, ...locFns }; const babel = { parse, astFormat: "estree", hasPragma, ...locFns };
const babelFlow = { ...babel, parse: parseFlow }; const babelFlow = { ...babel, parse: parseFlow };
const babelTypeScript = { ...babel, parse: parseTypeScript };
const babelExpression = { ...babel, parse: parseExpression }; const babelExpression = { ...babel, parse: parseExpression };
// Export as a plugin so we can reuse the same bundle for UMD loading // Export as a plugin so we can reuse the same bundle for UMD loading
@@ -153,6 +178,7 @@ module.exports = {
parsers: { parsers: {
babel, babel,
"babel-flow": babelFlow, "babel-flow": babelFlow,
"babel-ts": babelTypeScript,
// aliased to keep backwards compatibility // aliased to keep backwards compatibility
babylon: babel, babylon: babel,
json: { json: {
+16
View File
@@ -32,6 +32,22 @@ function postprocess(ast, options) {
return { ...node.types[0], loc: node.loc, range: node.range }; return { ...node.types[0], loc: node.loc, range: node.range };
} }
break; break;
case "TSTypeParameter":
// babel-ts
if (typeof node.name === "string") {
node.name = {
type: "Identifier",
name: node.name,
...composeLoc(node, node.name.length)
};
}
break;
case "SequenceExpression":
// Babel (unlike other parsers) includes spaces and comments in the range. Let's unify this.
if (node.end && node.end > getLast(node.expressions).end) {
node.end = getLast(node.expressions).end;
}
break;
} }
}); });
+57 -34
View File
@@ -167,7 +167,8 @@ function genericPrint(path, options, printPath, args) {
node.type === "TSAbstractClassProperty" || node.type === "TSAbstractClassProperty" ||
node.type === "ClassPrivateProperty" || node.type === "ClassPrivateProperty" ||
node.type === "MethodDefinition" || node.type === "MethodDefinition" ||
node.type === "TSAbstractMethodDefinition" node.type === "TSAbstractMethodDefinition" ||
node.type === "TSDeclareMethod"
) { ) {
// their decorators are handled themselves // their decorators are handled themselves
} else if ( } else if (
@@ -1416,14 +1417,18 @@ function printPathNoParens(path, options, print, args) {
path.match( path.match(
node => node.type === "ObjectPattern" && !node.decorators, node => node.type === "ObjectPattern" && !node.decorators,
(node, name, number) => (node, name, number) =>
shouldHugArguments(node) && name === "params" && number === 0 shouldHugArguments(node) &&
(name === "params" || name === "parameters") &&
number === 0
) || ) ||
path.match( path.match(
shouldHugType, shouldHugType,
(node, name) => name === "typeAnnotation", (node, name) => name === "typeAnnotation",
(node, name) => name === "typeAnnotation", (node, name) => name === "typeAnnotation",
(node, name, number) => (node, name, number) =>
shouldHugArguments(node) && name === "params" && number === 0 shouldHugArguments(node) &&
(name === "params" || name === "parameters") &&
number === 0
) )
) { ) {
return content; return content;
@@ -1458,6 +1463,7 @@ function printPathNoParens(path, options, print, args) {
case "ClassPrivateMethod": case "ClassPrivateMethod":
case "MethodDefinition": case "MethodDefinition":
case "TSAbstractMethodDefinition": case "TSAbstractMethodDefinition":
case "TSDeclareMethod":
if (n.decorators && n.decorators.length !== 0) { if (n.decorators && n.decorators.length !== 0) {
parts.push(printDecorators(path, options, print)); parts.push(printDecorators(path, options, print));
} }
@@ -1467,7 +1473,7 @@ function printPathNoParens(path, options, print, args) {
if (n.static) { if (n.static) {
parts.push("static "); parts.push("static ");
} }
if (n.type === "TSAbstractMethodDefinition") { if (n.type === "TSAbstractMethodDefinition" || n.abstract) {
parts.push("abstract "); parts.push("abstract ");
} }
@@ -2355,7 +2361,7 @@ function printPathNoParens(path, options, print, args) {
if (n.static) { if (n.static) {
parts.push("static "); parts.push("static ");
} }
if (n.type === "TSAbstractClassProperty") { if (n.type === "TSAbstractClassProperty" || n.abstract) {
parts.push("abstract "); parts.push("abstract ");
} }
if (n.readonly) { if (n.readonly) {
@@ -2394,6 +2400,7 @@ function printPathNoParens(path, options, print, args) {
parts.push(concat(printClass(path, options, print))); parts.push(concat(printClass(path, options, print)));
return concat(parts); return concat(parts);
case "TSInterfaceHeritage": case "TSInterfaceHeritage":
case "TSExpressionWithTypeArguments": // Babel AST
parts.push(path.call(print, "expression")); parts.push(path.call(print, "expression"));
if (n.typeParameters) { if (n.typeParameters) {
@@ -3285,7 +3292,7 @@ function printPathNoParens(path, options, print, args) {
return concat([ return concat([
!n.isTypeOf ? "" : "typeof ", !n.isTypeOf ? "" : "typeof ",
"import(", "import(",
path.call(print, "parameter"), path.call(print, n.parameter ? "parameter" : "argument"),
")", ")",
!n.qualifier ? "" : concat([".", path.call(print, "qualifier")]), !n.qualifier ? "" : concat([".", path.call(print, "qualifier")]),
printTypeParameters(path, options, print, "typeParameters") printTypeParameters(path, options, print, "typeParameters")
@@ -3318,9 +3325,13 @@ function printPathNoParens(path, options, print, args) {
) )
); );
if (n.returnType) { if (n.returnType || n.typeAnnotation) {
const isType = n.type === "TSConstructorType"; const isType = n.type === "TSConstructorType";
parts.push(isType ? " => " : ": ", path.call(print, "returnType")); parts.push(
isType ? " => " : ": ",
path.call(print, "returnType"),
path.call(print, "typeAnnotation")
);
} }
return concat(parts); return concat(parts);
} }
@@ -3380,8 +3391,12 @@ function printPathNoParens(path, options, print, args) {
) )
); );
if (n.returnType) { if (n.returnType || n.typeAnnotation) {
parts.push(": ", path.call(print, "returnType")); parts.push(
": ",
path.call(print, "returnType"),
path.call(print, "typeAnnotation")
);
} }
return group(concat(parts)); return group(concat(parts));
case "TSNamespaceExportDeclaration": case "TSNamespaceExportDeclaration":
@@ -4638,7 +4653,9 @@ function printTypeParameters(path, options, print, paramsKey) {
]) ])
), ),
ifBreak( ifBreak(
options.parser !== "typescript" && shouldPrintComma(options, "all") options.parser !== "typescript" &&
options.parser !== "babel-ts" &&
shouldPrintComma(options, "all")
? "," ? ","
: "" : ""
), ),
@@ -5892,29 +5909,33 @@ function shouldHugType(node) {
} }
function shouldHugArguments(fun) { function shouldHugArguments(fun) {
if (!fun || fun.rest) {
return false;
}
const params = fun.params || fun.parameters;
if (!params || params.length !== 1) {
return false;
}
const param = params[0];
return ( return (
fun && !param.comments &&
fun.params && (param.type === "ObjectPattern" ||
fun.params.length === 1 && param.type === "ArrayPattern" ||
!fun.params[0].comments && (param.type === "Identifier" &&
(fun.params[0].type === "ObjectPattern" || param.typeAnnotation &&
fun.params[0].type === "ArrayPattern" || (param.typeAnnotation.type === "TypeAnnotation" ||
(fun.params[0].type === "Identifier" && param.typeAnnotation.type === "TSTypeAnnotation") &&
fun.params[0].typeAnnotation && isObjectType(param.typeAnnotation.typeAnnotation)) ||
(fun.params[0].typeAnnotation.type === "TypeAnnotation" || (param.type === "FunctionTypeParam" &&
fun.params[0].typeAnnotation.type === "TSTypeAnnotation") && isObjectType(param.typeAnnotation)) ||
isObjectType(fun.params[0].typeAnnotation.typeAnnotation)) || (param.type === "AssignmentPattern" &&
(fun.params[0].type === "FunctionTypeParam" && (param.left.type === "ObjectPattern" ||
isObjectType(fun.params[0].typeAnnotation)) || param.left.type === "ArrayPattern") &&
(fun.params[0].type === "AssignmentPattern" && (param.right.type === "Identifier" ||
(fun.params[0].left.type === "ObjectPattern" || (param.right.type === "ObjectExpression" &&
fun.params[0].left.type === "ArrayPattern") && param.right.properties.length === 0) ||
(fun.params[0].right.type === "Identifier" || (param.right.type === "ArrayExpression" &&
(fun.params[0].right.type === "ObjectExpression" && param.right.elements.length === 0))))
fun.params[0].right.properties.length === 0) ||
(fun.params[0].right.type === "ArrayExpression" &&
fun.params[0].right.elements.length === 0)))) &&
!fun.rest
); );
} }
@@ -6118,5 +6139,7 @@ module.exports = {
ownLine: handleComments.handleOwnLineComment, ownLine: handleComments.handleOwnLineComment,
endOfLine: handleComments.handleEndOfLineComment, endOfLine: handleComments.handleEndOfLineComment,
remaining: handleComments.handleRemainingComment remaining: handleComments.handleRemainingComment
} },
getGapRegex: handleComments.getGapRegex,
getCommentChildNodes: handleComments.getCommentChildNodes
}; };
+6 -1
View File
@@ -711,7 +711,12 @@ function isStringPropSafeToCoerceToIdentifier(node, options) {
isStringLiteral(node.key) && isStringLiteral(node.key) &&
isIdentifierName(node.key.value) && isIdentifierName(node.key.value) &&
options.parser !== "json" && options.parser !== "json" &&
!(options.parser === "typescript" && node.type === "ClassProperty") // With `--strictPropertyInitialization`, TS treats properties with quoted names differently than unquoted ones.
// See https://github.com/microsoft/TypeScript/pull/20075
!(
(options.parser === "typescript" || options.parser === "babel-ts") &&
node.type === "ClassProperty"
)
); );
} }
+21 -17
View File
@@ -29,7 +29,7 @@ function getSortedChildNodes(node, options, resultArray) {
const { printer, locStart, locEnd } = options; const { printer, locStart, locEnd } = options;
if (resultArray) { if (resultArray) {
if (node && printer.canAttachComment && printer.canAttachComment(node)) { if (printer.canAttachComment && printer.canAttachComment(node)) {
// This reverse insertion sort almost always takes constant // This reverse insertion sort almost always takes constant
// time because we almost always (maybe always?) append the // time because we almost always (maybe always?) append the
// nodes in order anyway. // nodes in order anyway.
@@ -49,20 +49,18 @@ function getSortedChildNodes(node, options, resultArray) {
return node[childNodesCacheKey]; return node[childNodesCacheKey];
} }
let childNodes; const childNodes =
(printer.getCommentChildNodes &&
if (printer.getCommentChildNodes) { printer.getCommentChildNodes(node, options)) ||
childNodes = printer.getCommentChildNodes(node); (typeof node === "object" &&
} else if (node && typeof node === "object") { Object.keys(node)
childNodes = Object.keys(node) .filter(
.filter( n =>
n => n !== "enclosingNode" &&
n !== "enclosingNode" && n !== "precedingNode" &&
n !== "precedingNode" && n !== "followingNode"
n !== "followingNode" )
) .map(n => node[n]));
.map(n => node[n]);
}
if (!childNodes) { if (!childNodes) {
return; return;
@@ -301,7 +299,12 @@ function breakTies(tiesToBreak, text, options) {
if (tieCount === 0) { if (tieCount === 0) {
return; return;
} }
const { precedingNode, followingNode } = tiesToBreak[0]; const { precedingNode, followingNode, enclosingNode } = tiesToBreak[0];
const gapRegExp =
(options.printer.getGapRegex &&
options.printer.getGapRegex(enclosingNode)) ||
/^[\s(]*$/;
let gapEndPos = options.locStart(followingNode); let gapEndPos = options.locStart(followingNode);
@@ -321,7 +324,8 @@ function breakTies(tiesToBreak, text, options) {
assert.strictEqual(comment.followingNode, followingNode); assert.strictEqual(comment.followingNode, followingNode);
const gap = text.slice(options.locEnd(comment), gapEndPos); const gap = text.slice(options.locEnd(comment), gapEndPos);
if (/^[\s(]*$/.test(gap)) {
if (gapRegExp.test(gap)) {
gapEndPos = options.locStart(comment); gapEndPos = options.locStart(comment);
} else { } else {
// The gap string contained something other than whitespace or open // The gap string contained something other than whitespace or open
+1
View File
@@ -133,6 +133,7 @@ const options = {
}, },
{ value: "babel", since: "1.16.0", description: "JavaScript" }, { value: "babel", since: "1.16.0", description: "JavaScript" },
{ value: "babel-flow", since: "1.16.0", description: "Flow" }, { value: "babel-flow", since: "1.16.0", description: "Flow" },
{ value: "babel-ts", since: "2.0.0", description: "TypeScript" },
{ value: "typescript", since: "1.4.0", description: "TypeScript" }, { value: "typescript", since: "1.4.0", description: "TypeScript" },
{ value: "css", since: "1.7.1", description: "CSS" }, { value: "css", since: "1.7.1", description: "CSS" },
{ {
+2
View File
@@ -137,6 +137,8 @@ function isSourceElement(opts, node) {
switch (opts.parser) { switch (opts.parser) {
case "flow": case "flow":
case "babel": case "babel":
case "babel-flow":
case "babel-ts":
case "typescript": case "typescript":
return jsSourceElements.includes(node.type); return jsSourceElements.includes(node.type);
case "json": case "json":
+2 -2
View File
@@ -75,8 +75,8 @@ function getSupportInfo(version, opts) {
.map(language => { .map(language => {
let parsers; let parsers;
// Prevent breaking changes // Prevent breaking changes
if (language.name === "Markdown" || language.name === "TypeScript") { if (language.name === "Markdown") {
parsers = [language.name.toLowerCase()]; parsers = ["markdown"];
// "babylon" was renamed to "babel" in 1.16.0 // "babylon" was renamed to "babel" in 1.16.0
} else if (useBabylonParser && language.parsers.includes("babel")) { } else if (useBabylonParser && language.parsers.includes("babel")) {
parsers = language.parsers.map(parser => parsers = language.parsers.map(parser =>
@@ -87,8 +87,7 @@ class A4 /* a */ extends B {}
(class A9 /* a */ extends B {}); (class A9 /* a */ extends B {});
class x { class x {
focus() // do nothing focus() { // do nothing
{
// do nothing // do nothing
} }
} }
+4 -4
View File
@@ -2,7 +2,7 @@
exports[`empty 1`] = ` exports[`empty 1`] = `
====================================options===================================== ====================================options=====================================
parsers: ["flow", "babel", "babel-flow", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"] parsers: ["flow", "babel", "babel-flow", "babel-ts", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"]
printWidth: 80 printWidth: 80
| printWidth | printWidth
=====================================input====================================== =====================================input======================================
@@ -14,7 +14,7 @@ printWidth: 80
exports[`newline 1`] = ` exports[`newline 1`] = `
====================================options===================================== ====================================options=====================================
parsers: ["flow", "babel", "babel-flow", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"] parsers: ["flow", "babel", "babel-flow", "babel-ts", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"]
printWidth: 80 printWidth: 80
| printWidth | printWidth
=====================================input====================================== =====================================input======================================
@@ -27,7 +27,7 @@ printWidth: 80
exports[`space 1`] = ` exports[`space 1`] = `
====================================options===================================== ====================================options=====================================
parsers: ["flow", "babel", "babel-flow", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"] parsers: ["flow", "babel", "babel-flow", "babel-ts", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"]
printWidth: 80 printWidth: 80
| printWidth | printWidth
=====================================input====================================== =====================================input======================================
@@ -40,7 +40,7 @@ printWidth: 80
exports[`space-newline 1`] = ` exports[`space-newline 1`] = `
====================================options===================================== ====================================options=====================================
parsers: ["flow", "babel", "babel-flow", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"] parsers: ["flow", "babel", "babel-flow", "babel-ts", "typescript", "css", "less", "scss", "json", "json5", "json-stringify", "graphql", "markdown", "mdx", "vue", "yaml", "html", "angular", "lwc"]
printWidth: 80 printWidth: 80
| printWidth | printWidth
=====================================input====================================== =====================================input======================================
+7 -1
View File
@@ -1 +1,7 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], {
disableBabelTS: [
"downlevelLetConst1.ts",
"errorOnInitializerInInterfaceProperty.ts",
"modifiersOnInterfaceIndexSignature1.ts"
]
});
@@ -1 +1,3 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], {
disableBabelTS: ["classAbstractMixedWithModifiers.ts"]
});
@@ -1 +1,3 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], {
disableBabelTS: ["readonlyInConstructorParameters.ts", "readonlyReadonly.ts"]
});
@@ -1 +1 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: true });
@@ -1 +1 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: true });
@@ -1 +1 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: true });
@@ -1 +1,3 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], {
disableBabelTS: ["functionOverloadErrorsSyntax.ts"]
});
@@ -1 +1 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: true });
+3 -1
View File
@@ -1 +1,3 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], {
disableBabelTS: ["constructor.ts", "generics.ts", "methods.ts"]
});
+1 -1
View File
@@ -1 +1 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: ["interface.ts"] });
+11 -3
View File
@@ -1,3 +1,11 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], {
run_spec(__dirname, ["typescript"], { trailingComma: "es5" }); disableBabelTS: ["jsdoc_only_types.ts", "index-signature.ts"]
run_spec(__dirname, ["typescript"], { trailingComma: "all" }); });
run_spec(__dirname, ["typescript"], {
trailingComma: "es5",
disableBabelTS: ["jsdoc_only_types.ts", "index-signature.ts"]
});
run_spec(__dirname, ["typescript"], {
trailingComma: "all",
disableBabelTS: ["jsdoc_only_types.ts", "index-signature.ts"]
});
@@ -1,5 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`single-parameter.ts 1`] = `
====================================options=====================================
parsers: ["typescript"]
printWidth: 80
| printWidth
=====================================input======================================
type X = (options:{ a: string; b: AbstractCompositeThingamabobberFactoryProvider}) => {};
type Y = new (options:{ a: string; b: AbstractCompositeThingamabobberFactoryProvider}) => {};
=====================================output=====================================
type X = (options: {
a: string;
b: AbstractCompositeThingamabobberFactoryProvider;
}) => {};
type Y = new (options: {
a: string;
b: AbstractCompositeThingamabobberFactoryProvider;
}) => {};
================================================================================
`;
exports[`type-annotation.ts 1`] = ` exports[`type-annotation.ts 1`] = `
====================================options===================================== ====================================options=====================================
parsers: ["typescript"] parsers: ["typescript"]
@@ -0,0 +1,2 @@
type X = (options:{ a: string; b: AbstractCompositeThingamabobberFactoryProvider}) => {};
type Y = new (options:{ a: string; b: AbstractCompositeThingamabobberFactoryProvider}) => {};
+5 -2
View File
@@ -1,2 +1,5 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: ["abstract.ts"] });
run_spec(__dirname, ["typescript"], { semi: false }); run_spec(__dirname, ["typescript"], {
semi: false,
disableBabelTS: ["abstract.ts"]
});
+1 -1
View File
@@ -1 +1 @@
run_spec(__dirname, ["typescript"]); run_spec(__dirname, ["typescript"], { disableBabelTS: true });
+20 -2
View File
@@ -90,7 +90,21 @@ global.run_spec = (dirname, parsers, options) => {
).toMatchSnapshot(); ).toMatchSnapshot();
}); });
for (const parser of parsers.slice(1)) { const parsersToVerify = parsers.slice(1);
if (
parsers.includes("typescript") &&
!parsers.includes("babel-ts") &&
!(
options &&
(options.disableBabelTS === true ||
(Array.isArray(options.disableBabelTS) &&
options.disableBabelTS.includes(basename)))
)
) {
parsersToVerify.push("babel-ts");
}
for (const parser of parsersToVerify) {
const verifyOptions = { ...baseOptions, parser }; const verifyOptions = { ...baseOptions, parser };
test(`${basename} - ${parser}-verify`, () => { test(`${basename} - ${parser}-verify`, () => {
const verifyOutput = format(input, filename, verifyOptions); const verifyOutput = format(input, filename, verifyOptions);
@@ -172,7 +186,11 @@ function createSnapshot(input, output, options) {
printOptions( printOptions(
omit( omit(
options, options,
k => k === "rangeStart" || k === "rangeEnd" || k === "cursorOffset" k =>
k === "rangeStart" ||
k === "rangeEnd" ||
k === "cursorOffset" ||
k === "disableBabelTS"
) )
), ),
printWidthIndicator, printWidthIndicator,
@@ -72,7 +72,7 @@ Format options:
Defaults to false. Defaults to false.
--jsx-single-quote Use single quotes in JSX. --jsx-single-quote Use single quotes in JSX.
Defaults to false. Defaults to false.
--parser <flow|babel|babel-flow|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc> --parser <flow|babel|babel-flow|babel-ts|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc>
Which parser to use. Which parser to use.
--print-width <int> The line length where Prettier will try wrap. --print-width <int> The line length where Prettier will try wrap.
Defaults to 80. Defaults to 80.
@@ -168,7 +168,7 @@ exports[`show warning with --help not-found (typo) (stderr) 1`] = `
`; `;
exports[`show warning with --help not-found (typo) (stdout) 1`] = ` exports[`show warning with --help not-found (typo) (stdout) 1`] = `
"--parser <flow|babel|babel-flow|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc> "--parser <flow|babel|babel-flow|babel-ts|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc>
Which parser to use. Which parser to use.
@@ -177,6 +177,7 @@ Valid options:
flow Flow flow Flow
babel JavaScript babel JavaScript
babel-flow Flow babel-flow Flow
babel-ts TypeScript
typescript TypeScript typescript TypeScript
css CSS css CSS
less Less less Less
@@ -228,7 +229,7 @@ Format options:
Defaults to false. Defaults to false.
--jsx-single-quote Use single quotes in JSX. --jsx-single-quote Use single quotes in JSX.
Defaults to false. Defaults to false.
--parser <flow|babel|babel-flow|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc> --parser <flow|babel|babel-flow|babel-ts|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc>
Which parser to use. Which parser to use.
--print-width <int> The line length where Prettier will try wrap. --print-width <int> The line length where Prettier will try wrap.
Defaults to 80. Defaults to 80.
@@ -332,7 +332,7 @@ exports[`show detailed usage with --help no-semi (write) 1`] = `Array []`;
exports[`show detailed usage with --help parser (stderr) 1`] = `""`; exports[`show detailed usage with --help parser (stderr) 1`] = `""`;
exports[`show detailed usage with --help parser (stdout) 1`] = ` exports[`show detailed usage with --help parser (stdout) 1`] = `
"--parser <flow|babel|babel-flow|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc> "--parser <flow|babel|babel-flow|babel-ts|typescript|css|less|scss|json|json5|json-stringify|graphql|markdown|mdx|vue|yaml|html|angular|lwc>
Which parser to use. Which parser to use.
@@ -341,6 +341,7 @@ Valid options:
flow Flow flow Flow
babel JavaScript babel JavaScript
babel-flow Flow babel-flow Flow
babel-ts TypeScript
typescript TypeScript typescript TypeScript
css CSS css CSS
less Less less Less
@@ -132,6 +132,12 @@ This option cannot be used with --range-start and --range-end.",
"babel-flow", "babel-flow",
], ],
}, },
Object {
"description": "TypeScript",
"enum": Array [
"babel-ts",
],
},
Object { Object {
"description": "TypeScript", "description": "TypeScript",
"enum": Array [ "enum": Array [
@@ -141,7 +141,7 @@ exports[`API getSupportInfo() with version 1.0.0 -> 1.4.0 1`] = `
\\"flow\\", \\"flow\\",
], ],
\\"JSX\\": Array [ \\"JSX\\": Array [
@@ -9,31 +12,79 @@ @@ -9,31 +12,81 @@
\\"flow\\", \\"flow\\",
], ],
\\"JavaScript\\": Array [ \\"JavaScript\\": Array [
@@ -156,26 +156,28 @@ exports[`API getSupportInfo() with version 1.0.0 -> 1.4.0 1`] = `
+ ], + ],
+ \\"SCSS\\": Array [ + \\"SCSS\\": Array [
+ \\"postcss\\", + \\"postcss\\",
], + ],
+ \\"TSX\\": Array [ + \\"TSX\\": Array [
+ \\"typescript\\", + \\"typescript\\",
+ \\"babel-ts\\",
+ ], + ],
+ \\"TypeScript\\": Array [ + \\"TypeScript\\": Array [
+ \\"typescript\\", + \\"typescript\\",
+ ], + \\"babel-ts\\",
],
}, },
\\"options\\": Object { \\"options\\": Object {
\\"bracketSpacing\\": Object { \\"bracketSpacing\\": Object {
\\"default\\": true, \\"default\\": true,
\\"type\\": \\"boolean\\", \\"type\\": \\"boolean\\",
+ }, },
+ \\"cursorOffset\\": Object { + \\"cursorOffset\\": Object {
+ \\"default\\": -1, + \\"default\\": -1,
+ \\"range\\": Object { + \\"range\\": Object {
+ \\"end\\": Infinity, + \\"end\\": Infinity,
+ \\"start\\": -1, + \\"start\\": -1,
+ \\"step\\": 1, + \\"step\\": 1,
}, + },
+ \\"type\\": \\"int\\", + \\"type\\": \\"int\\",
+ }, + },
+ \\"filepath\\": Object { + \\"filepath\\": Object {
@@ -248,7 +250,7 @@ exports[`API getSupportInfo() with version 1.4.0 -> 1.5.0 1`] = `
\\"flow\\", \\"flow\\",
], ],
\\"JavaScript\\": Array [ \\"JavaScript\\": Array [
@@ -57,10 +66,12 @@ @@ -59,10 +68,12 @@
\\"choices\\": Array [ \\"choices\\": Array [
\\"flow\\", \\"flow\\",
\\"babylon\\", \\"babylon\\",
@@ -298,9 +300,9 @@ exports[`API getSupportInfo() with version 1.5.0 -> 1.7.1 1`] = `
], ],
\\"TSX\\": Array [ \\"TSX\\": Array [
\\"typescript\\", \\"typescript\\",
\\"babel-ts\\",
], ],
\\"TypeScript\\": Array [ @@ -67,11 +67,13 @@
@@ -65,11 +65,13 @@
\\"parser\\": Object { \\"parser\\": Object {
\\"choices\\": Array [ \\"choices\\": Array [
\\"flow\\", \\"flow\\",
@@ -315,7 +317,7 @@ exports[`API getSupportInfo() with version 1.5.0 -> 1.7.1 1`] = `
], ],
\\"default\\": \\"babylon\\", \\"default\\": \\"babylon\\",
\\"type\\": \\"choice\\", \\"type\\": \\"choice\\",
@@ -98,10 +100,14 @@ @@ -100,10 +102,14 @@
\\"end\\": Infinity, \\"end\\": Infinity,
\\"start\\": 0, \\"start\\": 0,
\\"step\\": 1, \\"step\\": 1,
@@ -351,7 +353,7 @@ exports[`API getSupportInfo() with version 1.7.1 -> 1.8.0 1`] = `
], ],
\\"SCSS\\": Array [ \\"SCSS\\": Array [
\\"scss\\", \\"scss\\",
@@ -55,10 +58,14 @@ @@ -57,10 +60,14 @@
\\"type\\": \\"int\\", \\"type\\": \\"int\\",
}, },
\\"filepath\\": Object { \\"filepath\\": Object {
@@ -366,7 +368,7 @@ exports[`API getSupportInfo() with version 1.7.1 -> 1.8.0 1`] = `
\\"default\\": false, \\"default\\": false,
\\"type\\": \\"boolean\\", \\"type\\": \\"boolean\\",
}, },
@@ -70,10 +77,11 @@ @@ -72,10 +79,11 @@
\\"css\\", \\"css\\",
\\"less\\", \\"less\\",
\\"scss\\", \\"scss\\",
@@ -385,7 +387,7 @@ exports[`API getSupportInfo() with version 1.8.0 -> 1.8.2 1`] = `
- First value - First value
+ Second value + Second value
@@ -91,10 +91,18 @@ @@ -93,10 +93,18 @@
\\"start\\": 0, \\"start\\": 0,
\\"step\\": 1, \\"step\\": 1,
}, },
@@ -463,12 +465,12 @@ exports[`API getSupportInfo() with version 1.8.2 -> 1.16.0 1`] = `
\\"markdown\\", \\"markdown\\",
], ],
\\"PostCSS\\": Array [ \\"PostCSS\\": Array [
@@ -39,13 +54,27 @@ @@ -41,13 +56,27 @@
\\"TSX\\": Array [ \\"babel-ts\\",
\\"typescript\\",
], ],
\\"TypeScript\\": Array [ \\"TypeScript\\": Array [
\\"typescript\\", \\"typescript\\",
\\"babel-ts\\",
+ ], + ],
+ \\"Vue\\": Array [ + \\"Vue\\": Array [
+ \\"vue\\", + \\"vue\\",
@@ -491,7 +493,7 @@ exports[`API getSupportInfo() with version 1.8.2 -> 1.16.0 1`] = `
\\"type\\": \\"boolean\\", \\"type\\": \\"boolean\\",
}, },
\\"cursorOffset\\": Object { \\"cursorOffset\\": Object {
@@ -55,36 +84,75 @@ @@ -57,36 +86,75 @@
\\"start\\": -1, \\"start\\": -1,
\\"step\\": 1, \\"step\\": 1,
}, },
@@ -569,7 +571,7 @@ exports[`API getSupportInfo() with version 1.8.2 -> 1.16.0 1`] = `
\\"default\\": 80, \\"default\\": 80,
\\"range\\": Object { \\"range\\": Object {
\\"end\\": Infinity, \\"end\\": Infinity,
@@ -93,14 +161,15 @@ @@ -95,14 +163,15 @@
}, },
\\"type\\": \\"int\\", \\"type\\": \\"int\\",
}, },
@@ -609,7 +611,7 @@ exports[`API getSupportInfo() with version 1.16.0 -> undefined 1`] = `
], ],
\\"Markdown\\": Array [ \\"Markdown\\": Array [
\\"markdown\\", \\"markdown\\",
@@ -68,11 +71,11 @@ @@ -70,11 +73,11 @@
\\"arrowParens\\": Object { \\"arrowParens\\": Object {
\\"choices\\": Array [ \\"choices\\": Array [
\\"always\\", \\"always\\",
@@ -622,7 +624,7 @@ exports[`API getSupportInfo() with version 1.16.0 -> undefined 1`] = `
\\"bracketSpacing\\": Object { \\"bracketSpacing\\": Object {
\\"default\\": true, \\"default\\": true,
\\"type\\": \\"boolean\\", \\"type\\": \\"boolean\\",
@@ -91,11 +94,11 @@ @@ -93,11 +96,11 @@
\\"lf\\", \\"lf\\",
\\"crlf\\", \\"crlf\\",
\\"cr\\", \\"cr\\",
@@ -635,7 +637,19 @@ exports[`API getSupportInfo() with version 1.16.0 -> undefined 1`] = `
\\"filepath\\": Object { \\"filepath\\": Object {
\\"default\\": undefined, \\"default\\": undefined,
\\"type\\": \\"path\\", \\"type\\": \\"path\\",
@@ -138,10 +141,11 @@ @@ -126,10 +129,11 @@
\\"parser\\": Object {
\\"choices\\": Array [
\\"flow\\",
\\"babel\\",
\\"babel-flow\\",
+ \\"babel-ts\\",
\\"typescript\\",
\\"css\\",
\\"less\\",
\\"scss\\",
\\"json\\",
@@ -140,10 +144,11 @@
\\"mdx\\", \\"mdx\\",
\\"vue\\", \\"vue\\",
\\"yaml\\", \\"yaml\\",
@@ -647,12 +661,14 @@ exports[`API getSupportInfo() with version 1.16.0 -> undefined 1`] = `
\\"type\\": \\"choice\\", \\"type\\": \\"choice\\",
}, },
\\"pluginSearchDirs\\": Object { \\"pluginSearchDirs\\": Object {
@@ -168,10 +172,19 @@ @@ -168,10 +173,19 @@
\\"always\\",
\\"never\\",
\\"preserve\\", \\"preserve\\",
], ],
\\"default\\": \\"preserve\\", \\"default\\": \\"preserve\\",
\\"type\\": \\"choice\\", + \\"type\\": \\"choice\\",
}, + },
+ \\"quoteProps\\": Object { + \\"quoteProps\\": Object {
+ \\"choices\\": Array [ + \\"choices\\": Array [
+ \\"as-needed\\", + \\"as-needed\\",
@@ -660,14 +676,12 @@ exports[`API getSupportInfo() with version 1.16.0 -> undefined 1`] = `
+ \\"preserve\\", + \\"preserve\\",
+ ], + ],
+ \\"default\\": \\"as-needed\\", + \\"default\\": \\"as-needed\\",
+ \\"type\\": \\"choice\\", \\"type\\": \\"choice\\",
+ }, },
\\"rangeEnd\\": Object { \\"rangeEnd\\": Object {
\\"default\\": Infinity, \\"default\\": Infinity,
\\"range\\": Object { \\"range\\": Object {
\\"end\\": Infinity, @@ -215,14 +229,18 @@
\\"start\\": 0,
@@ -213,14 +226,18 @@
\\"choices\\": Array [ \\"choices\\": Array [
\\"es5\\", \\"es5\\",
\\"none\\", \\"none\\",
@@ -783,7 +797,7 @@ exports[`CLI --support-info (stdout) 1`] = `
\\"interpreters\\": [\\"deno\\", \\"ts-node\\"], \\"interpreters\\": [\\"deno\\", \\"ts-node\\"],
\\"linguistLanguageId\\": 378, \\"linguistLanguageId\\": 378,
\\"name\\": \\"TypeScript\\", \\"name\\": \\"TypeScript\\",
\\"parsers\\": [\\"typescript\\"], \\"parsers\\": [\\"typescript\\", \\"babel-ts\\"],
\\"since\\": \\"1.4.0\\", \\"since\\": \\"1.4.0\\",
\\"tmScope\\": \\"source.ts\\", \\"tmScope\\": \\"source.ts\\",
\\"type\\": \\"programming\\", \\"type\\": \\"programming\\",
@@ -797,7 +811,7 @@ exports[`CLI --support-info (stdout) 1`] = `
\\"group\\": \\"TypeScript\\", \\"group\\": \\"TypeScript\\",
\\"linguistLanguageId\\": 94901924, \\"linguistLanguageId\\": 94901924,
\\"name\\": \\"TSX\\", \\"name\\": \\"TSX\\",
\\"parsers\\": [\\"typescript\\"], \\"parsers\\": [\\"typescript\\", \\"babel-ts\\"],
\\"since\\": \\"1.4.0\\", \\"since\\": \\"1.4.0\\",
\\"tmScope\\": \\"source.tsx\\", \\"tmScope\\": \\"source.tsx\\",
\\"type\\": \\"programming\\", \\"type\\": \\"programming\\",
@@ -1245,6 +1259,7 @@ exports[`CLI --support-info (stdout) 1`] = `
{ \\"description\\": \\"Flow\\", \\"value\\": \\"flow\\" }, { \\"description\\": \\"Flow\\", \\"value\\": \\"flow\\" },
{ \\"description\\": \\"JavaScript\\", \\"since\\": \\"1.16.0\\", \\"value\\": \\"babel\\" }, { \\"description\\": \\"JavaScript\\", \\"since\\": \\"1.16.0\\", \\"value\\": \\"babel\\" },
{ \\"description\\": \\"Flow\\", \\"since\\": \\"1.16.0\\", \\"value\\": \\"babel-flow\\" }, { \\"description\\": \\"Flow\\", \\"since\\": \\"1.16.0\\", \\"value\\": \\"babel-flow\\" },
{ \\"description\\": \\"TypeScript\\", \\"since\\": \\"2.0.0\\", \\"value\\": \\"babel-ts\\" },
{ {
\\"description\\": \\"TypeScript\\", \\"description\\": \\"TypeScript\\",
\\"since\\": \\"1.4.0\\", \\"since\\": \\"1.4.0\\",
+1
View File
@@ -38,6 +38,7 @@ export default function(parser) {
'declare type FetchPolicy = "cache-first" | "cache-and-network" | "network-only" | "cache-only"' 'declare type FetchPolicy = "cache-first" | "cache-and-network" | "network-only" | "cache-only"'
].join("\n"); ].join("\n");
case "typescript": case "typescript":
case "babel-ts":
return [ return [
"interface MyInterface {", "interface MyInterface {",
" foo(): string,", " foo(): string,",
+1
View File
@@ -40,6 +40,7 @@ function getMarkdownSyntax(options) {
case "babel-flow": case "babel-flow":
case "flow": case "flow":
return "jsx"; return "jsx";
case "babel-ts":
case "typescript": case "typescript":
return "tsx"; return "tsx";
case "json": case "json":
+4
View File
@@ -21,6 +21,10 @@ var parsers = {
importScriptOnce("lib/parser-babylon.js"); importScriptOnce("lib/parser-babylon.js");
return prettierPlugins.babylon.parsers["babel-flow"]; return prettierPlugins.babylon.parsers["babel-flow"];
}, },
get "babel-ts"() {
importScriptOnce("lib/parser-babylon.js");
return prettierPlugins.babylon.parsers["babel-ts"];
},
// backward compatibility // backward compatibility
get babylon() { get babylon() {
importScriptOnce("lib/parser-babylon.js"); importScriptOnce("lib/parser-babylon.js");