Fix usage with the Flow parser

master
James Long 2017-01-09 21:24:42 -05:00
parent 27af6be07a
commit 74fc539e1a
3 changed files with 72 additions and 35 deletions

View File

@ -10,6 +10,8 @@ var hardline = pp.hardline;
var util = require("./util");
var comparePos = util.comparePos;
var childNodesCacheKey = require("private").makeUniqueKey();
var locStart = util.locStart;
var locEnd = util.locEnd;
// TODO Move a non-caching implementation of this function into ast-types,
// and implement a caching wrapper function here.
@ -28,7 +30,7 @@ function getSortedChildNodes(node, text, resultArray) {
// time because we almost always (maybe always?) append the
// nodes in order anyway.
for (var i = resultArray.length - 1; i >= 0; --i) {
if (resultArray[i].end - node.start <= 0) {
if (locEnd(resultArray[i]) - locStart(node) <= 0) {
break;
}
}
@ -74,13 +76,14 @@ function decorateComment(node, comment, text) {
var middle = (left + right) >> 1;
var child = childNodes[middle];
if (child.start - comment.start <= 0 && comment.end - child.end <= 0) {
if (locStart(child) - locStart(comment) <= 0 &&
locEnd(comment) - locEnd(child) <= 0) {
// The comment is completely contained by this child node.
decorateComment(comment.enclosingNode = child, comment, text);
return; // Abandon the binary search at this level.
}
if (child.end - comment.start <= 0) {
if (locEnd(child) - locStart(comment) <= 0) {
// This child node falls completely before the comment.
// Because we will never consider this node or any nodes
// before it again, this node must be the closest preceding
@ -90,7 +93,7 @@ function decorateComment(node, comment, text) {
continue;
}
if (comment.end - child.start <= 0) {
if (locEnd(comment) - locStart(child) <= 0) {
// This child node falls completely after the comment.
// Because we will never consider this node or any nodes after
// it again, this node must be the closest following node we
@ -184,7 +187,7 @@ function breakTies(tiesToBreak, text) {
var pn = tiesToBreak[0].precedingNode;
var fn = tiesToBreak[0].followingNode;
var gapEndPos = fn.start;
var gapEndPos = locStart(fn);
// Iterate backwards through tiesToBreak, examining the gaps
// between the tied comments. In order to qualify as leading, a
@ -197,13 +200,13 @@ function breakTies(tiesToBreak, text) {
assert.strictEqual(comment.precedingNode, pn);
assert.strictEqual(comment.followingNode, fn);
var gap = text.slice(comment.end, gapEndPos);
var gap = text.slice(locEnd(comment), gapEndPos);
if (/\S/.test(gap)) {
// The gap string contained something other than whitespace.
break;
}
gapEndPos = comment.start;
gapEndPos = locStart(comment);
}
// while (indexOfFirstLeadingComment <= tieCount &&
@ -261,7 +264,7 @@ function printTrailingComment(commentPath, print, options) {
const text = options.originalText;
return concat([
util.newlineExistsBefore(text, comment.start) ? hardline : " ",
util.newlineExistsBefore(text, locStart(comment)) ? hardline : " ",
print(commentPath)
]);
}

View File

@ -213,9 +213,6 @@ function genericPrintNoParens(path, options, print) {
)
);
// Make sure the file always ends with a newline
parts.push(hardline);
return concat(parts);
// Babel extension.
case "Noop":
@ -2013,7 +2010,7 @@ function nodeStr(str, options) {
function shouldAddSpacing(node, options) {
const text = options.originalText;
return util.newlineExistsAfter(text, node.end);
return util.newlineExistsAfter(text, util.locEnd(node));
}
function isFirstStatement(path) {

View File

@ -85,12 +85,12 @@ util.composeSourceMaps = function(formerMap, latterMap) {
};
function expandLoc(parentNode, childNode) {
if (childNode.start - parentNode.start < 0) {
parentNode.start = childNode.start;
if (locStart(childNode) - locStart(parentNode) < 0) {
setLocStart(parentNode, locStart(childNode));
}
if (parentNode.end - childNode.end < 0) {
parentNode.end = childNode.end;
if (locEnd(parentNode) - locEnd(childNode) < 0) {
setLocEnd(parentNode, locEnd(childNode));
}
}
@ -121,12 +121,12 @@ util.fixFaultyLocations = function(node, text) {
node.value.id = null;
}
} else if (node.type === "ObjectTypeProperty") {
var end = skipSpaces(text, node.end, true);
var end = skipSpaces(text, locEnd(node), true);
if (end !== false && text.charAt(end) === ",") {
// Some parsers accidentally include trailing commas in the
// .end information for ObjectTypeProperty nodes.
// end information for ObjectTypeProperty nodes.
if ((end = skipSpaces(text, end - 1, true)) !== false) {
loc.end = end;
setLocEnd(node, end)
}
}
}
@ -142,51 +142,52 @@ function fixTemplateLiteral(node, text) {
// First we need to exclude the opening ` from the loc of the first
// quasi element, in case the parser accidentally decided to include it.
var afterLeftBackTickPos = node.start;
var afterLeftBackTickPos = locStart(node);
assert.strictEqual(text.charAt(afterLeftBackTickPos), "`");
assert.ok(afterLeftBackTickPos < text.length);
var firstQuasi = node.quasis[0];
if (firstQuasi.start - afterLeftBackTickPos < 0) {
firstQuasi.start = afterLeftBackTickPos;
if (locStart(firstQuasi) - afterLeftBackTickPos < 0) {
setLocStart(firstQuasi, afterLeftBackTickPos);
}
// Next we need to exclude the closing ` from the loc of the last quasi
// element, in case the parser accidentally decided to include it.
var rightBackTickPos = node.end;
var rightBackTickPos = locEnd(node);
assert.ok(rightBackTickPos >= 0);
assert.strictEqual(text.charAt(rightBackTickPos), "`");
var lastQuasi = node.quasis[node.quasis.length - 1];
if (rightBackTickPos - lastQuasi.end < 0) {
lastQuasi.end = rightBackTickPos;
if (rightBackTickPos - locEnd(lastQuasi) < 0) {
setLocEnd(locEnd(lastQuasi), rightBackTickPos);
}
// Now we need to exclude ${ and } characters from the loc's of all
// quasi elements, since some parsers accidentally include them.
node.expressions.forEach(function (expr, i) {
// Rewind from expr.start over any whitespace and the ${ that
// precedes the expression. The position of the $ should be the same
// as the .end of the preceding quasi element, but some parsers
// accidentally include the ${ in the loc of the quasi element.
var dollarCurlyPos = skipSpaces(text, expr.start - 1, true);
// Rewind from the start loc over any whitespace and the ${ that
// precedes the expression. The position of the $ should be the
// same as the end of the preceding quasi element, but some
// parsers accidentally include the ${ in the loc of the quasi
// element.
var dollarCurlyPos = skipSpaces(text, locStart(expr) - 1, true);
if (dollarCurlyPos - 1 >= 0 &&
text.charAt(dollarCurlyPos - 1) === "{" &&
dollarCurlyPos - 2 >= 0 &&
text.charAt(dollarCurlyPos - 2) === "$") {
var quasiBefore = node.quasis[i];
if (dollarCurlyPos - quasiBefore.end < 0) {
quasiBefore.end = dollarCurlyPos;
if (dollarCurlyPos - locEnd(quasiBefore) < 0) {
setLocEnd(quasiBefore, dollarCurlyPos);
}
}
// Likewise, some parsers accidentally include the } that follows
// the expression in the loc of the following quasi element.
var rightCurlyPos = skipSpaces(text, expr.end);
var rightCurlyPos = skipSpaces(text, locEnd(expr));
if (text.charAt(rightCurlyPos) === "}") {
assert.ok(rightCurlyPos + 1 < text.length);
// Now rightCurlyPos is technically the position just after the }.
var quasiAfter = node.quasis[i + 1];
if (quasiAfter.start - rightCurlyPos < 0) {
quasiAfter.start = rightCurlyPos;
if (locStart(quasiAfter) - rightCurlyPos < 0) {
setLocStart(locStart(quasiAfter), rightCurlyPos);
}
}
});
@ -273,3 +274,39 @@ function skipSpaces(text, index, backwards) {
return false;
}
util.skipSpaces = skipSpaces;
function locStart(node) {
if(node.range) {
return node.range[0];
}
return node.start;
}
util.locStart = locStart;
function locEnd(node) {
if(node.range) {
return node.range[1];
}
return node.end;
}
util.locEnd = locEnd;
function setLocStart(node, index) {
if(node.range) {
node.range[0] = index;
}
else {
node.start = index;
}
}
util.setLocStart = setLocStart;
function setLocEnd(node, index) {
if(node.range) {
node.range[1] = index;
}
else {
node.end = index;
}
}
util.setLocEnd = setLocEnd;