Skip to content

Commit

Permalink
fix(javascript): fix locEnd for VariableDeclaration caused by --no-se…
Browse files Browse the repository at this point in the history
…mi (#5434)
  • Loading branch information
ikatyang committed Nov 10, 2018
1 parent 1ce7629 commit 7e72889
Show file tree
Hide file tree
Showing 6 changed files with 90 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/language-js/parser-babylon.js
Expand Up @@ -3,6 +3,7 @@
const createError = require("../common/parser-create-error");
const hasPragma = require("./pragma").hasPragma;
const locFns = require("./loc");
const postprocess = require("./postprocess");

function babylonOptions(extraOptions, extraPlugins) {
return Object.assign(
Expand Down Expand Up @@ -74,7 +75,7 @@ function parse(text, parsers, opts) {
);
}
delete ast.tokens;
return ast;
return postprocess(ast, Object.assign({}, opts, { originalText: text }));
}

function tryCombinations(fn, combinations) {
Expand Down
5 changes: 3 additions & 2 deletions src/language-js/parser-flow.js
Expand Up @@ -4,8 +4,9 @@ const createError = require("../common/parser-create-error");
const includeShebang = require("../common/parser-include-shebang");
const hasPragma = require("./pragma").hasPragma;
const locFns = require("./loc");
const postprocess = require("./postprocess");

function parse(text /*, parsers, opts*/) {
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
Expand All @@ -28,7 +29,7 @@ function parse(text /*, parsers, opts*/) {
}

includeShebang(text, ast);
return ast;
return postprocess(ast, Object.assign({}, opts, { originalText: text }));
}

// Export as a plugin so we can reuse the same bundle for UMD loading
Expand Down
5 changes: 3 additions & 2 deletions src/language-js/parser-typescript.js
Expand Up @@ -4,8 +4,9 @@ const createError = require("../common/parser-create-error");
const includeShebang = require("../common/parser-include-shebang");
const hasPragma = require("./pragma").hasPragma;
const locFns = require("./loc");
const postprocess = require("./postprocess");

function parse(text /*, parsers, opts*/) {
function parse(text, parsers, opts) {
const jsx = isProbablyJsx(text);
let ast;
try {
Expand All @@ -31,7 +32,7 @@ function parse(text /*, parsers, opts*/) {

delete ast.tokens;
includeShebang(text, ast);
return ast;
return postprocess(ast, Object.assign({}, opts, { originalText: text }));
}

function tryParseTypeScript(text, jsx) {
Expand Down
70 changes: 70 additions & 0 deletions src/language-js/postprocess.js
@@ -0,0 +1,70 @@
"use strict";

const { getLast } = require("../common/util");

// fix unexpected locEnd caused by --no-semi style
function postprocess(ast, options) {
visitNode(ast, node => {
switch (node.type) {
case "VariableDeclaration": {
const lastDeclaration = getLast(node.declarations);
if (lastDeclaration && lastDeclaration.init) {
overrideLocEnd(node, lastDeclaration);
}
break;
}
}
});

return ast;

/**
* - `toOverrideNode` must be the last thing in `toBeOverriddenNode`
* - do nothing if there's a semicolon on `toOverrideNode.end` (no need to fix)
*/
function overrideLocEnd(toBeOverriddenNode, toOverrideNode) {
if (options.originalText[locEnd(toOverrideNode)] === ";") {
return;
}
if (options.parser === "flow") {
toBeOverriddenNode.range = [
toBeOverriddenNode.range[0],
toOverrideNode.range[1]
];
} else {
toBeOverriddenNode.end = toOverrideNode.end;
}
toBeOverriddenNode.loc = Object.assign({}, toBeOverriddenNode.loc, {
end: toBeOverriddenNode.loc.end
});
}

function locEnd(node) {
return options.parser === "flow" ? node.range[1] : node.end;
}
}

function visitNode(node, fn) {
if (!node || typeof node !== "object") {
return;
}

if (Array.isArray(node)) {
for (const subNode of node) {
visitNode(subNode, fn);
}
return;
}

if (typeof node.type !== "string") {
return;
}

for (const key of Object.keys(node)) {
visitNode(node[key], fn);
}

fn(node);
}

module.exports = postprocess;
8 changes: 8 additions & 0 deletions tests/comments/__snapshots__/jsfmt.spec.js.snap
Expand Up @@ -2057,6 +2057,10 @@ let // Comment
let // Comment
foo = 'val',
bar = 'val';
const foo = 123
// Nothing to see here.
;["2", "3"].forEach(x => console.log(x))
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
let obj =
// Comment
Expand Down Expand Up @@ -2127,6 +2131,10 @@ let // Comment
foo = "val",
bar = "val";
const foo = 123;
// Nothing to see here.
["2", "3"].forEach(x => console.log(x));
`;
exports[`while.js - flow-verify 1`] = `
Expand Down
4 changes: 4 additions & 0 deletions tests/comments/variable_declarator.js
Expand Up @@ -60,3 +60,7 @@ let // Comment
let // Comment
foo = 'val',
bar = 'val';

const foo = 123
// Nothing to see here.
;["2", "3"].forEach(x => console.log(x))

0 comments on commit 7e72889

Please sign in to comment.