Cherry-pick PR #44070 into release-4.3 (#44187)

Component commits:
d1920805b0 Do not incorrectly add line separators for non-synthetic nodes when emitting node list
As of 3c32f6e154, a line separator is
added between nodes if the nodes are not synthetic and on separate
lines. This it push s wrong and previously only happened if the non-synthetic
nodes were on different lines but had the same parent.

Fixes #44068.

Co-authored-by: Paul Gschwendtner <paulgschwendtner@gmail.com>
This commit is contained in:
TypeScript Bot
2021-06-16 15:28:44 -07:00
committed by GitHub
co-authored by Paul Gschwendtner
parent 60f6d7bb34
commit 419f1e7fe8
10 changed files with 61 additions and 24 deletions
+27 -14
View File
@@ -4564,16 +4564,26 @@ namespace ts {
// JsxText will be written with its leading whitespace, so don't add more manually.
return 0;
}
else if (preserveSourceNewlines && siblingNodePositionsAreComparable(previousNode, nextNode)) {
return getEffectiveLines(
includeComments => getLinesBetweenRangeEndAndRangeStart(
previousNode,
nextNode,
currentSourceFile!,
includeComments));
}
else if (!preserveSourceNewlines && !nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) {
return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile!) ? 0 : 1;
else if (!nodeIsSynthesized(previousNode) && !nodeIsSynthesized(nextNode)) {
if (preserveSourceNewlines && siblingNodePositionsAreComparable(previousNode, nextNode)) {
return getEffectiveLines(
includeComments => getLinesBetweenRangeEndAndRangeStart(
previousNode,
nextNode,
currentSourceFile!,
includeComments));
}
// If `preserveSourceNewlines` is `false` we do not intend to preserve the effective lines between the
// previous and next node. Instead we naively check whether nodes are on separate lines within the
// same node parent. If so, we intend to preserve a single line terminator. This is less precise and
// expensive than checking with `preserveSourceNewlines` as above, but the goal is not to preserve the
// effective source lines between two sibling nodes.
else if (!preserveSourceNewlines && originalNodesHaveSameParent(previousNode, nextNode)) {
return rangeEndIsOnSameLineAsRangeStart(previousNode, nextNode, currentSourceFile!) ? 0 : 1;
}
// If the two nodes are not comparable, add a line terminator based on the format that can indicate
// whether new lines are preferred or not.
return format & ListFormat.PreferNewLine ? 1 : 0;
}
else if (synthesizedNodeStartsOnNewLine(previousNode, format) || synthesizedNodeStartsOnNewLine(nextNode, format)) {
return 1;
@@ -5300,11 +5310,14 @@ namespace ts {
}
function siblingNodePositionsAreComparable(previousNode: Node, nextNode: Node) {
if (nodeIsSynthesized(previousNode) || nodeIsSynthesized(nextNode)) {
return false;
}
function originalNodesHaveSameParent(nodeA: Node, nodeB: Node) {
nodeA = getOriginalNode(nodeA);
// For performance, do not call `getOriginalNode` for `nodeB` if `nodeA` doesn't even
// have a parent node.
return nodeA.parent && nodeA.parent === getOriginalNode(nodeB).parent;
}
function siblingNodePositionsAreComparable(previousNode: Node, nextNode: Node) {
if (nextNode.pos < previousNode.end) {
return false;
}
+20
View File
@@ -154,6 +154,26 @@ namespace ts {
}).outputText;
});
testBaseline("issue44068", () => {
return transformSourceFile(`
const FirstVar = null;
const SecondVar = null;
`, [
context => file => {
const firstVarName = (file.statements[0] as VariableStatement)
.declarationList.declarations[0].name as Identifier;
const secondVarName = (file.statements[0] as VariableStatement)
.declarationList.declarations[0].name as Identifier;
return context.factory.updateSourceFile(file, file.statements.concat([
context.factory.createExpressionStatement(
context.factory.createArrayLiteralExpression([firstVarName, secondVarName])
),
]));
}
]);
});
testBaseline("rewrittenNamespace", () => {
return transpileModule(`namespace Reflect { const x = 1; }`, {
transformers: {