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
This commit is contained in:
1 parent
781ba9580a
commit
a78d1389f6
20 files changed
+74
-120
No files matched your search
@@ -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_
|
||||
|
||||
@@ -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":
|
||||
|
||||
+1
-2
@@ -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",
|
||||
|
||||
@@ -14,8 +14,7 @@ const parsers = [
|
||||
"typescript",
|
||||
"graphql",
|
||||
"postcss",
|
||||
"parse5",
|
||||
"json"
|
||||
"parse5"
|
||||
];
|
||||
|
||||
process.env.PATH += path.delimiter + path.join(rootDir, "node_modules", ".bin");
|
||||
|
||||
@@ -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 })
|
||||
);
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
+1
-1
@@ -22,7 +22,7 @@ const parsers = {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
get json() {
|
||||
return eval("require")("./parser-json");
|
||||
return eval("require")("./parser-babylon");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
+6
-3
@@ -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),
|
||||
|
||||
@@ -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": "" \\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,
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
{/*comment*/"K":"V"}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
//comment
|
||||
"K":"V"
|
||||
}
|
||||
@@ -3020,7 +3020,7 @@ var parsers = {
|
||||
return eval("require")("./parser-postcss");
|
||||
},
|
||||
get json() {
|
||||
return eval("require")("./parser-json");
|
||||
return eval("require")("./parser-babylon");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
var json = (function () {
|
||||
var commonjsGlobal$1 = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
||||
|
||||
function createError$1(e,t){const n=new SyntaxError(e+" ("+t.start.line+":"+t.start.column+")");return n.loc=t,n}function createCommonjsModule$$1(e,t){return t={exports:{}},e(t,t.exports),t.exports}function parse(e){const t=parse$1;try{const n=t(e);return toBabylon(n)}catch(e){const t=e.message.indexOf("\n"),n=e.message.slice(0,t),r=n.lastIndexOf(" "),o=n.slice(0,r),l=n.slice(r+1),a=l.split(":").map(Number);throw createError("(json-to-ast) "+o,{start:{line:a[0],column:a[1]}})}}function toBabylon(e){const t={type:{object:"ObjectExpression",property:"ObjectProperty",identifier:"json-identifier",array:"ArrayExpression"}[e.type],start:e.loc.start.offset,end:e.loc.end.offset,loc:e.loc};switch(e.type){case"object":return Object.assign(t,{properties:e.children.map(toBabylon)});case"property":return Object.assign(t,{key:toBabylon(e.key),value:toBabylon(e.value)});case"identifier":return Object.assign(t,{value:e.value});case"array":return Object.assign(t,{elements:e.children.map(toBabylon)});case"literal":{const n={String:"StringLiteral",Number:"NumericLiteral",Boolean:"BooleanLiteral"},r=JSON.parse(e.rawValue),o=null===r?"NullLiteral":n[r.constructor.name];return Object.assign(t,{type:o,value:r,extra:{raw:e.rawValue}})}}}var parserCreateError=createError$1; var commonjsGlobal$$1="undefined"!=typeof window?window:"undefined"!=typeof commonjsGlobal$1?commonjsGlobal$1:"undefined"!=typeof self?self:{}; var parse$1=createCommonjsModule$$1(function(e,t){!function(t,n){n(e);}(0,function(e){function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function r(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t);}function o(e,t,n){return e.split(/\n|\r\n?|\f/)[t-1]+"\n"+(new Array(n).join(" ")+"^")}function l(e){return e>="1"&&e<="9"}function a(e){return e>="0"&&e<="9"}function c(e){return a(e)||e>="a"&&e<="f"||e>="A"&&e<="F"}function s(e){return"e"===e||"E"===e}function u(e,t,n,r){var o=e.charAt(t);if("\r"===o)t++,n++,r=1,"\n"===e.charAt(t)&&t++;else if("\n"===o)t++,n++,r=1;else{if("\t"!==o&&" "!==o)return null;t++,r++;}return{index:t,line:n,column:r}}function i(e,t,n,r){var o=e.charAt(t);return o in x?{type:x[o],line:n,column:r+1,index:t+1,value:null}:null}function f(e,t,n,r){for(var o in S)if(S.hasOwnProperty(o)&&e.substr(t,o.length)===o){var l=S[o],a=l.type,c=l.value;return{type:a,line:n,column:r+o.length,index:t+o.length,value:c}}return null}function p(e,t,n,r){for(var o=t,l="",a=N._START_;t<e.length;){var s=e.charAt(t);switch(a){case N._START_:if('"'!==s)return null;a=N.START_QUOTE_OR_CHAR,t++;break;case N.START_QUOTE_OR_CHAR:if("\\"===s)a=N.ESCAPE,l+=s,t++;else{if('"'===s)return t++,{type:I.STRING,line:n,column:r+t-o,index:t,value:l};l+=s,t++;}break;case N.ESCAPE:if(!(s in k))return null;if(l+=s,t++,"u"===s)for(var u=0;u<4;u++){var i=e.charAt(t);if(!i||!c(i))return null;l+=i,t++;}a=N.START_QUOTE_OR_CHAR;}}}function T(e,t,n,r){var o=t,c=t,u=P._START_;e:for(;t<e.length;){var i=e.charAt(t);switch(u){case P._START_:if("-"===i)u=P.MINUS;else if("0"===i)c=t+1,u=P.ZERO;else{if(!l(i))return null;c=t+1,u=P.DIGIT;}break;case P.MINUS:if("0"===i)c=t+1,u=P.ZERO;else{if(!l(i))return null;c=t+1,u=P.DIGIT;}break;case P.ZERO:if("."===i)u=P.POINT;else{if(!s(i))break e;u=P.EXP;}break;case P.DIGIT:if(a(i))c=t+1;else if("."===i)u=P.POINT;else{if(!s(i))break e;u=P.EXP;}break;case P.POINT:if(!a(i))break e;c=t+1,u=P.DIGIT_FRACTION;break;case P.DIGIT_FRACTION:if(a(i))c=t+1;else{if(!s(i))break e;u=P.EXP;}break;case P.EXP:if("+"===i||"-"===i)u=P.EXP_DIGIT_OR_SIGN;else{if(!a(i))break e;c=t+1,u=P.EXP_DIGIT_OR_SIGN;}break;case P.EXP_DIGIT_OR_SIGN:if(!a(i))break e;c=t+1;}t++;}return c>0?{type:I.NUMBER,line:n,column:r+c-o,index:c,value:parseFloat(e.substring(o,c))}:null}function d(e,t){for(var n=1,r=1,o=0,l=[];o<e.length;){var a=[e,o,n,r],c=u.apply(void 0,a);if(c)o=c.index,n=c.line,r=c.column;else{var s=i.apply(void 0,a)||f.apply(void 0,a)||p.apply(void 0,a)||T.apply(void 0,a);if(s){var d={type:s.type,value:s.value,loc:b(n,r,o,s.line,s.column,s.index,t.source)};l.push(d),o=s.index,n=s.line,r=s.column;}else m(C.cannotTokenizeSymbol(e.charAt(o),n,r),e,n,r);}}return l}function v(e,t,n,r){for(var o=void 0,l={type:"object",children:[]},a=w._START_;n<t.length;){var c=t[n];switch(a){case w._START_:if(c.type!==I.LEFT_BRACE)return null;o=c,a=w.OPEN_OBJECT,n++;break;case w.OPEN_OBJECT:if(c.type===I.RIGHT_BRACE){if(r.verbose)return l.loc=b(o.loc.start.line,o.loc.start.column,o.loc.start.offset,c.loc.end.line,c.loc.end.column,c.loc.end.offset,r.source),{value:l,index:n+1}}else{var s=E(e,t,n,r);l.children.push(s.value),Line truncated
|
||||
|
||||
return parserJson_1;
|
||||
|
||||
}());
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
|
||||
Reference in new issue
Block a user