Skip to content

Commit 6e272f3

Browse files
committed
Progress
1 parent c689617 commit 6e272f3

15 files changed

+40
-33
lines changed

src/compiler/emitter.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,7 @@ namespace ts {
842842
let tempFlags: TempFlags; // TempFlags for the current name generation scope.
843843
let reservedNamesStack: Map<true>[]; // Stack of TempFlags reserved in enclosing name generation scopes.
844844
let reservedNames: Map<true>; // TempFlags to reserve in nested name generation scopes.
845+
let preserveNewlines = printerOptions.preserveNewlines; // Can be overridden inside nodes with the `IgnoreSourceNewlines` emit flag.
845846

846847
let writer: EmitTextWriter;
847848
let ownWriter: EmitTextWriter; // Reusable `EmitTextWriter` for basic printing.
@@ -1164,8 +1165,12 @@ namespace ts {
11641165
function pipelineEmit(emitHint: EmitHint, node: Node) {
11651166
const savedLastNode = lastNode;
11661167
const savedLastSubstitution = lastSubstitution;
1168+
const savedPreserveNewlines = preserveNewlines;
11671169
lastNode = node;
11681170
lastSubstitution = undefined;
1171+
if (preserveNewlines && !!(getEmitFlags(node) & EmitFlags.IgnoreSourceNewlines)) {
1172+
preserveNewlines = false;
1173+
}
11691174

11701175
const pipelinePhase = getPipelinePhase(PipelinePhase.Notification, emitHint, node);
11711176
pipelinePhase(emitHint, node);
@@ -1175,6 +1180,7 @@ namespace ts {
11751180
const substitute = lastSubstitution;
11761181
lastNode = savedLastNode;
11771182
lastSubstitution = savedLastSubstitution;
1183+
preserveNewlines = savedPreserveNewlines;
11781184

11791185
return substitute || node;
11801186
}
@@ -3991,7 +3997,7 @@ namespace ts {
39913997

39923998
if (isEmpty) {
39933999
// Write a line terminator if the parent node was multi-line
3994-
if (format & ListFormat.MultiLine) {
4000+
if (format & ListFormat.MultiLine && !(preserveNewlines && rangeIsOnSingleLine(parentNode, currentSourceFile!))) {
39954001
writeLine();
39964002
}
39974003
else if (format & ListFormat.SpaceBetweenBraces && !(format & ListFormat.NoSpaceIfEmpty)) {
@@ -4262,7 +4268,7 @@ namespace ts {
42624268
}
42634269

42644270
function getLeadingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat): number {
4265-
if (format & ListFormat.PreserveLines || printerOptions.preserveNewlines) {
4271+
if (format & ListFormat.PreserveLines || preserveNewlines) {
42664272
if (format & ListFormat.PreferNewLine) {
42674273
return 1;
42684274
}
@@ -4283,7 +4289,7 @@ namespace ts {
42834289
}
42844290

42854291
function getSeparatingLineTerminatorCount(previousNode: Node | undefined, nextNode: Node, format: ListFormat): number {
4286-
if (format & ListFormat.PreserveLines || printerOptions.preserveNewlines) {
4292+
if (format & ListFormat.PreserveLines || preserveNewlines) {
42874293
if (previousNode === undefined || nextNode === undefined) {
42884294
return 0;
42894295
}
@@ -4302,7 +4308,7 @@ namespace ts {
43024308
}
43034309

43044310
function getClosingLineTerminatorCount(parentNode: TextRange, children: NodeArray<Node>, format: ListFormat): number {
4305-
if (format & ListFormat.PreserveLines || printerOptions.preserveNewlines) {
4311+
if (format & ListFormat.PreserveLines || preserveNewlines) {
43064312
if (format & ListFormat.PreferNewLine) {
43074313
return 1;
43084314
}

src/compiler/factoryPublic.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3559,6 +3559,11 @@ namespace ts {
35593559
return node;
35603560
}
35613561

3562+
export function ignoreSourceNewlines<T extends Node>(node: T): T {
3563+
getOrCreateEmitNode(node).flags |= EmitFlags.IgnoreSourceNewlines;
3564+
return node;
3565+
}
3566+
35623567
/**
35633568
* Gets the constant value to emit for an expression.
35643569
*/

src/compiler/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5780,6 +5780,7 @@ namespace ts {
57805780
NoAsciiEscaping = 1 << 24, // When synthesizing nodes that lack an original node or textSourceNode, we want to write the text on the node with ASCII escaping substitutions.
57815781
/*@internal*/ TypeScriptClassWrapper = 1 << 25, // The node is an IIFE class wrapper created by the ts transform.
57825782
/*@internal*/ NeverApplyImportHelper = 1 << 26, // Indicates the node should never be wrapped with an import star helper (because, for example, it imports tslib itself)
5783+
/*@internal*/ IgnoreSourceNewlines = 1 << 27, // Overrides `printerOptions.preserveNewlines` to print this node (and all descendants) with default whitespace.
57835784
}
57845785

57855786
export interface EmitHelper {

src/services/formatting/formatting.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ namespace ts.formatting {
7070
* Formatter calls this function when rule adds or deletes new lines from the text
7171
* so indentation scope can adjust values of indentation and delta.
7272
*/
73-
recomputeIndentation(lineAddedByFormatting: boolean): void;
73+
recomputeIndentation(lineAddedByFormatting: boolean, parent: Node): void;
7474
}
7575

7676
export function formatOnEnter(position: number, sourceFile: SourceFile, formatContext: FormatContext): TextChange[] {
@@ -565,8 +565,9 @@ namespace ts.formatting {
565565
!suppressDelta && shouldAddDelta(line, kind, container) ? indentation + getDelta(container) : indentation,
566566
getIndentation: () => indentation,
567567
getDelta,
568-
recomputeIndentation: lineAdded => {
569-
if (node.parent && SmartIndenter.shouldIndentChildNode(options, node.parent, node, sourceFile)) {
568+
recomputeIndentation: (lineAdded, parentIn) => {
569+
const parent = node.parent || parentIn;
570+
if (node !== parent && SmartIndenter.shouldIndentChildNode(options, parent, node, sourceFile)) {
570571
indentation += lineAdded ? options.indentSize! : -options.indentSize!;
571572
delta = SmartIndenter.shouldIndentChildNode(options, node) ? options.indentSize! : 0;
572573
}
@@ -991,15 +992,15 @@ namespace ts.formatting {
991992
// Handle the case where the next line is moved to be the end of this line.
992993
// In this case we don't indent the next line in the next pass.
993994
if (currentParent.getStart(sourceFile) === currentItem.pos) {
994-
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false);
995+
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ false, currentParent);
995996
}
996997
break;
997998
case LineAction.LineAdded:
998999
// Handle the case where token2 is moved to the new line.
9991000
// In this case we indent token2 in the next pass but we set
10001001
// sameLineIndent flag to notify the indenter that the indentation is within the line.
10011002
if (currentParent.getStart(sourceFile) === currentItem.pos) {
1002-
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true);
1003+
dynamicIndentation.recomputeIndentation(/*lineAddedByFormatting*/ true, currentParent);
10031004
}
10041005
break;
10051006
default:

src/services/refactors/extractType.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ namespace ts.refactor {
159159
typeParameters.map(id => updateTypeParameterDeclaration(id, id.name, id.constraint, /* defaultType */ undefined)),
160160
selection
161161
);
162-
changes.insertNodeBefore(file, firstStatement, newTypeNode, /* blankLineBetween */ true);
162+
changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true);
163163
changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
164164
}
165165

@@ -174,7 +174,7 @@ namespace ts.refactor {
174174
/* heritageClauses */ undefined,
175175
typeElements
176176
);
177-
changes.insertNodeBefore(file, firstStatement, newTypeNode, /* blankLineBetween */ true);
177+
changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true);
178178
changes.replaceNode(file, selection, createTypeReferenceNode(name, typeParameters.map(id => createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
179179
}
180180

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4359,6 +4359,7 @@ declare namespace ts {
43594359
function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[] | undefined): T;
43604360
function addSyntheticTrailingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T;
43614361
function moveSyntheticComments<T extends Node>(node: T, original: Node): T;
4362+
function ignoreSourceNewlines<T extends Node>(node: T): T;
43624363
/**
43634364
* Gets the constant value to emit for an expression.
43644365
*/

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4359,6 +4359,7 @@ declare namespace ts {
43594359
function setSyntheticTrailingComments<T extends Node>(node: T, comments: SynthesizedComment[] | undefined): T;
43604360
function addSyntheticTrailingComment<T extends Node>(node: T, kind: SyntaxKind.SingleLineCommentTrivia | SyntaxKind.MultiLineCommentTrivia, text: string, hasTrailingNewLine?: boolean): T;
43614361
function moveSyntheticComments<T extends Node>(node: T, original: Node): T;
4362+
function ignoreSourceNewlines<T extends Node>(node: T): T;
43624363
/**
43634364
* Gets the constant value to emit for an expression.
43644365
*/

tests/baselines/reference/objectLiteralShorthandPropertiesErrorFromNotUsingIdentifier.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ var y = {
3535
"typeof":
3636
};
3737
var x = (_a = {
38-
a: a, : .b,
38+
a: a,
39+
: .b,
3940
a: a
4041
},
4142
_a["ss"] = ,

tests/baselines/reference/objectLiteralShorthandPropertiesErrorWithModule.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ var n;
2525
(function (n) {
2626
var z = 10000;
2727
n.y = {
28-
m: m, : .x // error
28+
m: m,
29+
: .x // error
2930
};
3031
})(n || (n = {}));
3132
m.y.x;

tests/baselines/reference/objectTypesWithOptionalProperties2.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,6 @@ var C2 = /** @class */ (function () {
4242
return C2;
4343
}());
4444
var b = {
45-
x: function () { }, 1: // error
45+
x: function () { },
46+
1: // error
4647
};

tests/baselines/reference/parserErrorRecovery_ObjectLiteral2.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,4 @@ var v = { a
33
return;
44

55
//// [parserErrorRecovery_ObjectLiteral2.js]
6-
var v = { a: a,
7-
"return": };
6+
var v = { a: a, "return": };

tests/cases/fourslash/extract-const-callback-function-this3.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ edit.applyRefactor({
1010
actionDescription: "Extract to constant in enclosing scope",
1111
newContent:
1212
`declare function fWithThis(fn: (this: { a: string }, a: string) => string): void;
13-
const newLocal = function(this: {
14-
a: string;
15-
}, a: string): string { return this.a; };
13+
const newLocal = function(this: { a: string; }, a: string): string { return this.a; };
1614
fWithThis(/*RENAME*/newLocal);`
1715
});

tests/cases/fourslash/moveToNewFile_declarationKinds.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,11 @@ type U = T; type V = I;`,
2424
"/x.ts":
2525
`export const x = 0;
2626
export function f() { }
27-
export class C {
28-
}
29-
export enum E {
30-
}
31-
export namespace N {
32-
export const x = 0;
33-
}
27+
export class C { }
28+
export enum E { }
29+
export namespace N { export const x = 0; }
3430
export type T = number;
35-
export interface I {
36-
}
31+
export interface I { }
3732
`,
3833
},
3934
});

tests/cases/fourslash/refactorConvertToEs6Module_export_object.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,5 @@ verify.codeFix({
2222
export function f() { }
2323
export function g() { }
2424
export function h() { }
25-
export class C {
26-
}`,
25+
export class C { }`,
2726
});

tests/cases/fourslash/refactorConvertToEs6Module_expressionToDeclaration.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,6 @@ verify.codeFix({
1515
`var C = {};
1616
console.log(C);
1717
export async function* f(p) { p; }
18-
const _C = class C extends D {
19-
m() { }
20-
};
18+
const _C = class C extends D { m() { } };
2119
export { _C as C };`,
2220
});

0 commit comments

Comments
 (0)