Use babylon.parseExpression for JSON (#2476)

* Add comments showing parser arguments

Since this is how they are invoked, the comments make it easier to maintain.

* Use babylon.parseExpression for JSON

See https://github.com/prettier/prettier/issues/2378#issuecomment-314600778

Note that this doesn't yet print comments:

    echo '{/*comment*/"K":"V"}' | ./bin/prettier.js --parser json

* Remove parser-json.js

This reduces duplicate code in the built package.
See https://github.com/prettier/prettier/pull/2476#pullrequestreview-50181398

* Add test with block comment in JSON

* Fix test with block comment in JSON

* Add test with line comment in JSON

* Don't build now-redundant parser-json.js
master
Joseph Frazier 2017-07-23 21:43:49 -04:00 committed by Lucas Azzola
parent 781ba9580a
commit a78d1389f6
20 changed files with 74 additions and 120 deletions

View File

@ -601,7 +601,7 @@ Built-in parsers:
* [`flow`](https://github.com/facebook/flow/tree/master/src/parser)
* [`typescript`](https://github.com/eslint/typescript-eslint-parser) _Since v1.4.0_
* [`postcss`](https://github.com/postcss/postcss) _Since v1.4.0_
* [`json`](https://github.com/vtrushin/json-to-ast) _Since v1.5.0_
* [`json`](https://github.com/babel/babylon/tree/f09eb3200f57ea94d51c2a5b1facf2149fb406bf#babylonparseexpressioncode-options) _Since v1.5.0_
* [`graphql`](https://github.com/graphql/graphql-js/tree/master/src/language) _Since v1.5.0_
[Custom parsers](#custom-parser-api) are also supported. _Since v1.5.0_

View File

@ -182,8 +182,6 @@ function isSourceElement(opts, node) {
case "NumericLiteral": // JSON
case "BooleanLiteral": // JSON
case "NullLiteral": // JSON
case "json-identifier": // JSON
return opts.parser === "json";
case "FunctionDeclaration":
case "BlockStatement":
case "BreakStatement":

View File

@ -12,7 +12,7 @@
"main": "./index.js",
"dependencies": {
"babel-code-frame": "7.0.0-alpha.12",
"babylon": "7.0.0-beta.13",
"babylon": "7.0.0-beta.17",
"chalk": "2.0.1",
"cosmiconfig": "2.1.3",
"dashify": "0.2.2",
@ -24,7 +24,6 @@
"graphql": "0.10.1",
"ignore": "^3.3.3",
"jest-validate": "20.0.3",
"json-to-ast": "2.0.0-alpha1.2",
"minimatch": "3.0.4",
"minimist": "1.2.0",
"parse5": "3.0.2",

View File

@ -14,8 +14,7 @@ const parsers = [
"typescript",
"graphql",
"postcss",
"parse5",
"json"
"parse5"
];
process.env.PATH += path.delimiter + path.join(rootDir, "node_modules", ".bin");

View File

@ -2,7 +2,7 @@
const createError = require("./parser-create-error");
function parse(text) {
function parse(text, parsers, opts) {
// Inline the require to avoid loading all the JS if we don't use it
const babylon = require("babylon");
@ -27,12 +27,15 @@ function parse(text) {
]
};
const parseMethod =
opts && opts.parser === "json" ? "parseExpression" : "parse";
let ast;
try {
ast = babylon.parse(text, babylonOptions);
ast = babylon[parseMethod](text, babylonOptions);
} catch (originalError) {
try {
ast = babylon.parse(
ast = babylon[parseMethod](
text,
Object.assign({}, babylonOptions, { strictMode: false })
);

View File

@ -3,7 +3,7 @@
const createError = require("./parser-create-error");
const includeShebang = require("./parser-include-shebang");
function parse(text) {
function parse(text /*, parsers, opts*/) {
// Fixes Node 4 issue (#1986)
"use strict"; // eslint-disable-line
// Inline the require to avoid loading all the JS if we don't use it

View File

@ -34,7 +34,7 @@ function removeTokens(node) {
return node;
}
function parse(text) {
function parse(text /*, parsers, opts*/) {
// Inline the require to avoid loading all the JS if we don't use it
const parser = require("graphql/language");
try {

View File

@ -1,82 +0,0 @@
"use strict";
const createError = require("./parser-create-error");
function parse(text) {
const jsonToAst = require("json-to-ast");
try {
const ast = jsonToAst(text);
return toBabylon(ast);
} catch (err) {
const firstNewlineIndex = err.message.indexOf("\n");
const firstLine = err.message.slice(0, firstNewlineIndex);
const lastSpaceIndex = firstLine.lastIndexOf(" ");
const message = firstLine.slice(0, lastSpaceIndex);
const locString = firstLine.slice(lastSpaceIndex + 1);
const lineCol = locString.split(":").map(Number);
throw createError("(json-to-ast) " + message, {
start: {
line: lineCol[0],
column: lineCol[1]
}
});
}
}
function toBabylon(node) {
const typeMap = {
object: "ObjectExpression",
property: "ObjectProperty",
identifier: "json-identifier",
array: "ArrayExpression"
};
const result = {
type: typeMap[node.type],
start: node.loc.start.offset,
end: node.loc.end.offset,
loc: node.loc
};
switch (node.type) {
case "object":
return Object.assign(result, {
properties: node.children.map(toBabylon)
});
case "property":
return Object.assign(result, {
key: toBabylon(node.key),
value: toBabylon(node.value)
});
case "identifier":
return Object.assign(result, {
value: node.value
});
case "array":
return Object.assign(result, {
elements: node.children.map(toBabylon)
});
case "literal": {
const constructorTypes = {
String: "StringLiteral",
Number: "NumericLiteral",
Boolean: "BooleanLiteral"
};
const value = JSON.parse(node.rawValue);
const type =
value === null
? "NullLiteral"
: constructorTypes[value.constructor.name];
return Object.assign(result, {
type: type,
value: value,
extra: { raw: node.rawValue }
});
}
}
}
module.exports = parse;

View File

@ -2,7 +2,7 @@
// const createError = require("./parser-create-error");
function parse(text) {
function parse(text /*, parsers, opts*/) {
// Inline the require to avoid loading all the JS if we don't use it
const parse5 = require("parse5");
try {

View File

@ -208,7 +208,7 @@ function requireParser(isSCSS) {
return require("postcss-less");
}
function parse(text) {
function parse(text /*, parsers, opts*/) {
const isLikelySCSS = !!text.match(/(\w\s*: [^}:]+|#){|@import[^\n]+(url|,)/);
try {
return parseWithParser(requireParser(isLikelySCSS), text);

View File

@ -3,7 +3,7 @@
const createError = require("./parser-create-error");
const includeShebang = require("./parser-include-shebang");
function parse(text) {
function parse(text /*, parsers, opts*/) {
const jsx = isProbablyJsx(text);
let ast;
try {

View File

@ -22,7 +22,7 @@ const parsers = {
return eval("require")("./parser-postcss");
},
get json() {
return eval("require")("./parser-json");
return eval("require")("./parser-babylon");
}
};

View File

@ -2636,8 +2636,6 @@ function genericPrintNoParens(path, options, print, args) {
return path.call(bodyPath => {
return printStatementSequence(bodyPath, options, print);
}, "body");
case "json-identifier":
return '"' + n.value + '"';
default:
/* istanbul ignore next */
@ -2709,7 +2707,12 @@ function printPropertyKey(path, options, print) {
const node = path.getNode();
const key = node.key;
if (isStringLiteral(key) && isIdentifierName(key.value) && !node.computed) {
if (
isStringLiteral(key) &&
isIdentifierName(key.value) &&
!node.computed &&
options.parser !== "json"
) {
// 'a' -> a
return path.call(
keyPath => comments.printComments(keyPath, () => key.value, options),

View File

@ -1,5 +1,19 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`block-comment.json 1`] = `
{/*comment*/"K":"V"}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ /*comment*/ "K": "V" }
`;
exports[`block-comment.json 2`] = `
{/*comment*/"K":"V"}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{ /*comment*/ "K": "V" }
`;
exports[`boolean.json 1`] = `
true
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -14,6 +28,32 @@ true
`;
exports[`line-comment.json 1`] = `
{
//comment
"K":"V"
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
//comment
"K": "V"
}
`;
exports[`line-comment.json 2`] = `
{
//comment
"K":"V"
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{
//comment
"K": "V"
}
`;
exports[`multi-line.json 1`] = `
{"key1":[true,false,null],"key2":{"key3":[1,2,"3",
1e10,1e-3]}}
@ -168,7 +208,8 @@ exports[`pass1.json 1`] = `
"compact": [1, 2, 3, 4, 5, 6, 7],
"jsontext": "{\\"object with 1 member\\":[\\"array with 1 element\\"]}",
"quotes": "" \\u0022 %22 0x22 034 "",
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string"
"/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?":
"A key can be any string"
},
0.5,
98.6,
@ -285,7 +326,8 @@ exports[`pass1.json 2`] = `
"compact": [1, 2, 3, 4, 5, 6, 7],
"jsontext": "{\\"object with 1 member\\":[\\"array with 1 element\\"]}",
"quotes": "&#34; \\u0022 %22 0x22 034 &#x22;",
"\\/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?": "A key can be any string"
"/\\\\\\"\\uCAFE\\uBABE\\uAB98\\uFCDE\\ubcda\\uef4A\\b\\f\\n\\r\\t\`1~!@#$%^&*()_+-=[]{}|;:',./<>?":
"A key can be any string"
},
0.5,
98.6,

View File

@ -0,0 +1 @@
{/*comment*/"K":"V"}

View File

@ -0,0 +1,4 @@
{
//comment
"K":"V"
}

View File

@ -3020,7 +3020,7 @@ var parsers = {
return eval("require")("./parser-postcss");
},
get json() {
return eval("require")("./parser-json");
return eval("require")("./parser-babylon");
}
};

File diff suppressed because one or more lines are too long

View File

@ -14,7 +14,6 @@ toolbox.precache([
"lib/parser-postcss.js",
"lib/parser-flow.js",
"lib/parser-graphql.js",
"lib/parser-json.js",
"playground.js",
"lib/sw-toolbox.js",
"lib/sw-toolbox-companion.js",

View File

@ -664,9 +664,9 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25
lodash "^4.2.0"
to-fast-properties "^1.0.1"
babylon@7.0.0-beta.13:
version "7.0.0-beta.13"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.13.tgz#12425c1bfd9498be419021ed36b43fe4f0289c0a"
babylon@7.0.0-beta.17:
version "7.0.0-beta.17"
resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.17.tgz#2aad4d6764f409dfb3ac216d855dc93d70d37911"
babylon@^6.13.0, babylon@^6.17.2:
version "6.17.3"
@ -2421,10 +2421,6 @@ json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
json-to-ast@2.0.0-alpha1.2:
version "2.0.0-alpha1.2"
resolved "https://registry.yarnpkg.com/json-to-ast/-/json-to-ast-2.0.0-alpha1.2.tgz#fe27fd89eb639eca1e01f578e79d46ee36e238e8"
json5@^0.5.0, json5@^0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"