Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 101 additions & 13 deletions escodegen.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,60 @@
return len && esutils.code.isLineTerminator(str.charCodeAt(len - 1));
}

function removeComments(str) {
// https://stackoverflow.com/a/59094308
return str.replace(/\/\*[\s\S]*?\*\/|\/\/.*/g, '');
}

function removeTrailingWhiteSpaces(str) {
return str.replace(/\S(\s+)$/g, '');
}

function isParenthesized(str, leftPar, rightPar) {
str = removeComments(str);
str = removeTrailingWhiteSpaces(str);
var counter = 0;
for (var i = 0; i < str.length; ++i) {
if (str[i] == leftPar) {
counter++;
}
else if (str[i] == rightPar) {
if (counter == 0) {
return false;
}
counter--;
}
}
return counter == 0 && str[str.length-1] == rightPar;
}

function isParenthesizedByAnyBracketKind(str) {
return isParenthesized(str, '(', ')') ||
isParenthesized(str, '{', '}') ||
isParenthesized(str, '[', ']');
}

function shouldParenthesize(str, parent) {
if (!hasLineTerminator(str)) {
return false;
}
if (parent !== undefined && (
parent.type == Syntax.ObjectExpression ||
parent.type == Syntax.ArrayExpression ||
parent.type == Syntax.Property
)) {
return false;
}
if (!isParenthesizedByAnyBracketKind(str)) {
return true;
}

str = removeComments(str);
var firstNewlineIdx = str.indexOf(newline);
var firstParenthesisIdx = str.match(/[\(\[\{)]/).index;
return firstNewlineIdx < firstParenthesisIdx;
}

function merge(target, override) {
var key;
for (key in override) {
Expand Down Expand Up @@ -570,6 +624,18 @@
return [base, stmt];
}

function addMultiLineIndent(stmt) {
var str = base + flattenToString(stmt);
var split = str.split(/\n/g);
var suffix = '';
// do not replace the last newline
if (split[split.length-1].length == 0) {
split = split.slice(0, split.length-1);
suffix = newline;
}
return split.join(newline + base) + suffix;
}

function withIndent(fn) {
var previousBase;
previousBase = base;
Expand Down Expand Up @@ -659,7 +725,7 @@
return '/*' + comment.value + '*/';
}

function addComments(stmt, result) {
function addComments(stmt, result, parent) {
var i, len, comment, save, tailingToStatement, specialBase, fragment,
extRange, range, prevRange, prefix, infix, suffix, count;

Expand Down Expand Up @@ -703,10 +769,12 @@
} else {
comment = stmt.leadingComments[0];
result = [];

if (safeConcatenation && stmt.type === Syntax.Program && stmt.body.length === 0) {
result.push('\n');
}
result.push(generateComment(comment));

if (!endsWithLineTerminator(toSourceNodeWhenNeeded(result).toString())) {
result.push('\n');
}
Expand All @@ -721,7 +789,26 @@
}
}

result.push(addIndent(save));
if (!isExpression(stmt)) {
result.push(addIndent(save));
} else {
var text = toSourceNodeWhenNeeded(result).toString();
if (shouldParenthesize(text, parent)) {
withIndent(function () {
result = addMultiLineIndent(result);
});

result = ['(', newline, result];

withIndent(function () {
result.push(addMultiLineIndent(save));
});

result.push([newline, base, ')']);
} else {
result.push(addIndent(save));
}
}
}

if (stmt.trailingComments) {
Expand Down Expand Up @@ -977,14 +1064,14 @@
return result;
};

CodeGenerator.prototype.generatePropertyKey = function (expr, computed) {
CodeGenerator.prototype.generatePropertyKey = function (expr, computed, parent) {
var result = [];

if (computed) {
result.push('[');
}

result.push(this.generateExpression(expr, Precedence.Assignment, E_TTT));
result.push(this.generateExpression(expr, Precedence.Assignment, E_TTT, parent));

if (computed) {
result.push(']');
Expand Down Expand Up @@ -2095,7 +2182,7 @@
}
} else {
result.push(multiline ? indent : '');
result.push(that.generateExpression(expr.elements[i], Precedence.Assignment, E_TTT));
result.push(that.generateExpression(expr.elements[i], Precedence.Assignment, E_TTT, expr));
}
if (i + 1 < iz) {
result.push(',' + (multiline ? newline : space));
Expand Down Expand Up @@ -2155,7 +2242,7 @@
if (expr.kind === 'get' || expr.kind === 'set') {
return [
expr.kind, noEmptySpace(),
this.generatePropertyKey(expr.key, expr.computed),
this.generatePropertyKey(expr.key, expr.computed, expr),
this.generateFunctionBody(expr.value)
];
}
Expand All @@ -2164,19 +2251,19 @@
if (expr.value.type === "AssignmentPattern") {
return this.AssignmentPattern(expr.value, Precedence.Sequence, E_TTT);
}
return this.generatePropertyKey(expr.key, expr.computed);
return this.generatePropertyKey(expr.key, expr.computed, expr);
}

if (expr.method) {
return [
generateMethodPrefix(expr),
this.generatePropertyKey(expr.key, expr.computed),
this.generatePropertyKey(expr.key, expr.computed, expr),
this.generateFunctionBody(expr.value)
];
}

return [
this.generatePropertyKey(expr.key, expr.computed),
this.generatePropertyKey(expr.key, expr.computed, expr),
':' + space,
this.generateExpression(expr.value, Precedence.Assignment, E_TTT)
];
Expand All @@ -2191,7 +2278,7 @@
multiline = expr.properties.length > 1;

withIndent(function () {
fragment = that.generateExpression(expr.properties[0], Precedence.Sequence, E_TTT);
fragment = that.generateExpression(expr.properties[0], Precedence.Sequence, E_TTT, expr);
});

if (!multiline) {
Expand All @@ -2216,7 +2303,7 @@
result.push(',' + newline);
for (i = 1, iz = expr.properties.length; i < iz; ++i) {
result.push(indent);
result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT));
result.push(that.generateExpression(expr.properties[i], Precedence.Sequence, E_TTT, expr));
if (i + 1 < iz) {
result.push(',' + newline);
}
Expand Down Expand Up @@ -2484,7 +2571,7 @@

merge(CodeGenerator.prototype, CodeGenerator.Expression);

CodeGenerator.prototype.generateExpression = function (expr, precedence, flags) {
CodeGenerator.prototype.generateExpression = function (expr, precedence, flags, parent) {
var result, type;

type = expr.type || Syntax.Property;
Expand All @@ -2497,8 +2584,9 @@


if (extra.comment) {
result = addComments(expr, result);
result = addComments(expr, result, parent);
}

return toSourceNodeWhenNeeded(result, expr);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
let variable = (
// comment
3 + 3
);
let variable = (
// comment
3 + 3
);
let variable = (
/* comment */
3 + 3
);
let variable = (
/* comment
comment
comment
*/
3 + 3
);
let variable = (
// comment
/* comment */
// comment
3 + 3
);
let variable = (
// comment
3 + 3
);
let variable = (
// one
3 + 3
) - (
// two
(1 + 1)
);
function foo(a, b, c) {
return (
// comment
a >= b && a <= c || a === 42 || a === 666
);
}
function foo(a, b, c) {
return (
// comment
a >= b && a <= c
) || a === 42 || a === 666;
}
function foo(a, b, c) {
throw (
// comment
a >= b && a <= c || a === 42 || a === 666
);
}
let arrowFn = () => (
// comment
{
a: 1,
b: 2
}
);
var test = [
/**
* Test 2
*/
a,
/*
* Test 1
*/
2,
// Test 3
3 + 3
];
87 changes: 87 additions & 0 deletions test/comment/comment-as-first-element-in-parenthesis-expression.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
let variable = (
// comment
3+3
);

let variable = ( // comment
3+3
);

let variable = ( /* comment */
3+3
);

let variable = ( /* comment
comment
comment
*/
3+3
);

let variable = (
// comment
/* comment */
// comment
3+3
);

let variable = /* comment */ (
// comment
3+3
);

let variable = (
(
// one
3+3
) -
(
// two
1+1
)
);

function foo(a, b, c) {
return (
// comment
(a >= b && a <= c)
|| a === 42 || a === 666
);
}

function foo(a, b, c) {
return (
( // comment
a >= b &&
a <= c)
|| a === 42 || a === 666
);
}

function foo(a, b, c) {
throw (
// comment
(a >= b && a <= c)
|| a === 42 || a === 666
);
}

let arrowFn = () => (
// comment
{
a: 1, b: 2
}
);

var test = [
/**
* Test 2
*/
a,
/*
* Test 1
*/
2,
// Test 3
3+3
];