Allow formatting ranges of JSON (#2298)

* Add test for https://github.com/prettier/prettier/issues/2297

* Add JSON types to isSourceElement()

See https://github.com/prettier/prettier/issues/2297

* Avoid expanding format range when possible

This fixes https://github.com/prettier/prettier/issues/2297

* Move JSON range test into tests/range_json

This is so that the AST_COMPARE=1 tests don't try to parse JSON with Flow.

* Check parser in isSourceElement()

Otherwise JSON formatting would format weird things inside of JS.
See https://github.com/prettier/prettier/pull/2298#discussion_r124407056

* Use arrow functions instead of .bind()

See https://github.com/prettier/prettier/pull/2298#discussion_r124409783

* Add test of range-formatting JSON identifier

See https://github.com/prettier/prettier/pull/2298/files#r124410750

* Allow range-formatting JSON identifier

See https://github.com/prettier/prettier/pull/2298/files#r124410750

* Fix lint
master
Joseph Frazier 2017-06-27 19:04:42 -04:00 committed by Christopher Chedeau
parent 5f063ab168
commit b47c0b4e04
5 changed files with 38 additions and 9 deletions

View File

@ -103,6 +103,13 @@ function findSiblingAncestors(startNodeAndParents, endNodeAndParents) {
let resultStartNode = startNodeAndParents.node;
let resultEndNode = endNodeAndParents.node;
if (resultStartNode === resultEndNode) {
return {
startNode: resultStartNode,
endNode: resultEndNode
};
}
for (const endParent of endNodeAndParents.parentNodes) {
if (
endParent.type !== "Program" &&
@ -161,11 +168,19 @@ function findNodeAtOffset(node, offset, predicate, parentNodes) {
}
// See https://www.ecma-international.org/ecma-262/5.1/#sec-A.5
function isSourceElement(node) {
function isSourceElement(opts, node) {
if (node == null) {
return false;
}
switch (node.type) {
case "ObjectExpression": // JSON
case "ArrayExpression": // JSON
case "StringLiteral": // JSON
case "NumericLiteral": // JSON
case "BooleanLiteral": // JSON
case "NullLiteral": // JSON
case "json-identifier": // JSON
return opts.parser === "json";
case "FunctionDeclaration":
case "BlockStatement":
case "BreakStatement":
@ -219,15 +234,11 @@ function calculateRange(text, opts, ast) {
}
}
const startNodeAndParents = findNodeAtOffset(
ast,
startNonWhitespace,
isSourceElement
const startNodeAndParents = findNodeAtOffset(ast, startNonWhitespace, node =>
isSourceElement(opts, node)
);
const endNodeAndParents = findNodeAtOffset(
ast,
endNonWhitespace,
isSourceElement
const endNodeAndParents = findNodeAtOffset(ast, endNonWhitespace, node =>
isSourceElement(opts, node)
);
if (!startNodeAndParents || !endNodeAndParents) {

View File

@ -0,0 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`identifier.json 1`] = `
{"a":1, "b":2}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{"a":1, "b":2}
`;
exports[`issue2297.json 1`] = `
{"a":1, "b":2}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
{"a":1, "b":2}
`;

View File

@ -0,0 +1 @@
{<<<PRETTIER_RANGE_START>>>"a"<<<PRETTIER_RANGE_END>>>:1, "b":2}

View File

@ -0,0 +1 @@
{"a":<<<PRETTIER_RANGE_START>>>1<<<PRETTIER_RANGE_END>>>, "b":2}

View File

@ -0,0 +1 @@
run_spec(__dirname, { parser: "json" });