Skip to content

Commit 0a5f533

Browse files
author
Orta Therox
authored
Retains trailing cmments in a logical manner in extract type (microsoft#40245)
1 parent e350c35 commit 0a5f533

File tree

3 files changed

+82
-3
lines changed

3 files changed

+82
-3
lines changed

src/services/refactors/extractType.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ namespace ts.refactor {
190190
selection
191191
);
192192
changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true);
193-
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
193+
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.ExcludeWhitespace });
194194
}
195195

196196
function doInterfaceChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: InterfaceInfo) {
@@ -204,8 +204,9 @@ namespace ts.refactor {
204204
/* heritageClauses */ undefined,
205205
typeElements
206206
);
207+
setTextRange(newTypeNode, typeElements[0]?.parent);
207208
changes.insertNodeBefore(file, firstStatement, ignoreSourceNewlines(newTypeNode), /* blankLineBetween */ true);
208-
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))));
209+
changes.replaceNode(file, selection, factory.createTypeReferenceNode(name, typeParameters.map(id => factory.createTypeReferenceNode(id.name, /* typeArguments */ undefined))), { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude, trailingTriviaOption: textChanges.TrailingTriviaOption.ExcludeWhitespace });
209210
}
210211

211212
function doTypedefChange(changes: textChanges.ChangeTracker, file: SourceFile, name: string, info: Info) {

src/services/textChanges.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ namespace ts.textChanges {
5656
export enum TrailingTriviaOption {
5757
/** Exclude all trailing trivia (use getEnd()) */
5858
Exclude,
59+
/** Doesn't include whitespace, but does strip comments */
60+
ExcludeWhitespace,
5961
/** Include trailing trivia */
6062
Include,
6163
}
@@ -209,10 +211,19 @@ namespace ts.textChanges {
209211
function getAdjustedEndPosition(sourceFile: SourceFile, node: Node, options: ConfigurableEnd) {
210212
const { end } = node;
211213
const { trailingTriviaOption } = options;
212-
if (trailingTriviaOption === TrailingTriviaOption.Exclude || (isExpression(node) && trailingTriviaOption !== TrailingTriviaOption.Include)) {
214+
if (trailingTriviaOption === TrailingTriviaOption.Exclude) {
215+
return end;
216+
}
217+
if (trailingTriviaOption === TrailingTriviaOption.ExcludeWhitespace) {
218+
const comments = concatenate(getTrailingCommentRanges(sourceFile.text, end), getLeadingCommentRanges(sourceFile.text, end));
219+
const realEnd = comments?.[comments.length - 1]?.end;
220+
if (realEnd) {
221+
return realEnd;
222+
}
213223
return end;
214224
}
215225
const newEnd = skipTrivia(sourceFile.text, end, /*stopAfterLineBreak*/ true);
226+
216227
return newEnd !== end && (trailingTriviaOption === TrailingTriviaOption.Include || isLineBreak(sourceFile.text.charCodeAt(newEnd - 1)))
217228
? newEnd
218229
: end;
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/// <reference path='fourslash.ts' />
2+
/// Doesn't duplicate comments - #31629
3+
4+
//// type a = /*a*/{ x: string } /* foo */ | string /* bar *//*b*/;
5+
//// type b = /*c*//* leading */{ x: string } /* trailing *//*d*/;
6+
//// type c = /*e*/{ x: string } /* inner */ | string// trailing/*f*/
7+
////
8+
9+
goTo.select("a", "b");
10+
edit.applyRefactor({
11+
refactorName: "Extract type",
12+
actionName: "Extract to type alias",
13+
actionDescription: "Extract to type alias",
14+
newContent: `type /*RENAME*/NewType = {
15+
x: string;
16+
} /* foo */ | string /* bar */;
17+
18+
type a = NewType;
19+
type b = /* leading */{ x: string } /* trailing */;
20+
type c = { x: string } /* inner */ | string// trailing
21+
`,
22+
});
23+
24+
// Extract to interface
25+
goTo.select("c", "d");
26+
edit.applyRefactor({
27+
refactorName: "Extract type",
28+
actionName: "Extract to interface",
29+
actionDescription: "Extract to interface",
30+
newContent: `type NewType = {
31+
x: string;
32+
} /* foo */ | string /* bar */;
33+
34+
type a = NewType;
35+
interface /*RENAME*/NewType_1 {
36+
x: string;
37+
} /* trailing */
38+
39+
type b = /* leading */NewType_1;
40+
type c = { x: string } /* inner */ | string// trailing
41+
`,
42+
});
43+
44+
// Trailing comment using '//'
45+
goTo.select("e", "f");
46+
edit.applyRefactor({
47+
refactorName: "Extract type",
48+
actionName: "Extract to type alias",
49+
actionDescription: "Extract to type alias",
50+
newContent: `type NewType = {
51+
x: string;
52+
} /* foo */ | string /* bar */;
53+
54+
type a = NewType;
55+
interface NewType_1 {
56+
x: string;
57+
} /* trailing */
58+
59+
type b = /* leading */NewType_1;
60+
type /*RENAME*/NewType_2 = {
61+
x: string;
62+
} /* inner */ | string // trailing
63+
;
64+
65+
type c = NewType_2
66+
`,
67+
});

0 commit comments

Comments
 (0)