Skip to content

Commit 60f93aa

Browse files
authored
Making Move To File Action appear less often (#57080)
1 parent 363abe8 commit 60f93aa

File tree

8 files changed

+76
-23
lines changed

8 files changed

+76
-23
lines changed

src/harness/fourslashImpl.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3979,8 +3979,8 @@ export class TestState {
39793979
};
39803980
}
39813981

3982-
public verifyRefactorAvailable(negative: boolean, triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string) {
3983-
let refactors = this.getApplicableRefactorsAtSelection(triggerReason);
3982+
public verifyRefactorAvailable(negative: boolean, triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string, kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) {
3983+
let refactors = this.getApplicableRefactorsAtSelection(triggerReason, kind, preferences, includeInteractiveActions);
39843984
refactors = refactors.filter(r => r.name === name);
39853985

39863986
if (actionName !== undefined) {
@@ -4445,8 +4445,8 @@ export class TestState {
44454445
test(renameKeys(newFileContents, key => pathUpdater(key) || key), "with file moved");
44464446
}
44474447

4448-
private getApplicableRefactorsAtSelection(triggerReason: ts.RefactorTriggerReason = "implicit", kind?: string, preferences = ts.emptyOptions) {
4449-
return this.getApplicableRefactorsWorker(this.getSelection(), this.activeFile.fileName, preferences, triggerReason, kind);
4448+
private getApplicableRefactorsAtSelection(triggerReason: ts.RefactorTriggerReason = "implicit", kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) {
4449+
return this.getApplicableRefactorsWorker(this.getSelection(), this.activeFile.fileName, preferences, triggerReason, kind, includeInteractiveActions);
44504450
}
44514451
private getApplicableRefactors(rangeOrMarker: Range | Marker, preferences = ts.emptyOptions, triggerReason: ts.RefactorTriggerReason = "implicit", kind?: string, includeInteractiveActions?: boolean): readonly ts.ApplicableRefactorInfo[] {
44524452
return this.getApplicableRefactorsWorker("position" in rangeOrMarker ? rangeOrMarker.position : rangeOrMarker, rangeOrMarker.fileName, preferences, triggerReason, kind, includeInteractiveActions); // eslint-disable-line local/no-in-operator

src/harness/fourslashInterfaceImpl.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -212,12 +212,12 @@ export class VerifyNegatable {
212212
this.state.verifyRefactorsAvailable(names);
213213
}
214214

215-
public refactorAvailable(name: string, actionName?: string, actionDescription?: string) {
216-
this.state.verifyRefactorAvailable(this.negative, "implicit", name, actionName, actionDescription);
215+
public refactorAvailable(name: string, actionName?: string, actionDescription?: string, kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) {
216+
this.state.verifyRefactorAvailable(this.negative, "implicit", name, actionName, actionDescription, kind, preferences, includeInteractiveActions);
217217
}
218218

219-
public refactorAvailableForTriggerReason(triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string) {
220-
this.state.verifyRefactorAvailable(this.negative, triggerReason, name, actionName);
219+
public refactorAvailableForTriggerReason(triggerReason: ts.RefactorTriggerReason, name: string, actionName?: string, actionDescription?: string, kind?: string, preferences = ts.emptyOptions, includeInteractiveActions?: boolean) {
220+
this.state.verifyRefactorAvailable(this.negative, triggerReason, name, actionName, actionDescription, kind, preferences, includeInteractiveActions);
221221
}
222222

223223
public refactorKindAvailable(kind: string, expected: string[], preferences = ts.emptyOptions) {

src/services/refactors/extractSymbol.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
assertType,
77
BindingElement,
88
Block,
9-
BlockLike,
109
BreakStatement,
1110
CancellationToken,
1211
canHaveModifiers,
@@ -67,6 +66,7 @@ import {
6766
isAssignmentExpression,
6867
isBinaryExpression,
6968
isBlock,
69+
isBlockLike,
7070
isBlockScope,
7171
isCaseClause,
7272
isClassLike,
@@ -2221,18 +2221,6 @@ function isExtractableExpression(node: Node): boolean {
22212221
return true;
22222222
}
22232223

2224-
function isBlockLike(node: Node): node is BlockLike {
2225-
switch (node.kind) {
2226-
case SyntaxKind.Block:
2227-
case SyntaxKind.SourceFile:
2228-
case SyntaxKind.ModuleBlock:
2229-
case SyntaxKind.CaseClause:
2230-
return true;
2231-
default:
2232-
return false;
2233-
}
2234-
}
2235-
22362224
function isInJSXContent(node: Node) {
22372225
return isStringLiteralJsxAttribute(node) ||
22382226
(isJsxElement(node) || isJsxSelfClosingElement(node) || isJsxFragment(node)) && (isJsxElement(node.parent) || isJsxFragment(node.parent));

src/services/refactors/moveToFile.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import {
3939
filter,
4040
find,
4141
FindAllReferences,
42+
findAncestor,
4243
findIndex,
4344
findLast,
4445
firstDefined,
@@ -58,6 +59,7 @@ import {
5859
getRelativePathFromFile,
5960
getSourceFileOfNode,
6061
getSynthesizedDeepClone,
62+
getTokenAtPosition,
6163
getUniqueName,
6264
hasJSFileExtension,
6365
hasSyntacticModifier,
@@ -73,6 +75,7 @@ import {
7375
isArrayLiteralExpression,
7476
isBinaryExpression,
7577
isBindingElement,
78+
isBlockLike,
7679
isDeclarationName,
7780
isExportDeclaration,
7881
isExportSpecifier,
@@ -165,6 +168,16 @@ registerRefactor(refactorNameForMoveToFile, {
165168
if (!interactiveRefactorArguments) {
166169
return emptyArray;
167170
}
171+
/** If the start/end nodes of the selection are inside a block like node do not show the `Move to file` code action
172+
* This condition is used in order to show less often the `Move to file` code action */
173+
if (context.endPosition !== undefined) {
174+
const file = context.file;
175+
const startNodeAncestor = findAncestor(getTokenAtPosition(file, context.startPosition), isBlockLike);
176+
const endNodeAncestor = findAncestor(getTokenAtPosition(file, context.endPosition), isBlockLike);
177+
if (startNodeAncestor && !isSourceFile(startNodeAncestor) && endNodeAncestor && !isSourceFile(endNodeAncestor)) {
178+
return emptyArray;
179+
}
180+
}
168181
if (context.preferences.allowTextChangesInNewFiles && statements) {
169182
return [{ name: refactorNameForMoveToFile, description, actions: [moveToFileAction] }];
170183
}

src/services/utilities.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
BinaryExpression,
1010
binarySearchKey,
1111
BindingElement,
12+
BlockLike,
1213
BreakOrContinueStatement,
1314
CallExpression,
1415
canHaveModifiers,
@@ -4274,3 +4275,16 @@ export function fileShouldUseJavaScriptRequire(file: SourceFile | string, progra
42744275
}
42754276
return preferRequire;
42764277
}
4278+
4279+
/** @internal */
4280+
export function isBlockLike(node: Node): node is BlockLike {
4281+
switch (node.kind) {
4282+
case SyntaxKind.Block:
4283+
case SyntaxKind.SourceFile:
4284+
case SyntaxKind.ModuleBlock:
4285+
case SyntaxKind.CaseClause:
4286+
return true;
4287+
default:
4288+
return false;
4289+
}
4290+
}

tests/cases/fourslash/fourslash.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,8 @@ declare namespace FourSlashInterface {
281281
codeFixDiagnosticsAvailableAtMarkers(markerNames: string[], diagnosticCode?: number): void;
282282
applicableRefactorAvailableForRange(): void;
283283

284-
refactorAvailable(name: string, actionName?: string, actionDescription?: string): void;
285-
refactorAvailableForTriggerReason(triggerReason: RefactorTriggerReason, name: string, action?: string): void;
284+
refactorAvailable(name: string, actionName?: string, actionDescription?: string, kind?: string, preferences?: {}, includeInteractiveActions?: boolean): void;
285+
refactorAvailableForTriggerReason(triggerReason: RefactorTriggerReason, name: string, action?: string, actionDescription?: string, kind?: string, preferences?: {}, includeInteractiveActions?: boolean): void;
286286
refactorKindAvailable(refactorKind: string, expected: string[], preferences?: {}): void;
287287
}
288288
class verify extends verifyNegatable {
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
////namespace ns {
4+
//// /*a*/export function fn() {
5+
//// }
6+
//// fn();
7+
//// /*b*/
8+
////}
9+
10+
goTo.select("a", "b");
11+
verify.not.refactorAvailable("Move to file",
12+
/*actionName*/ undefined,
13+
/*actionDescription*/ undefined,
14+
/*kind*/ undefined,
15+
{
16+
allowTextChangesInNewFiles : true
17+
},
18+
/*includeInteractiveActions*/ true);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
/// <reference path='fourslash.ts' />
2+
3+
/////*a*/
4+
////namespace ns {
5+
//// export function fn() {
6+
//// }
7+
//// fn();
8+
////}
9+
/////*b*/
10+
11+
goTo.select("a", "b");
12+
verify.refactorAvailable("Move to file",
13+
/*actionName*/ undefined,
14+
/*actionDescription*/ undefined,
15+
/*kind*/ undefined,
16+
{
17+
allowTextChangesInNewFiles : true
18+
},
19+
/*includeInteractiveActions*/ true);
20+

0 commit comments

Comments
 (0)