From 74fc539e1acb87822e1fbe84a8e23442484e7c55 Mon Sep 17 00:00:00 2001 From: James Long Date: Mon, 9 Jan 2017 21:24:42 -0500 Subject: [PATCH] Fix usage with the Flow parser --- src/comments.js | 19 ++++++----- src/printer.js | 5 +-- src/util.js | 83 +++++++++++++++++++++++++++++++++++-------------- 3 files changed, 72 insertions(+), 35 deletions(-) diff --git a/src/comments.js b/src/comments.js index 3ae0c87e..617b2969 100644 --- a/src/comments.js +++ b/src/comments.js @@ -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) ]); } diff --git a/src/printer.js b/src/printer.js index 60c0936c..bc745a7b 100644 --- a/src/printer.js +++ b/src/printer.js @@ -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) { diff --git a/src/util.js b/src/util.js index 4f9ed1a8..17efffca 100644 --- a/src/util.js +++ b/src/util.js @@ -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;