mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-05 08:11:30 -06:00
Don't use text change's createNewFile for existing empty file (#54358)
This commit is contained in:
parent
13169870b4
commit
e7d62e57aa
@ -36,6 +36,7 @@ import {
|
||||
ImplementationLocation,
|
||||
InlayHint,
|
||||
InlayHintKind,
|
||||
InteractiveRefactorArguments,
|
||||
isString,
|
||||
JSDocTagInfo,
|
||||
LanguageService,
|
||||
@ -52,6 +53,7 @@ import {
|
||||
Program,
|
||||
QuickInfo,
|
||||
RefactorEditInfo,
|
||||
RefactorTriggerReason,
|
||||
ReferencedSymbol,
|
||||
ReferenceEntry,
|
||||
RenameInfo,
|
||||
@ -787,11 +789,25 @@ export class SessionClient implements LanguageService {
|
||||
return { file, line, offset, endLine, endOffset };
|
||||
}
|
||||
|
||||
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange): ApplicableRefactorInfo[] {
|
||||
const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName);
|
||||
|
||||
getApplicableRefactors(
|
||||
fileName: string,
|
||||
positionOrRange: number | TextRange,
|
||||
preferences: UserPreferences | undefined,
|
||||
triggerReason?: RefactorTriggerReason,
|
||||
kind?: string,
|
||||
includeInteractiveActions?: boolean): ApplicableRefactorInfo[] {
|
||||
if (preferences) { // Temporarily set preferences
|
||||
this.configure(preferences);
|
||||
}
|
||||
const args: protocol.GetApplicableRefactorsRequestArgs = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName);
|
||||
args.triggerReason = triggerReason;
|
||||
args.kind = kind;
|
||||
args.includeInteractiveActions = includeInteractiveActions;
|
||||
const request = this.processRequest<protocol.GetApplicableRefactorsRequest>(protocol.CommandTypes.GetApplicableRefactors, args);
|
||||
const response = this.processResponse<protocol.GetApplicableRefactorsResponse>(request);
|
||||
if (preferences) { // Restore preferences
|
||||
this.configure(this.preferences || {});
|
||||
}
|
||||
return response.body!; // TODO: GH#18217
|
||||
}
|
||||
|
||||
@ -808,11 +824,17 @@ export class SessionClient implements LanguageService {
|
||||
_formatOptions: FormatCodeSettings,
|
||||
positionOrRange: number | TextRange,
|
||||
refactorName: string,
|
||||
actionName: string): RefactorEditInfo {
|
||||
|
||||
const args = this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetEditsForRefactorRequestArgs;
|
||||
actionName: string,
|
||||
preferences: UserPreferences | undefined,
|
||||
interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo {
|
||||
if (preferences) { // Temporarily set preferences
|
||||
this.configure(preferences);
|
||||
}
|
||||
const args =
|
||||
this.createFileLocationOrRangeRequestArgs(positionOrRange, fileName) as protocol.GetEditsForRefactorRequestArgs;
|
||||
args.refactor = refactorName;
|
||||
args.action = actionName;
|
||||
args.interactiveRefactorArguments = interactiveRefactorArguments;
|
||||
|
||||
const request = this.processRequest<protocol.GetEditsForRefactorRequest>(protocol.CommandTypes.GetEditsForRefactor, args);
|
||||
const response = this.processResponse<protocol.GetEditsForRefactorResponse>(request);
|
||||
@ -829,6 +851,10 @@ export class SessionClient implements LanguageService {
|
||||
renameLocation = this.lineOffsetToPosition(renameFilename, response.body.renameLocation!);
|
||||
}
|
||||
|
||||
if (preferences) { // Restore preferences
|
||||
this.configure(this.preferences || {});
|
||||
}
|
||||
|
||||
return {
|
||||
edits,
|
||||
renameFilename,
|
||||
|
||||
@ -176,8 +176,8 @@ registerRefactor(refactorNameForMoveToFile, {
|
||||
function doChange(context: RefactorContext, oldFile: SourceFile, targetFile: string, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void {
|
||||
const checker = program.getTypeChecker();
|
||||
const usage = getUsageInfo(oldFile, toMove.all, checker);
|
||||
//For a new file or an existing blank target file
|
||||
if (!host.fileExists(targetFile) || host.fileExists(targetFile) && program.getSourceFile(targetFile)?.statements.length === 0) {
|
||||
//For a new file
|
||||
if (!host.fileExists(targetFile)) {
|
||||
changes.createNewFile(oldFile, targetFile, getNewStatementsAndRemoveFromOldFile(oldFile, targetFile, usage, changes, toMove, program, host, preferences));
|
||||
addNewFileToTsconfig(program, changes, oldFile.fileName, targetFile, hostGetCanonicalFileName(host));
|
||||
}
|
||||
@ -189,7 +189,15 @@ function doChange(context: RefactorContext, oldFile: SourceFile, targetFile: str
|
||||
}
|
||||
|
||||
function getNewStatementsAndRemoveFromOldFile(
|
||||
oldFile: SourceFile, targetFile: string | SourceFile, usage: UsageInfo, changes: textChanges.ChangeTracker, toMove: ToMove, program: Program, host: LanguageServiceHost, preferences: UserPreferences, importAdder?: codefix.ImportAdder
|
||||
oldFile: SourceFile,
|
||||
targetFile: string | SourceFile,
|
||||
usage: UsageInfo,
|
||||
changes: textChanges.ChangeTracker,
|
||||
toMove: ToMove,
|
||||
program: Program,
|
||||
host: LanguageServiceHost,
|
||||
preferences: UserPreferences,
|
||||
importAdder?: codefix.ImportAdder
|
||||
) {
|
||||
const checker = program.getTypeChecker();
|
||||
const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective);
|
||||
@ -218,6 +226,9 @@ function getNewStatementsAndRemoveFromOldFile(
|
||||
if (targetFile.statements.length > 0) {
|
||||
changes.insertNodesAfter(targetFile, targetFile.statements[targetFile.statements.length - 1], body);
|
||||
}
|
||||
else {
|
||||
changes.insertNodesAtEndOfFile(targetFile, body, /*blankLineBetween*/ false);
|
||||
}
|
||||
if (imports.length > 0) {
|
||||
insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences);
|
||||
}
|
||||
|
||||
@ -631,6 +631,25 @@ export class ChangeTracker {
|
||||
}
|
||||
}
|
||||
|
||||
public insertNodesAtEndOfFile(
|
||||
sourceFile: SourceFile,
|
||||
newNodes: readonly Statement[],
|
||||
blankLineBetween: boolean): void {
|
||||
this.insertAtEndOfFile(sourceFile, newNodes, blankLineBetween);
|
||||
}
|
||||
|
||||
private insertAtEndOfFile(
|
||||
sourceFile: SourceFile,
|
||||
insert: readonly Statement[],
|
||||
blankLineBetween: boolean): void {
|
||||
const pos = sourceFile.end + 1;
|
||||
const options = {
|
||||
prefix: this.newLineCharacter,
|
||||
suffix: this.newLineCharacter + (blankLineBetween ? this.newLineCharacter : ""),
|
||||
};
|
||||
this.insertNodesAt(sourceFile, pos, insert, options);
|
||||
}
|
||||
|
||||
private insertStatementsInNewFile(fileName: string, statements: readonly (Statement | SyntaxKind.NewLineTrivia)[], oldFile?: SourceFile): void {
|
||||
if (!this.newFileChanges) {
|
||||
this.newFileChanges = createMultiMap<string, NewFileInsertion>();
|
||||
|
||||
@ -652,7 +652,7 @@ export interface LanguageService {
|
||||
* arguments for any interactive action before offering it.
|
||||
*/
|
||||
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string, includeInteractiveActions?: boolean): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, includeInteractiveActions?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
|
||||
getMoveToRefactoringFileSuggestions(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): { newFileName: string, files: string[] };
|
||||
organizeImports(args: OrganizeImportsArgs, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[];
|
||||
getEditsForFileRename(oldFilePath: string, newFilePath: string, formatOptions: FormatCodeSettings, preferences: UserPreferences | undefined): readonly FileTextChanges[];
|
||||
|
||||
@ -10196,7 +10196,7 @@ declare namespace ts {
|
||||
* arguments for any interactive action before offering it.
|
||||
*/
|
||||
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string, includeInteractiveActions?: boolean): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, includeInteractiveActions?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
|
||||
getMoveToRefactoringFileSuggestions(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): {
|
||||
newFileName: string;
|
||||
files: string[];
|
||||
|
||||
@ -6227,7 +6227,7 @@ declare namespace ts {
|
||||
* arguments for any interactive action before offering it.
|
||||
*/
|
||||
getApplicableRefactors(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string, includeInteractiveActions?: boolean): ApplicableRefactorInfo[];
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, includeInteractiveActions?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
|
||||
getEditsForRefactor(fileName: string, formatOptions: FormatCodeSettings, positionOrRange: number | TextRange, refactorName: string, actionName: string, preferences: UserPreferences | undefined, interactiveRefactorArguments?: InteractiveRefactorArguments): RefactorEditInfo | undefined;
|
||||
getMoveToRefactoringFileSuggestions(fileName: string, positionOrRange: number | TextRange, preferences: UserPreferences | undefined, triggerReason?: RefactorTriggerReason, kind?: string): {
|
||||
newFileName: string;
|
||||
files: string[];
|
||||
|
||||
@ -18,9 +18,13 @@ verify.moveToFile({
|
||||
`,
|
||||
|
||||
"/bar.ts":
|
||||
`import { b } from './other';
|
||||
`//
|
||||
import { p } from './a';
|
||||
|
||||
|
||||
import { b } from "./other";
|
||||
|
||||
|
||||
const y: Date = p + b;
|
||||
`,
|
||||
},
|
||||
|
||||
@ -23,8 +23,10 @@ export const a = 10;
|
||||
y;`,
|
||||
|
||||
"/src/dir2/bar.ts":
|
||||
`import { b } from '../dir1/other';
|
||||
import { a } from '../dir1/a';
|
||||
`import { a } from '../dir1/a';
|
||||
|
||||
import { b } from "../dir1/other";
|
||||
|
||||
|
||||
export const y = b + a;
|
||||
`,
|
||||
|
||||
27
tests/cases/fourslash/server/moveToFile_emptyTargetFile.ts
Normal file
27
tests/cases/fourslash/server/moveToFile_emptyTargetFile.ts
Normal file
@ -0,0 +1,27 @@
|
||||
/// <reference path='../fourslash.ts' />
|
||||
|
||||
// @Filename: /source.ts
|
||||
////[|export const a = 1;|]
|
||||
////const b = 2;
|
||||
////console.log(a, b);
|
||||
|
||||
// @Filename: /target.ts
|
||||
/////** empty */
|
||||
|
||||
// @Filename: /tsconfig.json
|
||||
///// { "compilerOptions": { "newLine": "lf" } }
|
||||
|
||||
verify.moveToFile({
|
||||
newFileContents: {
|
||||
"/source.ts":
|
||||
`import { a } from "./target";
|
||||
|
||||
const b = 2;
|
||||
console.log(a, b);`,
|
||||
"/target.ts":
|
||||
`/** empty */
|
||||
export const a = 1;
|
||||
`,
|
||||
},
|
||||
interactiveRefactorArguments: { targetFile: "/target.ts" },
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user