From 36e67a4bd5b411ad68a3506f8a188a56e308af52 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 18 Jan 2024 06:54:25 -0800 Subject: [PATCH 01/41] Testing basic changes --- src/harness/client.ts | 14 ++ src/harness/fourslashImpl.ts | 13 ++ src/harness/fourslashInterfaceImpl.ts | 12 ++ src/server/project.ts | 123 +++++++++++++++++ src/server/protocol.ts | 24 ++++ src/server/session.ts | 9 ++ .../_namespaces/ts.postPasteImportFixes.ts | 1 + src/services/_namespaces/ts.ts | 2 + src/services/codefixes/importFixes.ts | 8 +- src/services/postPasteImportFix.ts | 130 ++++++++++++++++++ src/services/services.ts | 17 +++ src/services/types.ts | 16 ++- tests/cases/fourslash/fourslash.ts | 14 ++ .../fourslash/server/postPasteImportFix1.ts | 28 ++++ .../fourslash/server/postPasteImportFix2.ts | 38 +++++ .../fourslash/server/postPasteImportFix3.ts | 31 +++++ 16 files changed, 475 insertions(+), 5 deletions(-) create mode 100644 src/services/_namespaces/ts.postPasteImportFixes.ts create mode 100644 src/services/postPasteImportFix.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFix1.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFix2.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFix3.ts diff --git a/src/harness/client.ts b/src/harness/client.ts index 619fece8cae62..3f6d72f88f2f6 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -13,6 +13,7 @@ import { computeLineAndCharacterOfPosition, computeLineStarts, computePositionOfLineAndCharacter, + CopyRange, createQueue, createTextSpanFromBounds, Debug, @@ -1009,6 +1010,19 @@ export class SessionClient implements LanguageService { return getSupportedCodeFixes(); } + getPostPasteImportFixes(targetFile: string, pastes: Array<{text: string; range: TextRange}>, _preferences: UserPreferences, _formatOptions: FormatCodeSettings, originalFile?: string, copyRange?: CopyRange): FileTextChanges[]{ + const t = this.createFileRangeRequestArgs(targetFile, pastes[0].range.pos, pastes[0].range.end); + const args = this.createFileLocationOrRangeRequestArgs(pastes[0].range, targetFile) as protocol.GetPostPasteImportFixesRequestArgs; //needs to be fixed + args.targetFile = targetFile; + args.pastes = [{text: pastes[0].text, range: t}]; + args.originalFile = originalFile; + args.copyRange = copyRange; + + const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); + const response = this.processResponse(request); + return []; + } + getProgram(): Program { throw new Error("Program objects are not serializable through the server protocol."); } diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 5763b24c6bde6..99109ad800025 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3554,6 +3554,19 @@ export class TestState { assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers); } + public getPostPasteImportFixes( + targetFile: string, + pastes: Array<{text: string; range: ts.TextRange}>,//{ pos, end }: ts.TextRange + preferences: ts.UserPreferences, + originalFile?: string, + copyRange?: ts.CopyRange + ){ + const range = this.getSelection(); + //const range: ts.TextRange = {pos: pastes[0].range.pos, end: pastes[0].range.end}; + const t = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, pastes, preferences, this.formatCodeSettings, originalFile, copyRange); + return "hello"; + } + public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) { const name = "verifyDocCommentTemplate"; const actual = this.languageService.getDocCommentTemplateAtPosition(this.activeFile.fileName, this.currentCaretPosition, options || { generateReturnInDocTemplate: true }, this.formatCodeSettings)!; diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 52e028c5070bb..d1fdea4aef33e 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -620,6 +620,10 @@ export class Verify extends VerifyNegatable { public organizeImports(newContent: string, mode?: ts.OrganizeImportsMode, preferences?: ts.UserPreferences): void { this.state.verifyOrganizeImports(newContent, mode, preferences); } + + public postPasteImportFix(options: verifyPostPasteImportFix): void { + this.state.getPostPasteImportFixes(options.targetFile, options.pastes, options.preferences, options.originalFile, options.copyRange); + } } export class Edit { @@ -1872,6 +1876,14 @@ export interface VerifyCodeFixAllOptions { preferences?: ts.UserPreferences; } +export interface verifyPostPasteImportFix { + targetFile: string; + pastes: Array<{text: string; range: ts.TextRange}>; + preferences: ts.UserPreferences; + originalFile?: string; + copyRange?: ts.CopyRange +} + export interface VerifyRefactorOptions { name: string; actionName: string; diff --git a/src/server/project.ts b/src/server/project.ts index fbac2fb111c35..57ecf77f24db5 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,3 +1,4 @@ +import { getExportInfos, getImportFixes, getSymbolNamesToImport, shouldUseRequire } from "../services/codefixes/importFixes"; import * as ts from "./_namespaces/ts"; import { addRange, @@ -2212,6 +2213,128 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return this.noDtsResolutionProject; } + // export anotherGetFixes(updatedFile: ts.SourceFile, originalProgram: ts.Program, node: ts.Identifier, languageServiceHost: this, cancellationToken: ts.CancellationToken, preferences: ts.UserPreferences) { + // const imports = flatMap(getSymbolNamesToImport(updatedFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { + // // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. + // if (symbolName === ts.InternalSymbolName.Default) { + // return undefined; + // } + // const isValidTypeOnlyUseSite = ts.isValidTypeOnlyAliasUseSite(node); + // const useRequire = shouldUseRequire(updatedFile, originalProgram); + // const exportInfo = getExportInfos(symbolName, ts.isJSXTagName(node), ts.getMeaningFromLocation(node), cancellationToken, updatedFile, originalProgram, true, languageServiceHost, preferences); + // return arrayFrom( + // ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes), + // fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), + // ); + // } + // } + + /** @internal */ + updatedTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined} { + const originalProgram = this.program; + this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length-1, pastedText); + this.updateGraph(); + const updatedFile = this.program?.getSourceFile(rootFile); + const updatedProgram = this.program; + return { updatedFile, updatedProgram, originalProgram }; + } + /** @internal */ + getFakeSourceFile(rootFile: string, pastedText: string, _targetFileName: string, targetFileText: string): [] | undefined { + + /** + * cscriptInfo.editContent() + * project.updateGraph gives the new SF + * after scriptInfo.editContent("") the new SF is not updated + */ + //const t = this.getScriptInfo(rootFile); + // const scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(rootFile)); + this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); + this.updateGraph(); + const updatedFile = this.program?.getSourceFile(rootFile); + const updatedProgram = this.program; + + const originalProgram = this.program; + const cancellationToken = this.cancellationToken; + const languageServiceHost = this; + const preferences = this.projectService.getPreferences(toNormalizedPath(rootFile)); + let allImports:[] | undefined; + + if (updatedFile && updatedProgram && originalProgram) { + ts.forEachChild(updatedFile, function cb(node) { + if (ts.isIdentifier(node)) { + if (!updatedProgram.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && + !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { + //generate imports + const imports = flatMap(getSymbolNamesToImport(updatedFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { + // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. + if (symbolName === ts.InternalSymbolName.Default) { + return undefined; + } + const isValidTypeOnlyUseSite = ts.isValidTypeOnlyAliasUseSite(node); + const useRequire = shouldUseRequire(updatedFile, originalProgram); + const exportInfo = getExportInfos(symbolName, ts.isJSXTagName(node), ts.getMeaningFromLocation(node), cancellationToken, updatedFile, originalProgram, true, languageServiceHost, preferences); + const t = arrayFrom( + ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes), + fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), + ); + }); + } + } + else { + node.forEachChild(cb); + } + }); + } + + // const program: Program = ts.createProgram([rootFile], this.getCompilerOptions(), { + // getSourceFile:() => ts.createSourceFile("fake source file", pastedText, { languageVersion: ts.ScriptTarget.ES2015, jsDocParsingMode: JSDocParsingMode.ParseNone }, /*setParentNodes*/ false), + // getDefaultLibFileName: () => ts.getDefaultLibFilePath(this.getCompilerOptions()), + // writeFile: noop, + // getCurrentDirectory: () => this.getCurrentDirectory(), + // getCanonicalFileName: () => "fake source file", + // useCaseSensitiveFileNames: () => true, + // getNewLine: () => "\n", + // fileExists(){return true}, + // readFile() { + // return pastedText; + // } + // }); + // const fakeSourceFile = program.getSourceFile("fake source file"); + // const originalProgram = this.program; + // const cancellationToken = this.cancellationToken; + // const languageServiceHost = this; + // const preferences = this.projectService.getPreferences(toNormalizedPath(rootFile)); + // let imports; + + // if (fakeSourceFile && originalProgram) { + // ts.forEachChild(fakeSourceFile, function cb(node) { + // if (ts.isIdentifier(node)) { + // if (!program.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && + // !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { + // //generate imports + // imports = flatMap(getSymbolNamesToImport(fakeSourceFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { + // // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. + // if (symbolName === ts.InternalSymbolName.Default) { + // return undefined; + // } + // const isValidTypeOnlyUseSite = ts.isValidTypeOnlyAliasUseSite(node); + // const useRequire = shouldUseRequire(fakeSourceFile, originalProgram); + // const exportInfo = getExportInfos(symbolName, ts.isJSXTagName(node), ts.getMeaningFromLocation(node), cancellationToken, fakeSourceFile, originalProgram, true, languageServiceHost, preferences); + // return arrayFrom( + // ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(fakeSourceFile), isValidTypeOnlyUseSite, useRequire, program, fakeSourceFile, languageServiceHost, preferences).fixes), + // fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), + // ); + // }); + // } + // } + // else { + // node.forEachChild(cb); + // } + // }); + // } + return allImports; + } + /** @internal */ private getCompilerOptionsForNoDtsResolutionProject() { return { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index ae6c5bc055143..fe99eb2440307 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -144,6 +144,7 @@ export const enum CommandTypes { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", + GetPostPasteImportFixes = "getPostPasteImportFixes", /** @internal */ GetEditsForRefactorFull = "getEditsForRefactor-full", @@ -630,6 +631,29 @@ export interface GetMoveToRefactoringFileSuggestions extends Response { }; } +/** + * Request refactorings at a given position post pasting text from some other location. + */ + +export interface GetPostPasteImportFixesRequest extends Request { + command: CommandTypes.GetPostPasteImportFixes; + arguments: GetPostPasteImportFixesRequestArgs; +} +export type DocumentRange = FileRangeRequestArgs; +export type CopyRange = { + start: Location; + end: Location; +} +export type GetPostPasteImportFixesRequestArgs = FileLocationOrRangeRequestArgs & { + targetFile: string, + pastes: Array<{text: string; range: DocumentRange}>, + originalFile?: string, + copyRange?: CopyRange +} +export interface GetPostPasteImportFixesResponse extends Response { + filename: string; +} + /** * A set of one or more available refactoring actions, grouped under a parent refactoring. */ diff --git a/src/server/session.ts b/src/server/session.ts index 116ff92c5d9f9..bfb054f1c5a7c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2796,6 +2796,12 @@ export class Session implements EventSender { return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); } + private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs) { + const { file, project } = this.getFileAndProject(args); + const textRange = this.getRange(args.pastes[0].range, project.getScriptInfoForNormalizedPath(file)!); + return project.getLanguageService().getPostPasteImportFixes(args.targetFile, [{text: args.pastes[0].text, range: textRange}], this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); + } + private organizeImports(args: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): readonly protocol.FileCodeEdits[] | readonly FileTextChanges[] { Debug.assert(args.scope.type === "file"); const { file, project } = this.getFileAndProject(args.scope.args); @@ -3521,6 +3527,9 @@ export class Session implements EventSender { [protocol.CommandTypes.GetMoveToRefactoringFileSuggestions]: (request: protocol.GetMoveToRefactoringFileSuggestionsRequest) => { return this.requiredResponse(this.getMoveToRefactoringFileSuggestions(request.arguments)); }, + [protocol.CommandTypes.GetPostPasteImportFixes]: (request: protocol.GetPostPasteImportFixesRequest) => { + return this.requiredResponse(this.getPostPasteImportFixes(request.arguments)); + }, [protocol.CommandTypes.GetEditsForRefactorFull]: (request: protocol.GetEditsForRefactorRequest) => { return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false)); }, diff --git a/src/services/_namespaces/ts.postPasteImportFixes.ts b/src/services/_namespaces/ts.postPasteImportFixes.ts new file mode 100644 index 0000000000000..c46fc22994e95 --- /dev/null +++ b/src/services/_namespaces/ts.postPasteImportFixes.ts @@ -0,0 +1 @@ +export * from "../postPasteImportFix"; \ No newline at end of file diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts index e30ea818a04b5..a0fb6bf9ca8ff 100644 --- a/src/services/_namespaces/ts.ts +++ b/src/services/_namespaces/ts.ts @@ -56,3 +56,5 @@ import * as textChanges from "./ts.textChanges"; export { textChanges }; import * as formatting from "./ts.formatting"; export { formatting }; +import * as postPasteImportFixes from "./ts.postPasteImportFixes"; +export { postPasteImportFixes }; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 97c5bca540b54..295fc31b62c5d 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -626,7 +626,7 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } } -function getImportFixes( +export function getImportFixes( exportInfos: readonly SymbolExportInfo[], usagePosition: number | undefined, isValidTypeOnlyUseSite: boolean, @@ -833,7 +833,7 @@ function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile }; } -function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean { +export function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean { // 1. TypeScript files don't use require variable declarations if (!isSourceFileJS(sourceFile)) { return false; @@ -1198,7 +1198,7 @@ function getTypeOnlyPromotionFix(sourceFile: SourceFile, symbolToken: Identifier return { kind: ImportFixKind.PromoteTypeOnly, typeOnlyAliasDeclaration }; } -function getSymbolNamesToImport(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string[] { +export function getSymbolNamesToImport(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string[] { const parent = symbolToken.parent; if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && jsxModeNeedsExplicitImport(compilerOptions.jsx)) { const jsxNamespace = checker.getJsxNamespace(sourceFile); @@ -1217,7 +1217,7 @@ function needsJsxNamespaceFix(jsxNamespace: string, symbolToken: Identifier, che } // Returns a map from an exported symbol's ID to a list of every way it's (re-)exported. -function getExportInfos( +export function getExportInfos( symbolName: string, isJsxTagName: boolean, currentTokenMeaning: SemanticMeaning, diff --git a/src/services/postPasteImportFix.ts b/src/services/postPasteImportFix.ts new file mode 100644 index 0000000000000..0484322259dcb --- /dev/null +++ b/src/services/postPasteImportFix.ts @@ -0,0 +1,130 @@ +import { addRange, append } from "../compiler/core"; +import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange } from "../compiler/types"; +import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; +import { codefix, factory, fileShouldUseJavaScriptRequire, formatting, getLineInfo, getQuotePreference, insertImports, nodeSeenTracker, Symbol, textChanges } from "./_namespaces/ts"; +import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; +import { CopyRange, FileTextChanges, LanguageServiceHost } from "./types"; + +/** @internal */ +export function postPastImportFixProvider( + targetFile: SourceFile, + host: LanguageServiceHost, + pastes: Array<{text: string; range: TextRange}>, + preferences: UserPreferences, + formatContext: formatting.FormatContext, + originalFile?: SourceFile, + copyLocation?: CopyRange): FileTextChanges[] { + + /** + * When the source file exists + * 1.Need to turn pasted text, in pastes.text into statements + * 2.use getUsageInfo() to the symbols that need to be imported + * 3.use the if and the third part of getTargetFileImportsAndAddExportInOldFile + * */ + const { updatedFile, updatedProgram, originalProgram } = host.updatedTargetFile(targetFile.fileName, targetFile.text, pastes[0].text); + let statements: Statement[] = []; + + if (originalFile && originalProgram && updatedFile && updatedProgram) { + //addRange(statements, updatedFile?.statements, updatedFile?.statements.length - (targetFileStatements ? targetFileStatements.length : 0) - 1); + //addRange(statements, originalFile?.statements, 2); + //const start = originalFile.statements[0].getStart(originalFile);//addRange(statements, originalFile.statements, updatedFile.statements[updatedFile.statements.length - targetFileStatements.length].getStart(originalFile)) + + //addRange(statements, updatedFile.statements, a.getStart(originalFile), b.getStart(originalFile)); + // const a = updatedFile.statements[updatedFile.getLineAndCharacterOfPosition(pastes[0].range.pos).line] //21 + // const b = updatedFile.statements[updatedFile.getLineAndCharacterOfPosition(pastes[0].range.end).line] //pastes[0].range.end + pastes[0].range.length - 1 + addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation?.end.line); + const usage = getUsageInfo(originalFile, statements, originalProgram.getTypeChecker()); + const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); + + return textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => getImports(originalFile, updatedFile, statements, updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, + usage.targetFileImportsFromOldFile, changeTracker, preferences, host, updatedProgram.getTypeChecker())); + } + else { + return []; + } + + + //const unknownSymbols = host.getFakeSourceFile(targetFile,pastes[0].text,targetFile, targetFileText); +} + +function getImports( + originalFile: SourceFile, + targetFile: SourceFile, + statements: Statement[], + program: Program, + importAdder: codefix.ImportAdder, + importsToCopy: Map, + targetFileImportsFromOldFile: Set, + changes: textChanges.ChangeTracker, + preferences: UserPreferences, + host: LanguageServiceHost, + checker: TypeChecker) { + + const imports = getTargetFileImportsForKnownOriginalFile(originalFile, targetFile, program, importAdder, importsToCopy, targetFileImportsFromOldFile, changes, preferences, host, checker); + if (imports.length > 0) { + insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); + } + importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); + changes.insertNodesAtEndOfFile(targetFile, statements, true); //NEEDS TO BE FIXED!!!!!!!!!!!! +} + +function getTargetFileImportsForKnownOriginalFile( + originalFile: SourceFile, + targetFile: SourceFile, + program: Program, + importAdder: codefix.ImportAdder, + importsToCopy: Map, + targetFileImportsFromOldFile: Set, + changes: textChanges.ChangeTracker, + preferences: UserPreferences, + host: LanguageServiceHost, + checker: TypeChecker) { + const copiedOldImports: AnyImportOrRequireStatement[] = []; + importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { + try { + importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); + } + catch { + for (const oldStatement of originalFile.statements) { //might be changed to just statements, meaning that the updated statements in the target file + forEachImportInStatement(oldStatement, i => { + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + }); + } + } + }); + + const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, program, host, !!originalFile.commonJsModuleIndicator); + const quotePreference = getQuotePreference(targetFile, preferences); + // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. + let oldFileDefault: Identifier | undefined; + const oldFileNamedImports: string[] = []; + const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. + targetFileImportsFromOldFile.forEach(symbol => { + if (!symbol.declarations) { + return; + } + for (const decl of symbol.declarations) { + if (!isTopLevelDeclaration(decl)) continue; + const name = nameOfTopLevelDeclaration(decl); + if (!name) continue; + + const top = getTopLevelDeclarationStatement(decl); + if (markSeenTop(top)) { + addExportToChanges(originalFile, top, name, changes, useEsModuleSyntax); + } + if (importAdder && checker.isUnknownSymbol(symbol)) { + importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); + } + else { + if (hasSyntacticModifier(decl, ModifierFlags.Default)) { + oldFileDefault = name; + } + else { + oldFileNamedImports.push(name.text); + } + } + } + }); + + return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)) +} diff --git a/src/services/services.ts b/src/services/services.ts index 812eafd2c940e..e6a90ad61c966 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -319,6 +319,8 @@ import { updateSourceFile, UserPreferences, VariableDeclaration, + postPasteImportFixes, + CopyRange, } from "./_namespaces/ts"; import * as NavigateTo from "./_namespaces/ts.NavigateTo"; import * as NavigationBar from "./_namespaces/ts.NavigationBar"; @@ -2089,6 +2091,20 @@ export function createLanguageService( }; } + function getPostPasteImportFixes ( + targetFile: string, + pastes: Array<{text: string; range: TextRange}>, + preferences: UserPreferences, + formatOptions: FormatCodeSettings, + originalFile?: string, + copyLocation?: CopyRange + ): FileTextChanges[]{ + synchronizeHostData(); + const originalSourceFile = originalFile ? getValidSourceFile(originalFile) : undefined; + const edits = postPasteImportFixes.postPastImportFixProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), originalSourceFile, copyLocation); + return edits; + } + function getNodeForQuickInfo(node: Node): Node { if (isNewExpression(node.parent) && node.pos === node.parent.pos) { return node.parent.expression; @@ -3155,6 +3171,7 @@ export function createLanguageService( uncommentSelection, provideInlayHints, getSupportedCodeFixes, + getPostPasteImportFixes }; switch (languageServiceMode) { diff --git a/src/services/types.ts b/src/services/types.ts index 9bb560af02ac9..b40afb2f71d6e 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -431,7 +431,9 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - + /** @internal */ getFakeSourceFile(rootFile: string, pastedText: string, targetFileName: string, targetFileText: string) : [] | undefined; + /** @internal */ updatedTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined}; +//needs to be changed to optional jsDocParsingMode?: JSDocParsingMode | undefined; } @@ -684,6 +686,12 @@ export interface LanguageService { getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; + getPostPasteImportFixes (targetFile: string, pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatOptions: FormatCodeSettings, originalFile: string | undefined, copyLocation: CopyRange | undefined): FileTextChanges[]; +} + +export interface CopyRange { + start: { line: number, offset: number }; + end: { line: number, offset: number } } export interface JsxClosingTagInfo { @@ -706,6 +714,12 @@ export const enum OrganizeImportsMode { RemoveUnused = "RemoveUnused", } +export interface postPasteImportFix { + targetFile: string, + targetFileText: string, + pastes: Array<{text: string; range: TextSpan}> +} + export interface OrganizeImportsArgs extends CombinedCodeFixScope { /** @deprecated Use `mode` instead */ skipDestructiveCodeActions?: boolean; diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index b61f947e488b1..6722b3ef4b31e 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -212,6 +212,14 @@ declare namespace FourSlashInterface { start: number; end: number; } + interface Location { + line: number; + offset: number; + } + interface CopyRange { + start: Location; + end: Location; + } class test_ { markers(): Marker[]; markerNames(): string[]; @@ -444,6 +452,12 @@ declare namespace FourSlashInterface { toggleMultilineComment(newFileContent: string): void; commentSelection(newFileContent: string): void; uncommentSelection(newFileContent: string): void; + postPasteImportFix(options: { + targetFile: string, + pastes: Array<{text: string; range: {pos: number, end: number}}> + originalFile?: string, + copyRange?: CopyRange, + }): void; } class edit { caretPosition(): Marker; diff --git a/tests/cases/fourslash/server/postPasteImportFix1.ts b/tests/cases/fourslash/server/postPasteImportFix1.ts new file mode 100644 index 0000000000000..2918b3d89a660 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFix1.ts @@ -0,0 +1,28 @@ +/// + +// @Filename: file1.ts +//// export interface Test1 {} +//// export interface Test2 {} +//// export interface Test3 {} +//// export interface Test4 {} + +// @Filename: file2.ts +//// /*a*/const a = 10;/*b*/ + +// @Filename: tsconfig.json +////{ "files": ["file1.ts", "file2.ts"] } + +goTo.select("a", "b"); +verify.postPasteImportFix({ + targetFile: "file2.ts", + pastes: [{ + text: `const a = 10; + interface Testing { + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; + }`, + range: { pos: 0, end: 54 }, + }], +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix2.ts b/tests/cases/fourslash/server/postPasteImportFix2.ts new file mode 100644 index 0000000000000..e5385136e07de --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFix2.ts @@ -0,0 +1,38 @@ +/// + +// @Filename: file1.ts +//// export interface Test1 {} +//// export interface Test2 {} +//// export interface Test3 {} +//// export interface Test4 {} + +// @Filename: file2.ts +//// import { Test1, Test2, Test3, Test4 } from './file1'; +//// interface Testing { +//// test1: Test1; +//// test2: Test2; +//// test3: Test3; +//// test4: Test4; +//// } + +// @Filename: file3.ts +//// /*a*/const a = 10;/*b*/ + +// @Filename: tsconfig.json +////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } + +goTo.select("a", "b"); +verify.postPasteImportFix({ + targetFile: "file3.ts", + pastes: [{ + text: `const a = 10; + interface Testing { + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; + }`, + range: { pos: 13, end: 54 }, + }], + originalFile: "file2.ts", +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix3.ts b/tests/cases/fourslash/server/postPasteImportFix3.ts new file mode 100644 index 0000000000000..2472277f67f65 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFix3.ts @@ -0,0 +1,31 @@ +/// + +// @Filename: file1.ts +////export const b = 2; + +// @Filename: file2.ts +////import { b } from './other'; +////const a = 1; +////const c = a + b; +////const t = 9; + +// @Filename: file3.ts +//// /*a*/export const tt = 2;/*b*/ +//// function f(); + +// @Filename: tsconfig.json +////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } + +goTo.select("a", "b"); +verify.postPasteImportFix({ + targetFile: "file3.ts", + pastes: [{ + text: `export const tt = 2; + const c = a + b; + const t = 9; + function f();`, + range: { pos: 20, end: 29 }, + }], + originalFile: "file2.ts", + copyRange: { start: { line : 3, offset: 0}, end : { line: 4, offset: 21}}, +}); \ No newline at end of file From 5d931f86c759b327255c478f95eb54d5100d3cb7 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 25 Jan 2024 16:42:43 -0800 Subject: [PATCH 02/41] Basix structure working --- src/harness/client.ts | 21 +- src/harness/fourslashImpl.ts | 12 +- src/harness/fourslashInterfaceImpl.ts | 12 +- src/server/project.ts | 184 +++++++++++------- src/server/protocol.ts | 5 +- src/server/session.ts | 22 ++- src/services/codefixes/importFixes.ts | 10 +- src/services/postPasteImportFix.ts | 137 +++++++++++-- src/services/services.ts | 3 +- src/services/types.ts | 18 +- tests/cases/fourslash/fourslash.ts | 1 + .../fourslash/server/postPasteImportFix1.ts | 21 +- .../fourslash/server/postPasteImportFix3.ts | 34 +++- 13 files changed, 352 insertions(+), 128 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 3f6d72f88f2f6..c89433352209d 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -51,6 +51,7 @@ import { OrganizeImportsArgs, OutliningSpan, PatternMatchKind, + PostPasteImportFixes, Program, QuickInfo, RefactorEditInfo, @@ -1010,7 +1011,7 @@ export class SessionClient implements LanguageService { return getSupportedCodeFixes(); } - getPostPasteImportFixes(targetFile: string, pastes: Array<{text: string; range: TextRange}>, _preferences: UserPreferences, _formatOptions: FormatCodeSettings, originalFile?: string, copyRange?: CopyRange): FileTextChanges[]{ + getPostPasteImportFixes(targetFile: string, pastes: Array<{text: string; range: TextRange}>, _preferences: UserPreferences, _formatOptions: FormatCodeSettings, originalFile?: string, copyRange?: CopyRange): PostPasteImportFixes[]{ const t = this.createFileRangeRequestArgs(targetFile, pastes[0].range.pos, pastes[0].range.end); const args = this.createFileLocationOrRangeRequestArgs(pastes[0].range, targetFile) as protocol.GetPostPasteImportFixesRequestArgs; //needs to be fixed args.targetFile = targetFile; @@ -1020,7 +1021,23 @@ export class SessionClient implements LanguageService { const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); - return []; + if (!response.body) { + return []; + } + + // return response.body!.map(({ fixName, description, changes, commands, fixId, fixAllDescription }) => // TODO: GH#18217 + // ({ fixName, description, changes: this.convertChanges(changes, file), commands: commands as CodeActionCommand[], fixId, fixAllDescription })); + + //const q = response.body.map(({changes}) => ({this.convertChanges(changes, targetFile)})); + //const r: FileTextChanges[] = response.body.map(item =>({changes: this.convertCodeEditsToTextChanges(item.edits)})); + /////////const q = response.body.map(item =>this.convertCodeEditsToTextChanges(item.edits)); + const e = response.body.map(item => ({changes: this.convertCodeEditsToTextChanges(item.edits)})) + // let allEdits: FileTextChanges[] = []; + // for (const edits of response.body) { + // allEdits = this.convertCodeEditsToTextChanges(edits); + // } + // const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body); + return e; } getProgram(): Program { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 99109ad800025..05e9b675a0a63 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3554,17 +3554,11 @@ export class TestState { assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers); } - public getPostPasteImportFixes( - targetFile: string, - pastes: Array<{text: string; range: ts.TextRange}>,//{ pos, end }: ts.TextRange - preferences: ts.UserPreferences, - originalFile?: string, - copyRange?: ts.CopyRange - ){ + public getPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void{ const range = this.getSelection(); //const range: ts.TextRange = {pos: pastes[0].range.pos, end: pastes[0].range.end}; - const t = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, pastes, preferences, this.formatCodeSettings, originalFile, copyRange); - return "hello"; + const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.originalFile, options.copyRange); + this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo[0].changes); } public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) { diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index d1fdea4aef33e..a3d92dd98f6d5 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -621,8 +621,8 @@ export class Verify extends VerifyNegatable { this.state.verifyOrganizeImports(newContent, mode, preferences); } - public postPasteImportFix(options: verifyPostPasteImportFix): void { - this.state.getPostPasteImportFixes(options.targetFile, options.pastes, options.preferences, options.originalFile, options.copyRange); + public postPasteImportFix(options: PostPasteImportFixOptions): void { + this.state.getPostPasteImportFixes(options); } } @@ -1924,6 +1924,14 @@ export interface MoveToFileOptions { readonly preferences?: ts.UserPreferences; } +export interface PostPasteImportFixOptions { + readonly newFileContents: { readonly [fileName: string]: string; }; + readonly pastes: Array<{text: string; range: ts.TextRange}>,//{ pos, end }: ts.TextRange + readonly preferences: ts.UserPreferences, + readonly originalFile?: string, + readonly copyRange?: ts.CopyRange +} + export type RenameLocationsOptions = readonly RenameLocationOptions[] | { readonly findInStrings?: boolean; readonly findInComments?: boolean; diff --git a/src/server/project.ts b/src/server/project.ts index 57ecf77f24db5..18c642b1cd67f 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,4 +1,6 @@ -import { getExportInfos, getImportFixes, getSymbolNamesToImport, shouldUseRequire } from "../services/codefixes/importFixes"; +import { info } from "console"; +import { FormatContext } from "../services/_namespaces/ts.formatting"; +import { FixInfo, ImportFixWithModuleSpecifier, getFixesInfoForNonUMDImport, sortFixInfo } from "../services/codefixes/importFixes"; import * as ts from "./_namespaces/ts"; import { addRange, @@ -21,6 +23,7 @@ import { containsPath, createCacheableExportInfoMap, createLanguageService, + createPackageJsonImportFilter, createResolutionCache, createSymlinkCache, Debug, @@ -66,6 +69,7 @@ import { HasInvalidatedLibResolutions, HasInvalidatedResolutions, HostCancellationToken, + ImportClause, inferredTypesContainingFile, InstallPackageOptions, IScriptSnapshot, @@ -121,6 +125,7 @@ import { StringLiteralLike, stripQuotes, StructureIsReused, + SymbolExportInfo, SymlinkCache, ThrottledCancellationToken, timestamp, @@ -310,6 +315,63 @@ const enum TypingWatcherType { type TypingWatchers = Map & { isInvoked?: boolean; }; +//========================= +//type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; +const enum ImportFixKind { + UseNamespace, + JsdocTypeImport, + AddToExisting, + AddNew, + PromoteTypeOnly, +} +const enum AddAsTypeOnly { + Allowed = 1 << 0, + Required = 1 << 1, + NotAllowed = 1 << 2, +} +// interface FixInfo { +// readonly fix: ImportFix; +// readonly symbolName: string; +// readonly errorIdentifierText: string | undefined; +// readonly isJsxNamespaceFix?: boolean; +// } +type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; +interface ImportFixBase { + readonly isReExport?: boolean; + readonly exportInfo?: SymbolExportInfo; + readonly moduleSpecifier: string; +} +interface Qualification { + readonly usagePosition: number; + readonly namespacePrefix: string; +} +interface FixUseNamespaceImport extends ImportFixBase, Qualification { + readonly kind: ImportFixKind.UseNamespace; +} +interface FixAddJsdocTypeImport extends ImportFixBase { + readonly kind: ImportFixKind.JsdocTypeImport; + readonly usagePosition: number; + readonly isReExport: boolean; + readonly exportInfo: SymbolExportInfo; +} +interface FixAddToExistingImport extends ImportFixBase { + readonly kind: ImportFixKind.AddToExisting; + readonly importClauseOrBindingPattern: ImportClause | ts.ObjectBindingPattern; + readonly importKind: ts.ImportKind.Default | ts.ImportKind.Named; + readonly addAsTypeOnly: AddAsTypeOnly; +} +interface FixAddNewImport extends ImportFixBase { + readonly kind: ImportFixKind.AddNew; + readonly importKind: ts.ImportKind; + readonly addAsTypeOnly: AddAsTypeOnly; + readonly useRequire: boolean; + readonly qualification?: Qualification; +} +interface FixPromoteTypeOnlyImport { + readonly kind: ImportFixKind.PromoteTypeOnly; + readonly typeOnlyAliasDeclaration: ts.TypeOnlyAliasDeclaration; +} +//========================= export abstract class Project implements LanguageServiceHost, ModuleResolutionHost { private rootFiles: ScriptInfo[] = []; private rootFilesMap = new Map(); @@ -2230,7 +2292,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo // } /** @internal */ - updatedTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined} { + updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined} { const originalProgram = this.program; this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length-1, pastedText); this.updateGraph(); @@ -2238,8 +2300,16 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo const updatedProgram = this.program; return { updatedFile, updatedProgram, originalProgram }; } + + /** @internal */ + revertUpdatedFile(rootFile: string, updatedText: string, originalText: string) { + this.getScriptInfo(rootFile)?.editContent(0, updatedText.length-1, originalText); + this.updateGraph(); + } + + /** @internal */ - getFakeSourceFile(rootFile: string, pastedText: string, _targetFileName: string, targetFileText: string): [] | undefined { + getFakeSourceFile(rootFile: string, formatContext: FormatContext, updatedFile?: SourceFile, updatedProgram?: Program, originalProgram?: Program): FixInfo[] { /** * cscriptInfo.editContent() @@ -2248,16 +2318,17 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo */ //const t = this.getScriptInfo(rootFile); // const scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(rootFile)); - this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); - this.updateGraph(); - const updatedFile = this.program?.getSourceFile(rootFile); - const updatedProgram = this.program; + //this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); + //this.updateGraph(); + //const updatedFile = this.program?.getSourceFile(rootFile); + //const updatedProgram = this.program; - const originalProgram = this.program; + //const originalProgram = this.program; const cancellationToken = this.cancellationToken; const languageServiceHost = this; const preferences = this.projectService.getPreferences(toNormalizedPath(rootFile)); - let allImports:[] | undefined; + let imports: FixInfo[] =[]; + let allImports; if (updatedFile && updatedProgram && originalProgram) { ts.forEachChild(updatedFile, function cb(node) { @@ -2265,19 +2336,15 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo if (!updatedProgram.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { //generate imports - const imports = flatMap(getSymbolNamesToImport(updatedFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { - // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. - if (symbolName === ts.InternalSymbolName.Default) { - return undefined; - } - const isValidTypeOnlyUseSite = ts.isValidTypeOnlyAliasUseSite(node); - const useRequire = shouldUseRequire(updatedFile, originalProgram); - const exportInfo = getExportInfos(symbolName, ts.isJSXTagName(node), ts.getMeaningFromLocation(node), cancellationToken, updatedFile, originalProgram, true, languageServiceHost, preferences); - const t = arrayFrom( - ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes), - fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), - ); - }); + /** + * getImportFixes needs to be called separately and no flat Map is required. + * the 'fix' can be added to something like an array that can be returned and then done something with changes + * *****none of the flatMaps are required***** + */ + const info = tempFunc(updatedFile, updatedProgram, originalProgram, node, languageServiceHost, cancellationToken, preferences, formatContext); + if (info) { + imports = imports.concat(info); + } } } else { @@ -2285,54 +2352,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } }); } - - // const program: Program = ts.createProgram([rootFile], this.getCompilerOptions(), { - // getSourceFile:() => ts.createSourceFile("fake source file", pastedText, { languageVersion: ts.ScriptTarget.ES2015, jsDocParsingMode: JSDocParsingMode.ParseNone }, /*setParentNodes*/ false), - // getDefaultLibFileName: () => ts.getDefaultLibFilePath(this.getCompilerOptions()), - // writeFile: noop, - // getCurrentDirectory: () => this.getCurrentDirectory(), - // getCanonicalFileName: () => "fake source file", - // useCaseSensitiveFileNames: () => true, - // getNewLine: () => "\n", - // fileExists(){return true}, - // readFile() { - // return pastedText; - // } - // }); - // const fakeSourceFile = program.getSourceFile("fake source file"); - // const originalProgram = this.program; - // const cancellationToken = this.cancellationToken; - // const languageServiceHost = this; - // const preferences = this.projectService.getPreferences(toNormalizedPath(rootFile)); - // let imports; - - // if (fakeSourceFile && originalProgram) { - // ts.forEachChild(fakeSourceFile, function cb(node) { - // if (ts.isIdentifier(node)) { - // if (!program.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && - // !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { - // //generate imports - // imports = flatMap(getSymbolNamesToImport(fakeSourceFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { - // // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. - // if (symbolName === ts.InternalSymbolName.Default) { - // return undefined; - // } - // const isValidTypeOnlyUseSite = ts.isValidTypeOnlyAliasUseSite(node); - // const useRequire = shouldUseRequire(fakeSourceFile, originalProgram); - // const exportInfo = getExportInfos(symbolName, ts.isJSXTagName(node), ts.getMeaningFromLocation(node), cancellationToken, fakeSourceFile, originalProgram, true, languageServiceHost, preferences); - // return arrayFrom( - // ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(fakeSourceFile), isValidTypeOnlyUseSite, useRequire, program, fakeSourceFile, languageServiceHost, preferences).fixes), - // fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), - // ); - // }); - // } - // } - // else { - // node.forEachChild(cb); - // } - // }); - // } - return allImports; + return imports; } /** @internal */ @@ -2352,6 +2372,30 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } } +function tempFunc(updatedFile: SourceFile, updatedProgram: Program, originalProgram: Program, node: ts.Identifier, languageServiceHost: Project, cancellationToken: ts.CancellationToken, preferences: ts.UserPreferences, formatContext: FormatContext): +readonly FixInfo[] | undefined { + if (!updatedProgram.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && + !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { + //generate imports + /** + * getImportFixes needs to be called separately and no flat Map is required. + * the 'fix' can be added to something like an array that can be returned and then done something with changes + * *****none of the flatMaps are required***** + */ + const t: ts.CodeFixContextBase = { + sourceFile: updatedFile, + program: originalProgram, + cancellationToken: cancellationToken, + host: languageServiceHost, + preferences: preferences, + formatContext: formatContext + } + const info = getFixesInfoForNonUMDImport(t, node, true); + const packageJsonImportFilter = createPackageJsonImportFilter(updatedFile, preferences, languageServiceHost); + return info && sortFixInfo(info,updatedFile, updatedProgram, packageJsonImportFilter, languageServiceHost); + } +} + function getUnresolvedImports(program: Program, cachedUnresolvedImportsPerFile: Map): SortedReadonlyArray { const sourceFiles = program.getSourceFiles(); tracing?.push(tracing.Phase.Session, "getUnresolvedImports", { count: sourceFiles.length }); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index fe99eb2440307..378d455a7cabe 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -651,7 +651,10 @@ export type GetPostPasteImportFixesRequestArgs = FileLocationOrRangeRequestArgs copyRange?: CopyRange } export interface GetPostPasteImportFixesResponse extends Response { - filename: string; + body: PostPasteImportAction[]; +} +export interface PostPasteImportAction { + edits: FileCodeEdits[]; } /** diff --git a/src/server/session.ts b/src/server/session.ts index bfb054f1c5a7c..510a301249685 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -106,6 +106,7 @@ import { perfLogger, PerformanceEvent, PossibleProgramFileInfo, + PostPasteImportFixes, Program, QuickInfo, RefactorEditInfo, @@ -2796,10 +2797,23 @@ export class Session implements EventSender { return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); } - private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs) { + private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction[] { const { file, project } = this.getFileAndProject(args); const textRange = this.getRange(args.pastes[0].range, project.getScriptInfoForNormalizedPath(file)!); - return project.getLanguageService().getPostPasteImportFixes(args.targetFile, [{text: args.pastes[0].text, range: textRange}], this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); + const result = project.getLanguageService().getPostPasteImportFixes(args.targetFile, [{text: args.pastes[0].text, range: textRange}], this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); + // const seenFiles = new Set(); + // const textChanges: FileTextChanges[] = []; + // for (const textChange of projectTextChanges) { + // if (!seenFiles.has(textChange.fileName)) { + // textChanges.push(textChange); + // } + // } + if (result === undefined) { + return []; + } + const allResults = result.map(postPasteAction => this.mapPostPasteAction(postPasteAction)); + + return allResults; } private organizeImports(args: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): readonly protocol.FileCodeEdits[] | readonly FileTextChanges[] { @@ -2934,6 +2948,10 @@ export class Session implements EventSender { return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription }; } + private mapPostPasteAction({ changes }: PostPasteImportFixes): protocol.PostPasteImportAction { + return { edits: this.mapTextChangesToCodeEdits(changes)}; + } + private mapTextChangesToCodeEdits(textChanges: readonly FileTextChanges[]): protocol.FileCodeEdits[] { return textChanges.map(change => this.mapTextChangeToCodeEdit(change)); } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 295fc31b62c5d..f684c75cd8da0 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -474,7 +474,7 @@ const enum AddAsTypeOnly { NotAllowed = 1 << 2, } type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; -type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; +export type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; // Properties are be undefined if fix is derived from an existing import interface ImportFixBase { @@ -974,7 +974,7 @@ function newImportInfoFromExistingSpecifier( } } -interface FixInfo { +export interface FixInfo { readonly fix: ImportFix; readonly symbolName: string; readonly errorIdentifierText: string | undefined; @@ -1002,7 +1002,7 @@ function getFixInfos(context: CodeFixContextBase, errorCode: number, pos: number return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); } -function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] { +export function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] { const _toPath = (fileName: string) => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)); return sort(fixes, (a, b) => compareBooleans(!!a.isJsxNamespaceFix, !!b.isJsxNamespaceFix) || @@ -1169,7 +1169,7 @@ function getUmdImportKind(importingFile: SourceFile, compilerOptions: CompilerOp } } -function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] | undefined { +export function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] | undefined { const checker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); return flatMap(getSymbolNamesToImport(sourceFile, checker, symbolToken, compilerOptions), symbolName => { @@ -1309,7 +1309,7 @@ function codeActionForFix( }); return createCodeFixAction(importFixName, changes, diag, importFixId, Diagnostics.Add_all_missing_imports); } -function codeActionForFixWorker( +export function codeActionForFixWorker( changes: textChanges.ChangeTracker, sourceFile: SourceFile, symbolName: string, diff --git a/src/services/postPasteImportFix.ts b/src/services/postPasteImportFix.ts index 0484322259dcb..1b905b854908c 100644 --- a/src/services/postPasteImportFix.ts +++ b/src/services/postPasteImportFix.ts @@ -1,9 +1,10 @@ -import { addRange, append } from "../compiler/core"; -import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange } from "../compiler/types"; -import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; -import { codefix, factory, fileShouldUseJavaScriptRequire, formatting, getLineInfo, getQuotePreference, insertImports, nodeSeenTracker, Symbol, textChanges } from "./_namespaces/ts"; +import { addRange, append, arrayFrom, flatMap, flatMapIterator } from "../compiler/core"; +import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange, CancellationToken, InternalSymbolName, ImportClause, ObjectBindingPattern, TypeOnlyAliasDeclaration } from "../compiler/types"; +import { hasSyntacticModifier, isJSXTagName, isValidTypeOnlyAliasUseSite, skipAlias } from "../compiler/utilities"; +import { codefix, Debug, DiagnosticOrDiagnosticAndArguments, factory, fileShouldUseJavaScriptRequire, formatting, getMeaningFromLocation, getQuotePreference, ImportKind, insertImports, nodeSeenTracker, Symbol, SymbolExportInfo, textChanges } from "./_namespaces/ts"; +import { getSymbolNamesToImport, shouldUseRequire, getExportInfos, getImportFixes, codeActionForFixWorker } from "./codefixes/importFixes"; import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; -import { CopyRange, FileTextChanges, LanguageServiceHost } from "./types"; +import { CopyRange, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; /** @internal */ export function postPastImportFixProvider( @@ -13,7 +14,7 @@ export function postPastImportFixProvider( preferences: UserPreferences, formatContext: formatting.FormatContext, originalFile?: SourceFile, - copyLocation?: CopyRange): FileTextChanges[] { + copyLocation?: CopyRange): PostPasteImportFixes[] { /** * When the source file exists @@ -21,32 +22,57 @@ export function postPastImportFixProvider( * 2.use getUsageInfo() to the symbols that need to be imported * 3.use the if and the third part of getTargetFileImportsAndAddExportInOldFile * */ - const { updatedFile, updatedProgram, originalProgram } = host.updatedTargetFile(targetFile.fileName, targetFile.text, pastes[0].text); + //const originalText = targetFile.text; + const { updatedFile, updatedProgram, originalProgram } = host.updateTargetFile(targetFile.fileName, targetFile.text, pastes[0].text); let statements: Statement[] = []; if (originalFile && originalProgram && updatedFile && updatedProgram) { - //addRange(statements, updatedFile?.statements, updatedFile?.statements.length - (targetFileStatements ? targetFileStatements.length : 0) - 1); - //addRange(statements, originalFile?.statements, 2); - //const start = originalFile.statements[0].getStart(originalFile);//addRange(statements, originalFile.statements, updatedFile.statements[updatedFile.statements.length - targetFileStatements.length].getStart(originalFile)) - - //addRange(statements, updatedFile.statements, a.getStart(originalFile), b.getStart(originalFile)); - // const a = updatedFile.statements[updatedFile.getLineAndCharacterOfPosition(pastes[0].range.pos).line] //21 - // const b = updatedFile.statements[updatedFile.getLineAndCharacterOfPosition(pastes[0].range.end).line] //pastes[0].range.end + pastes[0].range.length - 1 - addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation?.end.line); + addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); const usage = getUsageInfo(originalFile, statements, originalProgram.getTypeChecker()); const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); - return textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => getImports(originalFile, updatedFile, statements, updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, - usage.targetFileImportsFromOldFile, changeTracker, preferences, host, updatedProgram.getTypeChecker())); + const changes = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => getImports(originalFile, updatedFile, statements, updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, + usage.targetFileImportsFromOldFile, changeTracker, preferences, host, originalProgram.getTypeChecker())); + host.revertUpdatedFile(targetFile.fileName, updatedFile.text, targetFile.text); + return [{changes}]; } else { - return []; + Debug.assert(updatedFile !== undefined && originalProgram !== undefined); + Debug.assert(updatedProgram !== undefined); + const fixInfo = host.getFakeSourceFile(targetFile.fileName, formatContext, updatedFile, updatedProgram, originalProgram); + const fixes = fixInfo.map(({fix, symbolName}) => getImportsForUnknownSourceFile( + { host, formatContext, preferences }, + updatedFile, + symbolName, + fix, + true, + updatedProgram, + preferences, + )); + host.revertUpdatedFile(targetFile.fileName, updatedFile.text, targetFile.text); + return fixes; } //const unknownSymbols = host.getFakeSourceFile(targetFile,pastes[0].text,targetFile, targetFileText); } +function getImportsForUnknownSourceFile( + context: textChanges.TextChangesContext, + sourceFile: SourceFile, + symbolName: string, + fix: codefix.FixInfo["fix"], + includeSymbolNameInDescription: boolean, + program: Program, + preferences: UserPreferences, +): PostPasteImportFixes { + let diag!: DiagnosticOrDiagnosticAndArguments; + const changes = textChanges.ChangeTracker.with(context, tracker => { + diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, includeSymbolNameInDescription, program, preferences); + }); + return {changes}; +} + function getImports( originalFile: SourceFile, targetFile: SourceFile, @@ -128,3 +154,78 @@ function getTargetFileImportsForKnownOriginalFile( return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)) } +// interface FixInfo { +// readonly fix: ImportFix; +// readonly symbolName: string; +// readonly errorIdentifierText: string | undefined; +// readonly isJsxNamespaceFix?: boolean; +// } +// export function tempFunction(updatedFile: SourceFile, originalProgram: Program, node: Identifier, languageServiceHost: LanguageServiceHost, cancellationToken: CancellationToken, preferences: UserPreferences) { +// return flatMap(getSymbolNamesToImport(updatedFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { +// // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. +// if (symbolName === InternalSymbolName.Default) { +// return undefined; +// } +// const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(node); +// const useRequire = shouldUseRequire(updatedFile, originalProgram); +// const exportInfo = getExportInfos(symbolName, isJSXTagName(node), getMeaningFromLocation(node), cancellationToken, updatedFile, originalProgram, true, languageServiceHost, preferences); +// //const t1 = exportInfo.values(); +// //const fix = ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes); +// return arrayFrom( +// flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes), +// fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), +// ); +// }); + +// } + +// type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; +// type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; + +const enum ImportFixKind { + UseNamespace, + JsdocTypeImport, + AddToExisting, + AddNew, + PromoteTypeOnly, +} +interface ImportFixBase { + readonly isReExport?: boolean; + readonly exportInfo?: SymbolExportInfo; + readonly moduleSpecifier: string; +} +const enum AddAsTypeOnly { + Allowed = 1 << 0, + Required = 1 << 1, + NotAllowed = 1 << 2, +} +interface FixPromoteTypeOnlyImport { + readonly kind: ImportFixKind.PromoteTypeOnly; + readonly typeOnlyAliasDeclaration: TypeOnlyAliasDeclaration; +} +interface Qualification { + readonly usagePosition: number; + readonly namespacePrefix: string; +} +interface FixUseNamespaceImport extends ImportFixBase, Qualification { + readonly kind: ImportFixKind.UseNamespace; +} +// interface FixAddJsdocTypeImport extends ImportFixBase { +// readonly kind: ImportFixKind.JsdocTypeImport; +// readonly usagePosition: number; +// readonly isReExport: boolean; +// readonly exportInfo: SymbolExportInfo; +// } +interface FixAddToExistingImport extends ImportFixBase { + readonly kind: ImportFixKind.AddToExisting; + readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern; + readonly importKind: ImportKind.Default | ImportKind.Named; + readonly addAsTypeOnly: AddAsTypeOnly; +} +interface FixAddNewImport extends ImportFixBase { + readonly kind: ImportFixKind.AddNew; + readonly importKind: ImportKind; + readonly addAsTypeOnly: AddAsTypeOnly; + readonly useRequire: boolean; + readonly qualification?: Qualification; +} \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index e6a90ad61c966..f3581f6a1a0ad 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -321,6 +321,7 @@ import { VariableDeclaration, postPasteImportFixes, CopyRange, + PostPasteImportFixes, } from "./_namespaces/ts"; import * as NavigateTo from "./_namespaces/ts.NavigateTo"; import * as NavigationBar from "./_namespaces/ts.NavigationBar"; @@ -2098,7 +2099,7 @@ export function createLanguageService( formatOptions: FormatCodeSettings, originalFile?: string, copyLocation?: CopyRange - ): FileTextChanges[]{ + ): PostPasteImportFixes[]{ synchronizeHostData(); const originalSourceFile = originalFile ? getValidSourceFile(originalFile) : undefined; const edits = postPasteImportFixes.postPastImportFixProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), originalSourceFile, copyLocation); diff --git a/src/services/types.ts b/src/services/types.ts index b40afb2f71d6e..60f7f53076a3b 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -42,6 +42,8 @@ import { TextSpan, UserPreferences, } from "./_namespaces/ts"; +import { FixInfo } from "./_namespaces/ts.codefix"; +import { FormatContext } from "./formatting/formatting"; declare module "../compiler/types" { // Module transform: converted from interface augmentation @@ -431,8 +433,9 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ getFakeSourceFile(rootFile: string, pastedText: string, targetFileName: string, targetFileText: string) : [] | undefined; - /** @internal */ updatedTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined}; + /** @internal */ getFakeSourceFile(rootFile: string, formatContext: FormatContext, updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined): FixInfo[]; + /** @internal */ updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined}; + /** @internal */ revertUpdatedFile(rootFile: string, updatedText: string, originalText: string): void; //needs to be changed to optional jsDocParsingMode?: JSDocParsingMode | undefined; } @@ -686,7 +689,7 @@ export interface LanguageService { getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; - getPostPasteImportFixes (targetFile: string, pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatOptions: FormatCodeSettings, originalFile: string | undefined, copyLocation: CopyRange | undefined): FileTextChanges[]; + getPostPasteImportFixes (targetFile: string, pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatOptions: FormatCodeSettings, originalFile: string | undefined, copyLocation: CopyRange | undefined): PostPasteImportFixes[]; } export interface CopyRange { @@ -714,10 +717,11 @@ export const enum OrganizeImportsMode { RemoveUnused = "RemoveUnused", } -export interface postPasteImportFix { - targetFile: string, - targetFileText: string, - pastes: Array<{text: string; range: TextSpan}> +export interface PostPasteImportFixes { + // targetFile: string, + // targetFileText: string, + // pastes: Array<{text: string; range: TextSpan}> + changes: FileTextChanges[]; } export interface OrganizeImportsArgs extends CombinedCodeFixScope { diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 6722b3ef4b31e..105430b8d9feb 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -453,6 +453,7 @@ declare namespace FourSlashInterface { commentSelection(newFileContent: string): void; uncommentSelection(newFileContent: string): void; postPasteImportFix(options: { + newFileContents: { readonly [fileName: string]: string }; targetFile: string, pastes: Array<{text: string; range: {pos: number, end: number}}> originalFile?: string, diff --git a/tests/cases/fourslash/server/postPasteImportFix1.ts b/tests/cases/fourslash/server/postPasteImportFix1.ts index 2918b3d89a660..9f86b05928142 100644 --- a/tests/cases/fourslash/server/postPasteImportFix1.ts +++ b/tests/cases/fourslash/server/postPasteImportFix1.ts @@ -1,18 +1,19 @@ /// -// @Filename: file1.ts +// @Filename: /file1.ts //// export interface Test1 {} //// export interface Test2 {} //// export interface Test3 {} //// export interface Test4 {} -// @Filename: file2.ts +// @Filename: /file2.ts //// /*a*/const a = 10;/*b*/ -// @Filename: tsconfig.json +// @Filename: /tsconfig.json ////{ "files": ["file1.ts", "file2.ts"] } goTo.select("a", "b"); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFix({ targetFile: "file2.ts", pastes: [{ @@ -23,6 +24,18 @@ verify.postPasteImportFix({ test3: Test3; test4: Test4; }`, - range: { pos: 0, end: 54 }, + range: { pos: 0, end: 12 }, }], + newFileContents: { + "/file2.ts": +`import { Test1, Test2, Test3, Test4 } from './file1' + +const a = 10; +interface Testing { + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; +}` + } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix3.ts b/tests/cases/fourslash/server/postPasteImportFix3.ts index 2472277f67f65..c51259a35b45a 100644 --- a/tests/cases/fourslash/server/postPasteImportFix3.ts +++ b/tests/cases/fourslash/server/postPasteImportFix3.ts @@ -1,22 +1,23 @@ /// -// @Filename: file1.ts +// @Filename: /file1.ts ////export const b = 2; -// @Filename: file2.ts -////import { b } from './other'; +// @Filename: /file2.ts +////import { b } from './file1'; ////const a = 1; ////const c = a + b; ////const t = 9; -// @Filename: file3.ts +// @Filename: /file3.ts //// /*a*/export const tt = 2;/*b*/ //// function f(); -// @Filename: tsconfig.json +// @Filename: /tsconfig.json ////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } goTo.select("a", "b"); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFix({ targetFile: "file3.ts", pastes: [{ @@ -24,8 +25,27 @@ verify.postPasteImportFix({ const c = a + b; const t = 9; function f();`, - range: { pos: 20, end: 29 }, + range: { pos: 20, end: 22 }, }], originalFile: "file2.ts", - copyRange: { start: { line : 3, offset: 0}, end : { line: 4, offset: 21}}, + copyRange: { start: { line : 2, offset: 0}, end : { line: 3, offset: 0}}, + newFileContents: { + "/file2.ts": +`import { b } from './file1'; +export const a = 1; +const c = a + b; +const t = 9;`, + + "/file3.ts": +`import { a } from "./file2"; + +import { b } from './file1'; + +export const tt = 2; +function f(); +const c = a + b; +const t = 9; + +`, + } }); \ No newline at end of file From 17f9897a8f00958f8f8c66b80e59c4ffc9b0f2bb Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 1 Feb 2024 10:54:37 -0800 Subject: [PATCH 03/41] Allows different text in each cursor location --- src/harness/client.ts | 28 +-- src/harness/fourslashImpl.ts | 6 +- src/harness/fourslashInterfaceImpl.ts | 2 +- src/server/project.ts | 92 +------- src/server/protocol.ts | 2 +- src/server/session.ts | 16 +- src/services/codefixes/importFixes.ts | 15 +- src/services/postPasteImportFix.ts | 218 +++++------------- src/services/services.ts | 4 +- src/services/types.ts | 10 +- ...portNameCodeFix_add_all_missing_imports.ts | 9 +- .../fourslash/server/postPasteImportFix2.ts | 38 --- ... => postPasteImportFix_knownSourceFile.ts} | 21 +- .../postPasteImportFix_multiplePastes1.ts | 46 ++++ .../postPasteImportFix_multiplePastes2.ts | 50 ++++ ...> postPasteImportFix_unknownSourceFile.ts} | 22 +- 16 files changed, 230 insertions(+), 349 deletions(-) delete mode 100644 tests/cases/fourslash/server/postPasteImportFix2.ts rename tests/cases/fourslash/server/{postPasteImportFix3.ts => postPasteImportFix_knownSourceFile.ts} (69%) create mode 100644 tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts rename tests/cases/fourslash/server/{postPasteImportFix1.ts => postPasteImportFix_unknownSourceFile.ts} (64%) diff --git a/src/harness/client.ts b/src/harness/client.ts index c89433352209d..220cf4548dc0b 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1,5 +1,6 @@ import { ApplicableRefactorInfo, + arrayFrom, CallHierarchyIncomingCall, CallHierarchyItem, CallHierarchyOutgoingCall, @@ -1011,33 +1012,20 @@ export class SessionClient implements LanguageService { return getSupportedCodeFixes(); } - getPostPasteImportFixes(targetFile: string, pastes: Array<{text: string; range: TextRange}>, _preferences: UserPreferences, _formatOptions: FormatCodeSettings, originalFile?: string, copyRange?: CopyRange): PostPasteImportFixes[]{ - const t = this.createFileRangeRequestArgs(targetFile, pastes[0].range.pos, pastes[0].range.end); - const args = this.createFileLocationOrRangeRequestArgs(pastes[0].range, targetFile) as protocol.GetPostPasteImportFixesRequestArgs; //needs to be fixed + getPostPasteImportFixes(targetFile: string, pastes: Array<{text: string; range: TextRange}>, _preferences: UserPreferences, _formatOptions: FormatCodeSettings, originalFile?: string, copyRange?: CopyRange): PostPasteImportFixes{ + const args = this.createFileLocationOrRangeRequestArgs(pastes[0].range, targetFile) as protocol.GetPostPasteImportFixesRequestArgs; args.targetFile = targetFile; - args.pastes = [{text: pastes[0].text, range: t}]; + args.pastes = arrayFrom(pastes.map(paste => ({text: paste.text, range: this.createFileRangeRequestArgs(targetFile, paste.range.pos, paste.range.end)}))); args.originalFile = originalFile; args.copyRange = copyRange; - + const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); if (!response.body) { - return []; + return { edits: []}; } - - // return response.body!.map(({ fixName, description, changes, commands, fixId, fixAllDescription }) => // TODO: GH#18217 - // ({ fixName, description, changes: this.convertChanges(changes, file), commands: commands as CodeActionCommand[], fixId, fixAllDescription })); - - //const q = response.body.map(({changes}) => ({this.convertChanges(changes, targetFile)})); - //const r: FileTextChanges[] = response.body.map(item =>({changes: this.convertCodeEditsToTextChanges(item.edits)})); - /////////const q = response.body.map(item =>this.convertCodeEditsToTextChanges(item.edits)); - const e = response.body.map(item => ({changes: this.convertCodeEditsToTextChanges(item.edits)})) - // let allEdits: FileTextChanges[] = []; - // for (const edits of response.body) { - // allEdits = this.convertCodeEditsToTextChanges(edits); - // } - // const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body); - return e; + const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); + return { edits: edits }; } getProgram(): Program { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 05e9b675a0a63..f138c93fdf45c 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3554,11 +3554,9 @@ export class TestState { assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers); } - public getPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void{ - const range = this.getSelection(); - //const range: ts.TextRange = {pos: pastes[0].range.pos, end: pastes[0].range.end}; + public verifyPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void{ const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.originalFile, options.copyRange); - this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo[0].changes); + this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) { diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index a3d92dd98f6d5..f1d97d4661fb0 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -622,7 +622,7 @@ export class Verify extends VerifyNegatable { } public postPasteImportFix(options: PostPasteImportFixOptions): void { - this.state.getPostPasteImportFixes(options); + this.state.verifyPostPasteImportFixes(options); } } diff --git a/src/server/project.ts b/src/server/project.ts index 18c642b1cd67f..0056f6fb6e2d2 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2275,30 +2275,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return this.noDtsResolutionProject; } - // export anotherGetFixes(updatedFile: ts.SourceFile, originalProgram: ts.Program, node: ts.Identifier, languageServiceHost: this, cancellationToken: ts.CancellationToken, preferences: ts.UserPreferences) { - // const imports = flatMap(getSymbolNamesToImport(updatedFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { - // // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. - // if (symbolName === ts.InternalSymbolName.Default) { - // return undefined; - // } - // const isValidTypeOnlyUseSite = ts.isValidTypeOnlyAliasUseSite(node); - // const useRequire = shouldUseRequire(updatedFile, originalProgram); - // const exportInfo = getExportInfos(symbolName, ts.isJSXTagName(node), ts.getMeaningFromLocation(node), cancellationToken, updatedFile, originalProgram, true, languageServiceHost, preferences); - // return arrayFrom( - // ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes), - // fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), - // ); - // } - // } - /** @internal */ updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined} { const originalProgram = this.program; this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length-1, pastedText); this.updateGraph(); - const updatedFile = this.program?.getSourceFile(rootFile); - const updatedProgram = this.program; - return { updatedFile, updatedProgram, originalProgram }; + return { updatedFile: (this.program?.getSourceFile(rootFile)), updatedProgram: this.program, originalProgram }; } /** @internal */ @@ -2307,54 +2289,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo this.updateGraph(); } - - /** @internal */ - getFakeSourceFile(rootFile: string, formatContext: FormatContext, updatedFile?: SourceFile, updatedProgram?: Program, originalProgram?: Program): FixInfo[] { - - /** - * cscriptInfo.editContent() - * project.updateGraph gives the new SF - * after scriptInfo.editContent("") the new SF is not updated - */ - //const t = this.getScriptInfo(rootFile); - // const scriptInfo = this.projectService.getScriptInfoForPath(this.toPath(rootFile)); - //this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); - //this.updateGraph(); - //const updatedFile = this.program?.getSourceFile(rootFile); - //const updatedProgram = this.program; - - //const originalProgram = this.program; - const cancellationToken = this.cancellationToken; - const languageServiceHost = this; - const preferences = this.projectService.getPreferences(toNormalizedPath(rootFile)); - let imports: FixInfo[] =[]; - let allImports; - - if (updatedFile && updatedProgram && originalProgram) { - ts.forEachChild(updatedFile, function cb(node) { - if (ts.isIdentifier(node)) { - if (!updatedProgram.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && - !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { - //generate imports - /** - * getImportFixes needs to be called separately and no flat Map is required. - * the 'fix' can be added to something like an array that can be returned and then done something with changes - * *****none of the flatMaps are required***** - */ - const info = tempFunc(updatedFile, updatedProgram, originalProgram, node, languageServiceHost, cancellationToken, preferences, formatContext); - if (info) { - imports = imports.concat(info); - } - } - } - else { - node.forEachChild(cb); - } - }); - } - return imports; - } - /** @internal */ private getCompilerOptionsForNoDtsResolutionProject() { return { @@ -2372,30 +2306,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } } -function tempFunc(updatedFile: SourceFile, updatedProgram: Program, originalProgram: Program, node: ts.Identifier, languageServiceHost: Project, cancellationToken: ts.CancellationToken, preferences: ts.UserPreferences, formatContext: FormatContext): -readonly FixInfo[] | undefined { - if (!updatedProgram.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ true) && - !originalProgram?.getTypeChecker().resolveName(node.text, node, ts.SymbolFlags.All, /*excludeGlobals*/ false)) { - //generate imports - /** - * getImportFixes needs to be called separately and no flat Map is required. - * the 'fix' can be added to something like an array that can be returned and then done something with changes - * *****none of the flatMaps are required***** - */ - const t: ts.CodeFixContextBase = { - sourceFile: updatedFile, - program: originalProgram, - cancellationToken: cancellationToken, - host: languageServiceHost, - preferences: preferences, - formatContext: formatContext - } - const info = getFixesInfoForNonUMDImport(t, node, true); - const packageJsonImportFilter = createPackageJsonImportFilter(updatedFile, preferences, languageServiceHost); - return info && sortFixInfo(info,updatedFile, updatedProgram, packageJsonImportFilter, languageServiceHost); - } -} - function getUnresolvedImports(program: Program, cachedUnresolvedImportsPerFile: Map): SortedReadonlyArray { const sourceFiles = program.getSourceFiles(); tracing?.push(tracing.Phase.Session, "getUnresolvedImports", { count: sourceFiles.length }); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 378d455a7cabe..3d957c3f0db7e 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -651,7 +651,7 @@ export type GetPostPasteImportFixesRequestArgs = FileLocationOrRangeRequestArgs copyRange?: CopyRange } export interface GetPostPasteImportFixesResponse extends Response { - body: PostPasteImportAction[]; + body: PostPasteImportAction; } export interface PostPasteImportAction { edits: FileCodeEdits[]; diff --git a/src/server/session.ts b/src/server/session.ts index 510a301249685..62fe53833ad75 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2797,10 +2797,11 @@ export class Session implements EventSender { return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); } - private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction[] { + private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - const textRange = this.getRange(args.pastes[0].range, project.getScriptInfoForNormalizedPath(file)!); - const result = project.getLanguageService().getPostPasteImportFixes(args.targetFile, [{text: args.pastes[0].text, range: textRange}], this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); + //const pastes: Array<{text: string; range: TextRange}> = arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange(paste.range, project.getScriptInfoForNormalizedPath(file)!)})); + //const textRange = this.getRange(args.pastes[0].range, project.getScriptInfoForNormalizedPath(file)!); + const result = project.getLanguageService().getPostPasteImportFixes(args.targetFile, arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange(paste.range, project.getScriptInfoForNormalizedPath(file)!)})), this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); // const seenFiles = new Set(); // const textChanges: FileTextChanges[] = []; // for (const textChange of projectTextChanges) { @@ -2809,9 +2810,10 @@ export class Session implements EventSender { // } // } if (result === undefined) { - return []; + return undefined; } - const allResults = result.map(postPasteAction => this.mapPostPasteAction(postPasteAction)); + //const allResults = result.map(postPasteAction => this.mapPostPasteAction(postPasteAction)); + const allResults = this.mapPostPasteAction(result); return allResults; } @@ -2948,8 +2950,8 @@ export class Session implements EventSender { return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription }; } - private mapPostPasteAction({ changes }: PostPasteImportFixes): protocol.PostPasteImportAction { - return { edits: this.mapTextChangesToCodeEdits(changes)}; + private mapPostPasteAction({ edits }: PostPasteImportFixes): protocol.PostPasteImportAction { + return { edits: this.mapTextChangesToCodeEdits(edits)}; } private mapTextChangesToCodeEdits(textChanges: readonly FileTextChanges[]): protocol.FileCodeEdits[] { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index f684c75cd8da0..0e1131f6ef91f 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -212,6 +212,7 @@ export interface ImportAdder { addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void; addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) => void; writeFixes: (changeTracker: textChanges.ChangeTracker, oldFileQuotePreference?: QuotePreference) => void; + addImportsForUnknownSymbols: (context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) => void; } /** @internal */ @@ -236,8 +237,14 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu type NewImportsKey = `${0 | 1}|${string}`; /** Use `getNewImportEntry` for access */ const newImports = new Map>(); - return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes }; + return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes, addImportsForUnknownSymbols }; + function addImportsForUnknownSymbols(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) { + const info = getFixInfosWithoutDiagnostic(context, symbolToken, useAutoImportProvider); + if (!info || !info.length) return; + addImport(first(info)); + } + function addImportFromDiagnostic(diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) { const info = getFixInfos(context, diagnostic.code, diagnostic.start, useAutoImportProvider); if (!info || !info.length) return; @@ -1010,6 +1017,12 @@ export function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModul compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, packageJsonImportFilter.allowsImportingSpecifier, _toPath)); } +function getFixInfosWithoutDiagnostic(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly FixInfo[] | undefined { + const info = getFixesInfoForNonUMDImport(context, symbolToken, useAutoImportProvider); + const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host); + return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); +} + function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined { if (!some(fixes)) return; // These will always be placed first if available, and are better than other kinds diff --git a/src/services/postPasteImportFix.ts b/src/services/postPasteImportFix.ts index 1b905b854908c..7c0340d1ea715 100644 --- a/src/services/postPasteImportFix.ts +++ b/src/services/postPasteImportFix.ts @@ -1,10 +1,9 @@ -import { addRange, append, arrayFrom, flatMap, flatMapIterator } from "../compiler/core"; -import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange, CancellationToken, InternalSymbolName, ImportClause, ObjectBindingPattern, TypeOnlyAliasDeclaration } from "../compiler/types"; -import { hasSyntacticModifier, isJSXTagName, isValidTypeOnlyAliasUseSite, skipAlias } from "../compiler/utilities"; -import { codefix, Debug, DiagnosticOrDiagnosticAndArguments, factory, fileShouldUseJavaScriptRequire, formatting, getMeaningFromLocation, getQuotePreference, ImportKind, insertImports, nodeSeenTracker, Symbol, SymbolExportInfo, textChanges } from "./_namespaces/ts"; -import { getSymbolNamesToImport, shouldUseRequire, getExportInfos, getImportFixes, codeActionForFixWorker } from "./codefixes/importFixes"; +import { addRange, append } from "../compiler/core"; +import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange, CancellationToken, ImportClause, ObjectBindingPattern, TypeOnlyAliasDeclaration, SymbolFlags } from "../compiler/types"; +import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; +import { codefix, Debug, factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, ImportKind, insertImports, nodeSeenTracker, Symbol, SymbolExportInfo, textChanges, isIdentifier } from "./_namespaces/ts"; import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; -import { CopyRange, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; +import { CodeFixContextBase, CopyRange, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; /** @internal */ export function postPastImportFixProvider( @@ -13,88 +12,74 @@ export function postPastImportFixProvider( pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatContext: formatting.FormatContext, + cancellationToken: CancellationToken, originalFile?: SourceFile, - copyLocation?: CopyRange): PostPasteImportFixes[] { + copyLocation?: CopyRange): PostPasteImportFixes { - /** - * When the source file exists - * 1.Need to turn pasted text, in pastes.text into statements - * 2.use getUsageInfo() to the symbols that need to be imported - * 3.use the if and the third part of getTargetFileImportsAndAddExportInOldFile - * */ - //const originalText = targetFile.text; - const { updatedFile, updatedProgram, originalProgram } = host.updateTargetFile(targetFile.fileName, targetFile.text, pastes[0].text); - let statements: Statement[] = []; - - if (originalFile && originalProgram && updatedFile && updatedProgram) { - addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); - const usage = getUsageInfo(originalFile, statements, originalProgram.getTypeChecker()); - const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); - - const changes = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => getImports(originalFile, updatedFile, statements, updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, - usage.targetFileImportsFromOldFile, changeTracker, preferences, host, originalProgram.getTypeChecker())); - host.revertUpdatedFile(targetFile.fileName, updatedFile.text, targetFile.text); - return [{changes}]; - } - else { - Debug.assert(updatedFile !== undefined && originalProgram !== undefined); - Debug.assert(updatedProgram !== undefined); - const fixInfo = host.getFakeSourceFile(targetFile.fileName, formatContext, updatedFile, updatedProgram, originalProgram); - const fixes = fixInfo.map(({fix, symbolName}) => getImportsForUnknownSourceFile( - { host, formatContext, preferences }, - updatedFile, - symbolName, - fix, - true, - updatedProgram, - preferences, - )); - host.revertUpdatedFile(targetFile.fileName, updatedFile.text, targetFile.text); - return fixes; - } - - - //const unknownSymbols = host.getFakeSourceFile(targetFile,pastes[0].text,targetFile, targetFileText); + let changes: FileTextChanges[] = []; + changes = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => pastes.forEach(({text, range}) => + { postPasteFixes(targetFile, host, text, range, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)})); + return { edits: changes }; } -function getImportsForUnknownSourceFile( - context: textChanges.TextChangesContext, - sourceFile: SourceFile, - symbolName: string, - fix: codefix.FixInfo["fix"], - includeSymbolNameInDescription: boolean, - program: Program, +function postPasteFixes ( + targetFile: SourceFile, + host: LanguageServiceHost, + pastedText: string, + pastedRange: TextRange, preferences: UserPreferences, -): PostPasteImportFixes { - let diag!: DiagnosticOrDiagnosticAndArguments; - const changes = textChanges.ChangeTracker.with(context, tracker => { - diag = codeActionForFixWorker(tracker, sourceFile, symbolName, fix, includeSymbolNameInDescription, program, preferences); - }); - return {changes}; -} - -function getImports( - originalFile: SourceFile, - targetFile: SourceFile, - statements: Statement[], - program: Program, - importAdder: codefix.ImportAdder, - importsToCopy: Map, - targetFileImportsFromOldFile: Set, + formatContext: formatting.FormatContext, + cancellationToken: CancellationToken, changes: textChanges.ChangeTracker, - preferences: UserPreferences, - host: LanguageServiceHost, - checker: TypeChecker) { + originalFile?: SourceFile, + copyLocation?: CopyRange) { + + const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastedRange.pos) + pastedText + targetFile.getText().slice(0, pastedRange.end)); + let statements: Statement[] = []; + Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); + + if (originalFile) { + addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); + const usage = getUsageInfo(originalFile, statements, updatedTargetFile.originalProgram.getTypeChecker()); + const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); - const imports = getTargetFileImportsForKnownOriginalFile(originalFile, targetFile, program, importAdder, importsToCopy, targetFileImportsFromOldFile, changes, preferences, host, checker); - if (imports.length > 0) { - insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); + const imports = getImportsFromKnownOriginalFile(originalFile, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); + if (imports.length > 0) { + insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); + } + importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); + changes.replaceRangeWithText(targetFile, pastedRange, pastedText); + host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); + } + else { + const context: CodeFixContextBase = { + sourceFile: updatedTargetFile.updatedFile, + program: updatedTargetFile.originalProgram, + cancellationToken: cancellationToken, + host: host, + preferences: preferences, + formatContext: formatContext + } + const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); + forEachChild(updatedTargetFile.updatedFile, function cb(node) { + if (isIdentifier(node)) { + if (!updatedTargetFile.updatedProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ true) && + !updatedTargetFile.originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { + //generate imports + importAdder.addImportsForUnknownSymbols(context, node, /*useAutoImportProvider*/ true); + } + } + else { + node.forEachChild(cb); + } + }); + changes.replaceRangeWithText(targetFile, pastedRange, pastedText); + importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); + host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } - importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); - changes.insertNodesAtEndOfFile(targetFile, statements, true); //NEEDS TO BE FIXED!!!!!!!!!!!! } -function getTargetFileImportsForKnownOriginalFile( +function getImportsFromKnownOriginalFile( originalFile: SourceFile, targetFile: SourceFile, program: Program, @@ -111,7 +96,7 @@ function getTargetFileImportsForKnownOriginalFile( importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); } catch { - for (const oldStatement of originalFile.statements) { //might be changed to just statements, meaning that the updated statements in the target file + for (const oldStatement of originalFile.statements) { forEachImportInStatement(oldStatement, i => { append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); }); @@ -153,79 +138,4 @@ function getTargetFileImportsForKnownOriginalFile( }); return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)) -} -// interface FixInfo { -// readonly fix: ImportFix; -// readonly symbolName: string; -// readonly errorIdentifierText: string | undefined; -// readonly isJsxNamespaceFix?: boolean; -// } -// export function tempFunction(updatedFile: SourceFile, originalProgram: Program, node: Identifier, languageServiceHost: LanguageServiceHost, cancellationToken: CancellationToken, preferences: UserPreferences) { -// return flatMap(getSymbolNamesToImport(updatedFile, originalProgram.getTypeChecker(), node, originalProgram.getCompilerOptions()), symbolName => { -// // "default" is a keyword and not a legal identifier for the import, but appears as an identifier. -// if (symbolName === InternalSymbolName.Default) { -// return undefined; -// } -// const isValidTypeOnlyUseSite = isValidTypeOnlyAliasUseSite(node); -// const useRequire = shouldUseRequire(updatedFile, originalProgram); -// const exportInfo = getExportInfos(symbolName, isJSXTagName(node), getMeaningFromLocation(node), cancellationToken, updatedFile, originalProgram, true, languageServiceHost, preferences); -// //const t1 = exportInfo.values(); -// //const fix = ts.flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes); -// return arrayFrom( -// flatMapIterator(exportInfo.values(), exportInfos => getImportFixes(exportInfos, node.getStart(updatedFile), isValidTypeOnlyUseSite, useRequire, originalProgram, updatedFile, languageServiceHost, preferences).fixes), -// fix => ({ fix, symbolName, errorIdentifierText: node.text, isJsxNamespaceFix: symbolName !== node.text }), -// ); -// }); - -// } - -// type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; -// type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; - -const enum ImportFixKind { - UseNamespace, - JsdocTypeImport, - AddToExisting, - AddNew, - PromoteTypeOnly, -} -interface ImportFixBase { - readonly isReExport?: boolean; - readonly exportInfo?: SymbolExportInfo; - readonly moduleSpecifier: string; -} -const enum AddAsTypeOnly { - Allowed = 1 << 0, - Required = 1 << 1, - NotAllowed = 1 << 2, -} -interface FixPromoteTypeOnlyImport { - readonly kind: ImportFixKind.PromoteTypeOnly; - readonly typeOnlyAliasDeclaration: TypeOnlyAliasDeclaration; -} -interface Qualification { - readonly usagePosition: number; - readonly namespacePrefix: string; -} -interface FixUseNamespaceImport extends ImportFixBase, Qualification { - readonly kind: ImportFixKind.UseNamespace; -} -// interface FixAddJsdocTypeImport extends ImportFixBase { -// readonly kind: ImportFixKind.JsdocTypeImport; -// readonly usagePosition: number; -// readonly isReExport: boolean; -// readonly exportInfo: SymbolExportInfo; -// } -interface FixAddToExistingImport extends ImportFixBase { - readonly kind: ImportFixKind.AddToExisting; - readonly importClauseOrBindingPattern: ImportClause | ObjectBindingPattern; - readonly importKind: ImportKind.Default | ImportKind.Named; - readonly addAsTypeOnly: AddAsTypeOnly; -} -interface FixAddNewImport extends ImportFixBase { - readonly kind: ImportFixKind.AddNew; - readonly importKind: ImportKind; - readonly addAsTypeOnly: AddAsTypeOnly; - readonly useRequire: boolean; - readonly qualification?: Qualification; } \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index f3581f6a1a0ad..f622a742989d5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2099,10 +2099,10 @@ export function createLanguageService( formatOptions: FormatCodeSettings, originalFile?: string, copyLocation?: CopyRange - ): PostPasteImportFixes[]{ + ): PostPasteImportFixes{ synchronizeHostData(); const originalSourceFile = originalFile ? getValidSourceFile(originalFile) : undefined; - const edits = postPasteImportFixes.postPastImportFixProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), originalSourceFile, copyLocation); + const edits = postPasteImportFixes.postPastImportFixProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host),cancellationToken, originalSourceFile, copyLocation); return edits; } diff --git a/src/services/types.ts b/src/services/types.ts index 60f7f53076a3b..73c915a1fccb8 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -433,10 +433,8 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ getFakeSourceFile(rootFile: string, formatContext: FormatContext, updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined): FixInfo[]; - /** @internal */ updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined}; - /** @internal */ revertUpdatedFile(rootFile: string, updatedText: string, originalText: string): void; -//needs to be changed to optional + /** @internal */ updateTargetFile?(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined }; + /** @internal */ revertUpdatedFile?(rootFile: string, updatedText: string, originalText: string): void; jsDocParsingMode?: JSDocParsingMode | undefined; } @@ -689,7 +687,7 @@ export interface LanguageService { getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; - getPostPasteImportFixes (targetFile: string, pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatOptions: FormatCodeSettings, originalFile: string | undefined, copyLocation: CopyRange | undefined): PostPasteImportFixes[]; + getPostPasteImportFixes (targetFile: string, pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatOptions: FormatCodeSettings, originalFile: string | undefined, copyLocation: CopyRange | undefined): PostPasteImportFixes; } export interface CopyRange { @@ -721,7 +719,7 @@ export interface PostPasteImportFixes { // targetFile: string, // targetFileText: string, // pastes: Array<{text: string; range: TextSpan}> - changes: FileTextChanges[]; + edits: readonly FileTextChanges[]; } export interface OrganizeImportsArgs extends CombinedCodeFixScope { diff --git a/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts b/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts index 524a4979f1bc7..0386beb369950 100644 --- a/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts +++ b/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts @@ -2,15 +2,19 @@ // @Filename: /a.ts ////export const a: number; - +////export const k: number; // @Filename: /b.ts ////export const b: number; // @Filename: /c.ts ////export const c: number; +// @Filename: /d.ts +////export const k: number; + // @Filename: /main.ts ////a; +////k; ////b; ////c; @@ -19,11 +23,12 @@ verify.codeFixAll({ fixId: "fixMissingImport", fixAllDescription: "Add all missing imports", newFileContent: -`import { a } from "./a"; +`import { a, k } from "./a"; import { b } from "./b"; import { c } from "./c"; a; +k; b; c;`, }); diff --git a/tests/cases/fourslash/server/postPasteImportFix2.ts b/tests/cases/fourslash/server/postPasteImportFix2.ts deleted file mode 100644 index e5385136e07de..0000000000000 --- a/tests/cases/fourslash/server/postPasteImportFix2.ts +++ /dev/null @@ -1,38 +0,0 @@ -/// - -// @Filename: file1.ts -//// export interface Test1 {} -//// export interface Test2 {} -//// export interface Test3 {} -//// export interface Test4 {} - -// @Filename: file2.ts -//// import { Test1, Test2, Test3, Test4 } from './file1'; -//// interface Testing { -//// test1: Test1; -//// test2: Test2; -//// test3: Test3; -//// test4: Test4; -//// } - -// @Filename: file3.ts -//// /*a*/const a = 10;/*b*/ - -// @Filename: tsconfig.json -////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } - -goTo.select("a", "b"); -verify.postPasteImportFix({ - targetFile: "file3.ts", - pastes: [{ - text: `const a = 10; - interface Testing { - test1: Test1; - test2: Test2; - test3: Test3; - test4: Test4; - }`, - range: { pos: 13, end: 54 }, - }], - originalFile: "file2.ts", -}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix3.ts b/tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts similarity index 69% rename from tests/cases/fourslash/server/postPasteImportFix3.ts rename to tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts index c51259a35b45a..3e7c621ba2a54 100644 --- a/tests/cases/fourslash/server/postPasteImportFix3.ts +++ b/tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts @@ -9,23 +9,22 @@ ////const c = a + b; ////const t = 9; -// @Filename: /file3.ts +// @Filename: /target.ts //// /*a*/export const tt = 2;/*b*/ //// function f(); +//// const p = 1; // @Filename: /tsconfig.json -////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } +////{ "files": ["file1.ts", "file2.ts", "target.ts"] } goTo.select("a", "b"); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFix({ - targetFile: "file3.ts", + targetFile: "target.ts", pastes: [{ - text: `export const tt = 2; - const c = a + b; - const t = 9; - function f();`, - range: { pos: 20, end: 22 }, + text: `const c = a + b; +const t = 9;`, + range: { pos: 21, end: 34 }, }], originalFile: "file2.ts", copyRange: { start: { line : 2, offset: 0}, end : { line: 3, offset: 0}}, @@ -36,16 +35,14 @@ export const a = 1; const c = a + b; const t = 9;`, - "/file3.ts": + "/target.ts": `import { a } from "./file2"; import { b } from './file1'; export const tt = 2; -function f(); const c = a + b; const t = 9; - -`, +const p = 1;`, } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts new file mode 100644 index 0000000000000..2b449267be050 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts @@ -0,0 +1,46 @@ +/// + +// @Filename: /file1.ts +//// export const p = 10; +//// export const q = 12; + +// @Filename: /file3.ts +//// export const r = 10; +//// export const s = 12; + +// @Filename: /file2.ts +//// /*a*/const a = 1; +//// /*b*/const b = 2; +//// const c = 3; +//// const d = 4; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } + +goTo.select("a", "b"); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFix({ + targetFile: "file2.ts", + pastes: [{ + text: `const g = p + q;\n`, + range: { pos: 13, end: 26 }, + }, + { + text: `function e(); +const f = r + s;`, + range: { pos: 39, end: 51 }, + + }], + newFileContents: { + "/file2.ts": +`import { p, q } from "./file1"; + +import { r, s } from "./file3"; + +const a = 1; +const g = p + q; +const c = 3; +function e(); +const f = r + s;` + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts new file mode 100644 index 0000000000000..df8927fa64c5a --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts @@ -0,0 +1,50 @@ +/// + +// @Filename: /file1.ts +//// import { aa, bb } from "./other"; +//// export const r = 10; +//// export const s = 12; +//// export const t = aa + bb + r + s; +//// const u = 1; + +// @Filename: /target.ts +//// /*a*/const a = 1; +//// /*b*/const b = 2; +//// const c = 3; +//// const d = 4; + +// @Filename: /other.ts +//// export const aa = 1; +//// export const bb = 2; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "target.ts", "other.ts"] } + +goTo.select("a", "b"); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFix({ + targetFile: "target.ts", + pastes: [{ + text: `export const t = aa + bb + r + s;\n +const u = 1;`, + range: { pos: 13, end: 26 }, + }, + { + text: `export const t = aa + bb + r + s;\n +const u = 1;`, + range: { pos: 39, end: 51 }, + + }], + newFileContents: { + "/target.ts": +`import { r, s } from "./file1"; +import { aa, bb } from "./other"; + +const a = 1; +export const t = aa + bb + r + s; +const c = 3; +const u = 1;` + }, + originalFile: "file1.ts", + copyRange: { start: { line : 3, offset: 0}, end : { line: 4, offset: 12}}, +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix1.ts b/tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts similarity index 64% rename from tests/cases/fourslash/server/postPasteImportFix1.ts rename to tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts index 9f86b05928142..74181e4a5c1eb 100644 --- a/tests/cases/fourslash/server/postPasteImportFix1.ts +++ b/tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts @@ -7,7 +7,9 @@ //// export interface Test4 {} // @Filename: /file2.ts -//// /*a*/const a = 10;/*b*/ +//// /*a*/const a = 10; +//// /*b*/const b = 10; +//// const c = 10; // @Filename: /tsconfig.json ////{ "files": ["file1.ts", "file2.ts"] } @@ -17,25 +19,25 @@ format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFix({ targetFile: "file2.ts", pastes: [{ - text: `const a = 10; - interface Testing { + text: `interface Testing { test1: Test1; test2: Test2; test3: Test3; test4: Test4; }`, - range: { pos: 0, end: 12 }, + range: { pos: 14, end: 27 }, }], newFileContents: { "/file2.ts": -`import { Test1, Test2, Test3, Test4 } from './file1' +`import { Test1, Test2, Test3, Test4 } from "./file1"; const a = 10; interface Testing { - test1: Test1; - test2: Test2; - test3: Test3; - test4: Test4; -}` + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; + } +const c = 10;` } }); \ No newline at end of file From 64da77e12f285a345134d1c800e75ee94a51a83d Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 1 Feb 2024 11:27:00 -0800 Subject: [PATCH 04/41] working changes --- src/server/session.ts | 11 - src/services/postPasteImportFix.ts | 16 +- .../postPasteImportFix_knownSourceFile.js | 347 +++++++++++++++++ .../postPasteImportFix_multiplePastes1.js | 327 ++++++++++++++++ .../postPasteImportFix_multiplePastes2.js | 356 ++++++++++++++++++ .../postPasteImportFix_unknownSourceFile.js | 292 ++++++++++++++ .../postPasteImportFix_multiplePastes1.ts | 16 +- .../postPasteImportFix_multiplePastes2.ts | 14 +- 8 files changed, 1351 insertions(+), 28 deletions(-) create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js diff --git a/src/server/session.ts b/src/server/session.ts index 62fe53833ad75..189a9c9761e86 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2799,22 +2799,11 @@ export class Session implements EventSender { private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - //const pastes: Array<{text: string; range: TextRange}> = arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange(paste.range, project.getScriptInfoForNormalizedPath(file)!)})); - //const textRange = this.getRange(args.pastes[0].range, project.getScriptInfoForNormalizedPath(file)!); const result = project.getLanguageService().getPostPasteImportFixes(args.targetFile, arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange(paste.range, project.getScriptInfoForNormalizedPath(file)!)})), this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); - // const seenFiles = new Set(); - // const textChanges: FileTextChanges[] = []; - // for (const textChange of projectTextChanges) { - // if (!seenFiles.has(textChange.fileName)) { - // textChanges.push(textChange); - // } - // } if (result === undefined) { return undefined; } - //const allResults = result.map(postPasteAction => this.mapPostPasteAction(postPasteAction)); const allResults = this.mapPostPasteAction(result); - return allResults; } diff --git a/src/services/postPasteImportFix.ts b/src/services/postPasteImportFix.ts index 7c0340d1ea715..46afbf1dcb9a8 100644 --- a/src/services/postPasteImportFix.ts +++ b/src/services/postPasteImportFix.ts @@ -17,16 +17,15 @@ export function postPastImportFixProvider( copyLocation?: CopyRange): PostPasteImportFixes { let changes: FileTextChanges[] = []; - changes = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => pastes.forEach(({text, range}) => - { postPasteFixes(targetFile, host, text, range, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)})); + changes = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, host, pastes, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)); + return { edits: changes }; } function postPasteFixes ( targetFile: SourceFile, host: LanguageServiceHost, - pastedText: string, - pastedRange: TextRange, + pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, @@ -34,7 +33,7 @@ function postPasteFixes ( originalFile?: SourceFile, copyLocation?: CopyRange) { - const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastedRange.pos) + pastedText + targetFile.getText().slice(0, pastedRange.end)); + const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastes[0].range.pos) + pastes[0].text + targetFile.getText().slice(0, pastes[0].range.end)); let statements: Statement[] = []; Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); @@ -48,7 +47,7 @@ function postPasteFixes ( insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); - changes.replaceRangeWithText(targetFile, pastedRange, pastedText); + //changes.replaceRangeWithText(targetFile, pastedRange, pastedText); host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } else { @@ -73,10 +72,13 @@ function postPasteFixes ( node.forEachChild(cb); } }); - changes.replaceRangeWithText(targetFile, pastedRange, pastedText); + //changes.replaceRangeWithText(targetFile, pastedRange, pastedText); importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } + pastes.forEach(({ text, range}) => { + changes.replaceRangeWithText(targetFile, range, text); + }); } function getImportsFromKnownOriginalFile( diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js new file mode 100644 index 0000000000000..23d494bd3ac86 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js @@ -0,0 +1,347 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const b = 2; + +//// [/file2.ts] +import { b } from './file1'; +const a = 1; +const c = a + b; +const t = 9; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +export const tt = 2; +function f(); +const p = 1; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts", "target.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/file1.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /file1.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts", + "/target.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts Text-1 "export const tt = 2;\nfunction f();\nconst p = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + Imported via './file1' from file 'file2.ts' + file2.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/file1.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file2.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/target.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file2.ts: + {"pollingInterval":500} +/lib.d.ts: + {"pollingInterval":500} +/lib.decorators.d.ts: + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/tsconfig.json: + {"pollingInterval":2000} + +watchedFiles *deleted*:: +/target.ts: + {"pollingInterval":500} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 2, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/target.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 2, + "endOffset": 14, + "targetFile": "/target.ts", + "pastes": [ + { + "text": "const c = a + b;\nconst t = 9;", + "range": { + "file": "/target.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 2, + "endOffset": 14 + } + } + ], + "originalFile": "file2.ts", + "copyRange": { + "start": { + "line": 2, + "offset": 0 + }, + "end": { + "line": 3, + "offset": 0 + } + } + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-2-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;export const tt = 2;\nfunction f();;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-2-2 "export const tt = 2;\nfunction f();\nconst p = 1;;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 3, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "export " + } + ] + }, + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { a } from \"./file2\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { b } from './file1';\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + }, + "newText": "const c = a + b;\nconst t = 9;" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js new file mode 100644 index 0000000000000..5cbb6a734470d --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js @@ -0,0 +1,327 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const p = 10; +export const q = 12; + +//// [/file2.ts] +const a = 1; +const b = 2; +const c = 3; +const d = 4; + +//// [/file3.ts] +export const r = 10; +export const s = 12; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts", "file3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/file1.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /file1.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts", + "/file3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export const p = 10;\nexport const q = 12;" + /file2.ts Text-1 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + file2.ts + Part of 'files' list in tsconfig.json + file3.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/file1.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file2.ts: *new* + {"pollingInterval":500} +/file3.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/file2.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file3.ts: + {"pollingInterval":500} +/lib.d.ts: + {"pollingInterval":500} +/lib.decorators.d.ts: + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/tsconfig.json: + {"pollingInterval":2000} + +watchedFiles *deleted*:: +/file2.ts: + {"pollingInterval":500} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 2, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/file2.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 3, + "endOffset": 1, + "targetFile": "/file2.ts", + "pastes": [ + { + "text": "const g = p + q;\nfunction e();\nconst f = r + s;\n", + "range": { + "file": "/file2.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 3, + "endOffset": 1 + } + }, + { + "text": "const g = p + q;\nfunction e();\nconst f = r + s;\n", + "range": { + "file": "/file2.ts", + "startLine": 4, + "startOffset": 1, + "endLine": 4, + "endOffset": 13 + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export const p = 10;\nexport const q = 12;" + /file2.ts SVC-2-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst a = 1;\nconst b = 2;\n;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export const p = 10;\nexport const q = 12;" + /file2.ts SVC-2-2 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 3, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { p, q } from \"./file1\";\nimport { r, s } from \"./file3\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "const g = p + q;\nfunction e();\nconst f = r + s;\n" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 13 + }, + "newText": "const g = p + q;\nfunction e();\nconst f = r + s;\n" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js new file mode 100644 index 0000000000000..52bad6f959f07 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js @@ -0,0 +1,356 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +import { aa, bb } from "./other"; +export const r = 10; +export const s = 12; +export const t = aa + bb + r + s; +const u = 1; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const aa = 1; +export const bb = 2; + +//// [/target.ts] +const a = 1; +const b = 2; +const c = 3; +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "other.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/file1.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /file1.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/other.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts SVC-1-0 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts Text-1 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'file1.ts' + Part of 'files' list in tsconfig.json + file1.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/file1.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/target.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: + {"pollingInterval":500} +/lib.decorators.d.ts: + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/other.ts: + {"pollingInterval":500} +/tsconfig.json: + {"pollingInterval":2000} + +watchedFiles *deleted*:: +/target.ts: + {"pollingInterval":500} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 2, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/target.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 3, + "endOffset": 1, + "targetFile": "/target.ts", + "pastes": [ + { + "text": "export const t = aa + bb + r + s;\nconst u = 1;\n", + "range": { + "file": "/target.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 3, + "endOffset": 1 + } + }, + { + "text": "export const t = aa + bb + r + s;\nconst u = 1;\n", + "range": { + "file": "/target.ts", + "startLine": 4, + "startOffset": 1, + "endLine": 4, + "endOffset": 13 + } + } + ], + "originalFile": "file1.ts", + "copyRange": { + "start": { + "line": 3, + "offset": 0 + }, + "end": { + "line": 4, + "offset": 12 + } + } + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts SVC-1-0 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-2-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst a = 1;\nconst b = 2;\n;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts SVC-1-0 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-2-2 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 3, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { r, s } from \"./file1\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { aa, bb } from \"./other\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;\n" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 13 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;\n" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js new file mode 100644 index 0000000000000..3e21b762917c8 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js @@ -0,0 +1,292 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export interface Test1 {} +export interface Test2 {} +export interface Test3 {} +export interface Test4 {} + +//// [/file2.ts] +const a = 10; +const b = 10; +const c = 10; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/file1.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /file1.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts Text-1 "const a = 10;\nconst b = 10;\nconst c = 10;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + file2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/file1.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file2.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "file": "/file2.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: + {"pollingInterval":500} +/lib.decorators.d.ts: + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: + {"pollingInterval":500} +/tsconfig.json: + {"pollingInterval":2000} + +watchedFiles *deleted*:: +/file2.ts: + {"pollingInterval":500} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 2, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "file": "/file2.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 2, + "endOffset": 14, + "targetFile": "/file2.ts", + "pastes": [ + { + "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }", + "range": { + "file": "/file2.ts", + "startLine": 2, + "startOffset": 1, + "endLine": 2, + "endOffset": 14 + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-2-1 "const a = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const a = 10;\nconst b = 10;;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts SVC-1-0 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-2-2 "const a = 10;\nconst b = 10;\nconst c = 10;;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 3, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { Test1, Test2, Test3, Test4 } from \"./file1\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + }, + "newText": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts index 2b449267be050..acf943cf272c0 100644 --- a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts +++ b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts @@ -22,25 +22,31 @@ format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFix({ targetFile: "file2.ts", pastes: [{ - text: `const g = p + q;\n`, + text: `const g = p + q; +function e(); +const f = r + s;\n`, range: { pos: 13, end: 26 }, }, { - text: `function e(); -const f = r + s;`, + text: `const g = p + q; +function e(); +const f = r + s;\n`, range: { pos: 39, end: 51 }, }], newFileContents: { "/file2.ts": `import { p, q } from "./file1"; - import { r, s } from "./file3"; const a = 1; const g = p + q; +function e(); +const f = r + s; const c = 3; +const g = p + q; function e(); -const f = r + s;` +const f = r + s; +` } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts index df8927fa64c5a..d0e28c1452139 100644 --- a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts +++ b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts @@ -25,25 +25,29 @@ format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFix({ targetFile: "target.ts", pastes: [{ - text: `export const t = aa + bb + r + s;\n -const u = 1;`, + text: `export const t = aa + bb + r + s; +const u = 1;\n`, range: { pos: 13, end: 26 }, }, { - text: `export const t = aa + bb + r + s;\n -const u = 1;`, + text: `export const t = aa + bb + r + s; +const u = 1;\n`, range: { pos: 39, end: 51 }, }], newFileContents: { "/target.ts": `import { r, s } from "./file1"; + import { aa, bb } from "./other"; const a = 1; export const t = aa + bb + r + s; +const u = 1; const c = 3; -const u = 1;` +export const t = aa + bb + r + s; +const u = 1; +` }, originalFile: "file1.ts", copyRange: { start: { line : 3, offset: 0}, end : { line: 4, offset: 12}}, From 4fe48f622c75624954921718171afd121ad63d32 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 1 Feb 2024 11:40:20 -0800 Subject: [PATCH 05/41] removing extra code --- src/server/project.ts | 59 +-------------------------- src/services/codefixes/importFixes.ts | 8 ++-- src/services/types.ts | 3 -- 3 files changed, 5 insertions(+), 65 deletions(-) diff --git a/src/server/project.ts b/src/server/project.ts index 0056f6fb6e2d2..7796a7d2b859d 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,6 +1,6 @@ import { info } from "console"; import { FormatContext } from "../services/_namespaces/ts.formatting"; -import { FixInfo, ImportFixWithModuleSpecifier, getFixesInfoForNonUMDImport, sortFixInfo } from "../services/codefixes/importFixes"; +import { FixInfo, ImportFixWithModuleSpecifier, sortFixInfo } from "../services/codefixes/importFixes"; import * as ts from "./_namespaces/ts"; import { addRange, @@ -315,63 +315,6 @@ const enum TypingWatcherType { type TypingWatchers = Map & { isInvoked?: boolean; }; -//========================= -//type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; -const enum ImportFixKind { - UseNamespace, - JsdocTypeImport, - AddToExisting, - AddNew, - PromoteTypeOnly, -} -const enum AddAsTypeOnly { - Allowed = 1 << 0, - Required = 1 << 1, - NotAllowed = 1 << 2, -} -// interface FixInfo { -// readonly fix: ImportFix; -// readonly symbolName: string; -// readonly errorIdentifierText: string | undefined; -// readonly isJsxNamespaceFix?: boolean; -// } -type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; -interface ImportFixBase { - readonly isReExport?: boolean; - readonly exportInfo?: SymbolExportInfo; - readonly moduleSpecifier: string; -} -interface Qualification { - readonly usagePosition: number; - readonly namespacePrefix: string; -} -interface FixUseNamespaceImport extends ImportFixBase, Qualification { - readonly kind: ImportFixKind.UseNamespace; -} -interface FixAddJsdocTypeImport extends ImportFixBase { - readonly kind: ImportFixKind.JsdocTypeImport; - readonly usagePosition: number; - readonly isReExport: boolean; - readonly exportInfo: SymbolExportInfo; -} -interface FixAddToExistingImport extends ImportFixBase { - readonly kind: ImportFixKind.AddToExisting; - readonly importClauseOrBindingPattern: ImportClause | ts.ObjectBindingPattern; - readonly importKind: ts.ImportKind.Default | ts.ImportKind.Named; - readonly addAsTypeOnly: AddAsTypeOnly; -} -interface FixAddNewImport extends ImportFixBase { - readonly kind: ImportFixKind.AddNew; - readonly importKind: ts.ImportKind; - readonly addAsTypeOnly: AddAsTypeOnly; - readonly useRequire: boolean; - readonly qualification?: Qualification; -} -interface FixPromoteTypeOnlyImport { - readonly kind: ImportFixKind.PromoteTypeOnly; - readonly typeOnlyAliasDeclaration: ts.TypeOnlyAliasDeclaration; -} -//========================= export abstract class Project implements LanguageServiceHost, ModuleResolutionHost { private rootFiles: ScriptInfo[] = []; private rootFilesMap = new Map(); diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index a3b63d5239114..66a4896e0f97b 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -1183,7 +1183,7 @@ function getUmdImportKind(importingFile: SourceFile, compilerOptions: CompilerOp } } -export function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] | undefined { +function getFixesInfoForNonUMDImport({ sourceFile, program, cancellationToken, host, preferences }: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] | undefined { const checker = program.getTypeChecker(); const compilerOptions = program.getCompilerOptions(); return flatMap(getSymbolNamesToImport(sourceFile, checker, symbolToken, compilerOptions), symbolName => { @@ -1212,7 +1212,7 @@ function getTypeOnlyPromotionFix(sourceFile: SourceFile, symbolToken: Identifier return { kind: ImportFixKind.PromoteTypeOnly, typeOnlyAliasDeclaration }; } -export function getSymbolNamesToImport(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string[] { +function getSymbolNamesToImport(sourceFile: SourceFile, checker: TypeChecker, symbolToken: Identifier, compilerOptions: CompilerOptions): string[] { const parent = symbolToken.parent; if ((isJsxOpeningLikeElement(parent) || isJsxClosingElement(parent)) && parent.tagName === symbolToken && jsxModeNeedsExplicitImport(compilerOptions.jsx)) { const jsxNamespace = checker.getJsxNamespace(sourceFile); @@ -1231,7 +1231,7 @@ function needsJsxNamespaceFix(jsxNamespace: string, symbolToken: Identifier, che } // Returns a map from an exported symbol's ID to a list of every way it's (re-)exported. -export function getExportInfos( +function getExportInfos( symbolName: string, isJsxTagName: boolean, currentTokenMeaning: SemanticMeaning, @@ -1323,7 +1323,7 @@ function codeActionForFix( }); return createCodeFixAction(importFixName, changes, diag, importFixId, Diagnostics.Add_all_missing_imports); } -export function codeActionForFixWorker( +function codeActionForFixWorker( changes: textChanges.ChangeTracker, sourceFile: SourceFile, symbolName: string, diff --git a/src/services/types.ts b/src/services/types.ts index 73c915a1fccb8..1857a820aca9a 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -716,9 +716,6 @@ export const enum OrganizeImportsMode { } export interface PostPasteImportFixes { - // targetFile: string, - // targetFileText: string, - // pastes: Array<{text: string; range: TextSpan}> edits: readonly FileTextChanges[]; } From 17ff23ab0bd7d3bab2fcdd6decfdc934e8a6d23d Mon Sep 17 00:00:00 2001 From: navya9singh Date: Fri, 9 Feb 2024 13:18:50 -0800 Subject: [PATCH 06/41] Fixing protocol changes and tests --- src/harness/client.ts | 18 +- src/harness/fourslashImpl.ts | 5 +- src/harness/fourslashInterfaceImpl.ts | 15 +- src/server/project.ts | 6 +- src/server/protocol.ts | 14 +- src/server/session.ts | 3 +- .../_namespaces/ts.postPasteImportFixes.ts | 2 +- src/services/postPasteImportFixes.ts | 138 ++++++++ src/services/refactors/moveToFile.ts | 3 +- src/services/services.ts | 12 +- src/services/types.ts | 12 +- src/testRunner/tests.ts | 1 + .../tsserver/postPasteImportFixes.ts | 46 +++ .../postPasteImportFixes_existingImports1.js | 279 +++++++++++++++ .../postPasteImportFixes_existingImports2.js | 320 ++++++++++++++++++ .../postPasteImportFixes_knownSourceFile.js | 307 +++++++++++++++++ .../postPasteImportFixes_multiplePastes1.js | 292 ++++++++++++++++ .../postPasteImportFixes_multiplePastes2.js | 320 ++++++++++++++++++ .../postPasteImportFixes_pasteComments.js | 228 +++++++++++++ .../postPasteImportFixes_unknownSourceFile.js | 254 ++++++++++++++ tests/cases/fourslash/fourslash.ts | 12 +- .../postPasteImportFixes_existingImports1.ts | 38 +++ .../postPasteImportFixes_existingImports2.ts | 46 +++ .../postPasteImportFixes_knownSourceFile.ts | 46 +++ .../postPasteImportFixes_multiplePastes1.ts | 54 +++ .../postPasteImportFixes_multiplePastes2.ts | 53 +++ .../postPasteImportFixes_pasteComments.ts | 34 ++ .../postPasteImportFixes_unknownSourceFile.ts | 42 +++ 28 files changed, 2545 insertions(+), 55 deletions(-) create mode 100644 src/services/postPasteImportFixes.ts create mode 100644 src/testRunner/unittests/tsserver/postPasteImportFixes.ts create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts diff --git a/src/harness/client.ts b/src/harness/client.ts index b5fc806d76ce0..ae166c06ed207 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -14,7 +14,6 @@ import { computeLineAndCharacterOfPosition, computeLineStarts, computePositionOfLineAndCharacter, - CopyRange, createQueue, createTextSpanFromBounds, Debug, @@ -1012,13 +1011,18 @@ export class SessionClient implements LanguageService { return getSupportedCodeFixes(); } - getPostPasteImportFixes(targetFile: string, pastes: Array<{text: string; range: TextRange}>, _preferences: UserPreferences, _formatOptions: FormatCodeSettings, originalFile?: string, copyRange?: CopyRange): PostPasteImportFixes{ - const args = this.createFileLocationOrRangeRequestArgs(pastes[0].range, targetFile) as protocol.GetPostPasteImportFixesRequestArgs; - args.targetFile = targetFile; - args.pastes = arrayFrom(pastes.map(paste => ({text: paste.text, range: this.createFileRangeRequestArgs(targetFile, paste.range.pos, paste.range.end)}))); - args.originalFile = originalFile; - args.copyRange = copyRange; + getPostPasteImportFixes( + targetFile: string, + pastes: Array<{ text: string; range: TextRange }>, + _preferences: UserPreferences, + _formatOptions: FormatCodeSettings, + copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number } }): PostPasteImportFixes { + const args: protocol.GetPostPasteImportFixesRequestArgs = { + file: targetFile, + pastes: arrayFrom(pastes.map(paste => ({text: paste.text, range: { start: this.positionToOneBasedLineOffset(targetFile, paste.range.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.range.end)}}))), + copySpan: copySpan + } const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); if (!response.body) { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index fd72eee8e840f..7bfa915f924e2 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -10,6 +10,7 @@ import { } from "./tsserverLogger"; import ArrayOrSingle = FourSlashInterface.ArrayOrSingle; +import { arrayFrom } from "./_namespaces/ts"; export const enum FourSlashTestType { Native, @@ -3562,8 +3563,8 @@ export class TestState { assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers); } - public verifyPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void{ - const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.originalFile, options.copyRange); + public verifyPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void { + const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.copySpan); this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 26c8d4b6ef61b..72fa4a5e047ea 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1,3 +1,4 @@ +import { Location } from "../server/protocol"; import * as FourSlash from "./_namespaces/FourSlash"; import * as ts from "./_namespaces/ts"; @@ -621,7 +622,7 @@ export class Verify extends VerifyNegatable { this.state.verifyOrganizeImports(newContent, mode, preferences); } - public postPasteImportFix(options: PostPasteImportFixOptions): void { + public postPasteImportFixes(options: PostPasteImportFixOptions): void { this.state.verifyPostPasteImportFixes(options); } } @@ -1883,12 +1884,11 @@ export interface VerifyCodeFixAllOptions { preferences?: ts.UserPreferences; } -export interface verifyPostPasteImportFix { +export interface VerifyPostPasteImportFix { targetFile: string; pastes: Array<{text: string; range: ts.TextRange}>; preferences: ts.UserPreferences; - originalFile?: string; - copyRange?: ts.CopyRange + copySpan?: { file: string, start: Location, end: Location } } export interface VerifyRefactorOptions { @@ -1933,10 +1933,9 @@ export interface MoveToFileOptions { export interface PostPasteImportFixOptions { readonly newFileContents: { readonly [fileName: string]: string; }; - readonly pastes: Array<{text: string; range: ts.TextRange}>,//{ pos, end }: ts.TextRange - readonly preferences: ts.UserPreferences, - readonly originalFile?: string, - readonly copyRange?: ts.CopyRange + readonly pastes: Array<{text: string; range: ts.TextRange}>; + readonly preferences: ts.UserPreferences; + readonly copySpan?: { file: string, start: Location, end: Location }; } export type RenameLocationsOptions = readonly RenameLocationOptions[] | { diff --git a/src/server/project.ts b/src/server/project.ts index 7796a7d2b859d..35d12cec6071f 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2219,16 +2219,16 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): {updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined} { + updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined } { const originalProgram = this.program; - this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length-1, pastedText); + this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); this.updateGraph(); return { updatedFile: (this.program?.getSourceFile(rootFile)), updatedProgram: this.program, originalProgram }; } /** @internal */ revertUpdatedFile(rootFile: string, updatedText: string, originalText: string) { - this.getScriptInfo(rootFile)?.editContent(0, updatedText.length-1, originalText); + this.getScriptInfo(rootFile)?.editContent(0, updatedText.length, originalText); this.updateGraph(); } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index f7b2bb85d36ca..9ea16d803c8e4 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -639,16 +639,10 @@ export interface GetPostPasteImportFixesRequest extends Request { command: CommandTypes.GetPostPasteImportFixes; arguments: GetPostPasteImportFixesRequestArgs; } -export type DocumentRange = FileRangeRequestArgs; -export type CopyRange = { - start: Location; - end: Location; -} -export type GetPostPasteImportFixesRequestArgs = FileLocationOrRangeRequestArgs & { - targetFile: string, - pastes: Array<{text: string; range: DocumentRange}>, - originalFile?: string, - copyRange?: CopyRange + +export type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { + pastes: Array<{ text: string; range: TextSpan }>, + copySpan?: FileSpan, } export interface GetPostPasteImportFixesResponse extends Response { body: PostPasteImportAction; diff --git a/src/server/session.ts b/src/server/session.ts index 189a9c9761e86..a14467fd0345e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2799,7 +2799,8 @@ export class Session implements EventSender { private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - const result = project.getLanguageService().getPostPasteImportFixes(args.targetFile, arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange(paste.range, project.getScriptInfoForNormalizedPath(file)!)})), this.getPreferences(file), this.getFormatOptions(file), args.originalFile, args.copyRange); + const pastes = arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange({file: file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset}, project.getScriptInfoForNormalizedPath(file)!)})) + const result = project.getLanguageService().getPostPasteImportFixes( file, pastes, this.getPreferences(file), this.getFormatOptions(file), args.copySpan); if (result === undefined) { return undefined; } diff --git a/src/services/_namespaces/ts.postPasteImportFixes.ts b/src/services/_namespaces/ts.postPasteImportFixes.ts index c46fc22994e95..b75b8ec1d96cc 100644 --- a/src/services/_namespaces/ts.postPasteImportFixes.ts +++ b/src/services/_namespaces/ts.postPasteImportFixes.ts @@ -1 +1 @@ -export * from "../postPasteImportFix"; \ No newline at end of file +export * from "../postPasteImportFixes"; \ No newline at end of file diff --git a/src/services/postPasteImportFixes.ts b/src/services/postPasteImportFixes.ts new file mode 100644 index 0000000000000..611e564e74b4f --- /dev/null +++ b/src/services/postPasteImportFixes.ts @@ -0,0 +1,138 @@ +import { addRange, append } from "../compiler/core"; +import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange, CancellationToken, ImportClause, ObjectBindingPattern, TypeOnlyAliasDeclaration, SymbolFlags } from "../compiler/types"; +import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; +import { codefix, Debug, factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, ImportKind, insertImports, nodeSeenTracker, Symbol, SymbolExportInfo, textChanges, isIdentifier } from "./_namespaces/ts"; +import { addExportToChanges, filterImport, forEachImportInStatement, getExistingLocals, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; +import { CodeFixContextBase, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; + +/** @internal */ +export function postPasteImportFixesProvider( + targetFile: SourceFile, + host: LanguageServiceHost, + pastes: Array<{ text: string; range: TextRange }>, + preferences: UserPreferences, + formatContext: formatting.FormatContext, + cancellationToken: CancellationToken, + originalFile?: SourceFile, + copyLocation?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}): PostPasteImportFixes { + + const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, host, pastes, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)); + + return { edits: changes }; +} + +function postPasteFixes ( + targetFile: SourceFile, + host: LanguageServiceHost, + pastes: Array<{ text: string; range: TextRange }>, + preferences: UserPreferences, + formatContext: formatting.FormatContext, + cancellationToken: CancellationToken, + changes: textChanges.ChangeTracker, + originalFile?: SourceFile, + copyLocation?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}) { + const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastes[0].range.pos) + pastes[0].text + targetFile.getText().slice(pastes[0].range.end)); + let statements: Statement[] = []; + Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); + + if (originalFile) { + addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); + const usage = getUsageInfo(originalFile, statements, updatedTargetFile.originalProgram.getTypeChecker(), getExistingLocals(updatedTargetFile.updatedFile, statements, updatedTargetFile.originalProgram.getTypeChecker())); + const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); + + const imports = getImportsFromKnownOriginalFile(originalFile, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); + if (imports.length > 0) { + insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); + } + importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); + host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); + } + else { + const context: CodeFixContextBase = { + sourceFile: updatedTargetFile.updatedFile, + program: updatedTargetFile.originalProgram, + cancellationToken: cancellationToken, + host: host, + preferences: preferences, + formatContext: formatContext + } + const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); + forEachChild(updatedTargetFile.updatedFile, function cb(node) { + if (isIdentifier(node)) { + if (!updatedTargetFile.originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { + //generate imports + importAdder.addImportsForUnknownSymbols(context, node, /*useAutoImportProvider*/ true); + } + } + else { + node.forEachChild(cb); + } + }); + importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); + host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); + } + pastes.forEach(({ text, range}) => { + range.pos === range.end ? changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text) : changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text); + }); +} + +function getImportsFromKnownOriginalFile( + originalFile: SourceFile, + targetFile: SourceFile, + program: Program, + importAdder: codefix.ImportAdder, + importsToCopy: Map, + targetFileImportsFromOldFile: Set, + changes: textChanges.ChangeTracker, + preferences: UserPreferences, + host: LanguageServiceHost, + checker: TypeChecker) { + const copiedOldImports: AnyImportOrRequireStatement[] = []; + importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { + try { + importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); + } + catch { + for (const oldStatement of originalFile.statements) { + forEachImportInStatement(oldStatement, i => { + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + }); + } + } + }); + + const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, program, host, !!originalFile.commonJsModuleIndicator); + const quotePreference = getQuotePreference(targetFile, preferences); + // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. + let oldFileDefault: Identifier | undefined; + const oldFileNamedImports: string[] = []; + const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. + targetFileImportsFromOldFile.forEach(symbol => { + if (!symbol.declarations) { + return; + } + for (const decl of symbol.declarations) { + if (!isTopLevelDeclaration(decl)) continue; + const name = nameOfTopLevelDeclaration(decl); + if (!name) continue; + + const top = getTopLevelDeclarationStatement(decl); + if (markSeenTop(top)) { + addExportToChanges(originalFile, top, name, changes, useEsModuleSyntax); + } + if (importAdder && checker.isUnknownSymbol(symbol)) { + importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); + } + else { + if (hasSyntacticModifier(decl, ModifierFlags.Default)) { + oldFileDefault = name; + } + else { + oldFileNamedImports.push(name.text); + } + } + } + }); + + return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)) +} \ No newline at end of file diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 80064ab148951..c95163d4b71fd 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -1242,7 +1242,8 @@ function getOverloadRangeToMove(sourceFile: SourceFile, statement: Statement) { return undefined; } -function getExistingLocals(sourceFile: SourceFile, statements: readonly Statement[], checker: TypeChecker) { +/** @internal */ +export function getExistingLocals(sourceFile: SourceFile, statements: readonly Statement[], checker: TypeChecker) { const existingLocals = new Set(); for (const moduleSpecifier of sourceFile.imports) { const declaration = importFromModuleSpecifier(moduleSpecifier); diff --git a/src/services/services.ts b/src/services/services.ts index 1e4108a87a73c..aad974e869165 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -320,7 +320,6 @@ import { UserPreferences, VariableDeclaration, postPasteImportFixes, - CopyRange, PostPasteImportFixes, } from "./_namespaces/ts"; import * as NavigateTo from "./_namespaces/ts.NavigateTo"; @@ -2093,16 +2092,15 @@ export function createLanguageService( } function getPostPasteImportFixes ( - targetFile: string, - pastes: Array<{text: string; range: TextRange}>, + targetFile: string, + pastes: Array<{ text: string; range: TextRange }>, preferences: UserPreferences, formatOptions: FormatCodeSettings, - originalFile?: string, - copyLocation?: CopyRange + copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }} ): PostPasteImportFixes{ synchronizeHostData(); - const originalSourceFile = originalFile ? getValidSourceFile(originalFile) : undefined; - const edits = postPasteImportFixes.postPastImportFixProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host),cancellationToken, originalSourceFile, copyLocation); + const originalSourceFile = copySpan ? getValidSourceFile(copySpan.file) : undefined; + const edits = postPasteImportFixes.postPasteImportFixesProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host),cancellationToken, originalSourceFile, copySpan); return edits; } diff --git a/src/services/types.ts b/src/services/types.ts index 1857a820aca9a..94d7425445528 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -687,12 +687,12 @@ export interface LanguageService { getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; - getPostPasteImportFixes (targetFile: string, pastes: Array<{text: string; range: TextRange}>, preferences: UserPreferences, formatOptions: FormatCodeSettings, originalFile: string | undefined, copyLocation: CopyRange | undefined): PostPasteImportFixes; -} - -export interface CopyRange { - start: { line: number, offset: number }; - end: { line: number, offset: number } + getPostPasteImportFixes( + targetFile: string, + pastes: Array<{ text: string; range: TextRange }>, + preferences: UserPreferences, + formatOptions: FormatCodeSettings, + copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}): PostPasteImportFixes; } export interface JsxClosingTagInfo { diff --git a/src/testRunner/tests.ts b/src/testRunner/tests.ts index 01d5ddea11d4d..a7fc40d26c7ff 100644 --- a/src/testRunner/tests.ts +++ b/src/testRunner/tests.ts @@ -214,3 +214,4 @@ import "./unittests/debugDeprecation"; import "./unittests/tsserver/inconsistentErrorInEditor"; import "./unittests/tsserver/getMoveToRefactoringFileSuggestions"; import "./unittests/skipJSDocParsing"; +import "./unittests/tsserver/postPasteImportFixes"; \ No newline at end of file diff --git a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts new file mode 100644 index 0000000000000..ecb55a5f84af6 --- /dev/null +++ b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts @@ -0,0 +1,46 @@ +import * as ts from "../../_namespaces/ts"; +import { + baselineTsserverLogs, + openFilesForSession, + TestSession, +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; + +describe("unittests:: tsserver:: postPasteImportFixes", () => { + it("returns the same file unchanged, after updating and reverting changes added to a file", () => { + const target: File = { + path : "/project/a/target.ts", + content: `const a = 1; +const b = 2; +const c = 3;`, + } + const tsconfig: File = { + path: "/project/tsconfig.json", + content: "{}", + }; + const pastedText = `const a = 1; +function e(); +const f = r + s; +const b = 2; +const c = 3;`; + + const host = createServerHost([target, tsconfig]); + const session = new TestSession(host); + openFilesForSession([target], session); + + const originalContent = target.content; + const originalProgram = session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getProgram(); + + const hostProject = session.getProjectService().configuredProjects.get(tsconfig.path)!; + const updatedContent = hostProject.updateTargetFile(target.path, target.content, pastedText); + + if (updatedContent.updatedFile !== undefined) { + hostProject.revertUpdatedFile(target.path, updatedContent.updatedFile.getText(), originalContent); + } + assert.strictEqual(hostProject.getCurrentProgram()?.getSourceFileByPath(target.path as ts.Path)?.getText(), originalProgram?.getSourceFileByPath(target.path as ts.Path)?.getText()); + baselineTsserverLogs("getPostPasteImportFixes", "Returns the same file unchanged ", session); + }); +}); diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js new file mode 100644 index 0000000000000..8477babc0f4b3 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js @@ -0,0 +1,279 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const t = 1; + +//// [/other2.ts] +export const t2 = 1; + +//// [/other3.ts] +export const t3 = 1; + +//// [/target.ts] +import { t } from "./other"; +import { t3 } from "./other3"; +const a = t + 1; +const b = 10; +const c = 10; + +//// [/tsconfig.json] +{ "files": ["target.ts", "other.ts", "other2.ts", "other3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts", + "/other.ts", + "/other2.ts", + "/other3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-0 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'target.ts' + Part of 'files' list in tsconfig.json + other3.ts + Imported via "./other3" from file 'target.ts' + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + other2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/other2.ts: *new* + {"pollingInterval":500} +/other3.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastes": [ + { + "text": "const m = t3 + t2 + 1;", + "range": { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + } + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-2 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { t2 } from \"./other2\";\n" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + }, + "newText": "const m = t3 + t2 + 1;" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js new file mode 100644 index 0000000000000..8b9854f9637de --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js @@ -0,0 +1,320 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/originalFile.ts] +import { t2 } from "./other2"; +import { t3 } from "./other3"; +export const n = 10; +export const m = t3 + t2 + n; + +//// [/other.ts] +export const t = 1; + +//// [/other2.ts] +export const t2 = 1; + +//// [/other3.ts] +export const t3 = 1; + +//// [/target.ts] +import { t } from "./other"; +import { t3 } from "./other3"; +const a = t + 1; +const b = 10; +const c = 10; + +//// [/tsconfig.json] +{ "files": ["target.ts", "originalFile.ts", "other.ts", "other2.ts", "other3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts", + "/originalFile.ts", + "/other.ts", + "/other2.ts", + "/other3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /originalFile.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-0 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'target.ts' + Part of 'files' list in tsconfig.json + other3.ts + Imported via "./other3" from file 'target.ts' + Imported via "./other3" from file 'originalFile.ts' + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + other2.ts + Imported via "./other2" from file 'originalFile.ts' + Part of 'files' list in tsconfig.json + originalFile.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/originalFile.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/other2.ts: *new* + {"pollingInterval":500} +/other3.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastes": [ + { + "text": "const m = t3 + t2 + n;", + "range": { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + } + } + } + ], + "copySpan": { + "file": "originalFile.ts", + "start": { + "line": 3, + "offset": 0 + }, + "end": { + "line": 3, + "offset": 30 + } + } + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-2 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { n } from \"./originalFile\";\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { t2 } from \"./other2\";\n" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + }, + "newText": "const m = t3 + t2 + n;" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js new file mode 100644 index 0000000000000..60fb7ede7b610 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js @@ -0,0 +1,307 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const b = 2; + +//// [/file2.ts] +import { b } from './file1'; +const a = 1; +const c = a + b; +const t = 9; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +export const tt = 2; +function f(); +const p = 1; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts", "target.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts", + "/target.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-1-0 "export const tt = 2;\nfunction f();\nconst p = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + Imported via './file1' from file 'file2.ts' + file2.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/file2.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastes": [ + { + "text": "const c = a + b;\nconst t = 9;", + "range": { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + } + } + } + ], + "copySpan": { + "file": "file2.ts", + "start": { + "line": 2, + "offset": 0 + }, + "end": { + "line": 3, + "offset": 0 + } + } + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-1-2 "export const tt = 2;\nfunction f();\nconst p = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "export " + } + ] + }, + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { a } from \"./file2\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { b } from './file1';\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + }, + "newText": "const c = a + b;\nconst t = 9;" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js new file mode 100644 index 0000000000000..727d587a6636e --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js @@ -0,0 +1,292 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const p = 10; +export const q = 12; + +//// [/file3.ts] +export const r = 10; +export const s = 12; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +const a = 1; + +const b = 2; +const c = 3; + +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "file3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/file3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-0 "const a = 1;\n\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + file3.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/file3.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastes": [ + { + "text": "const g = p + q;\nfunction e();\nconst f = r + s;", + "range": { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + } + } + }, + { + "text": "const g = p + q;\nfunction e();\nconst f = r + s;", + "range": { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + } + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-2 "const a = 1;\n\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { p, q } from \"./file1\";\nimport { r, s } from \"./file3\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "const g = p + q;\nfunction e();\nconst f = r + s;" + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + }, + "newText": "const g = p + q;\nfunction e();\nconst f = r + s;" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js new file mode 100644 index 0000000000000..abd684c7c5130 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js @@ -0,0 +1,320 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +import { aa, bb } from "./other"; +export const r = 10; +export const s = 12; +export const t = aa + bb + r + s; +const u = 1; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const aa = 1; +export const bb = 2; + +//// [/target.ts] +const a = 1; +const b = 2; +const c = 3; + +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "other.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/other.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'file1.ts' + Part of 'files' list in tsconfig.json + file1.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastes": [ + { + "text": "export const t = aa + bb + r + s;\nconst u = 1;", + "range": { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 13 + } + } + }, + { + "text": "export const t = aa + bb + r + s;\nconst u = 1;", + "range": { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 1 + } + } + } + ], + "copySpan": { + "file": "file1.ts", + "start": { + "line": 3, + "offset": 0 + }, + "end": { + "line": 4, + "offset": 12 + } + } + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\n\nconst d = 4;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-1-2 "const a = 1;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { r, s } from \"./file1\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { aa, bb } from \"./other\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 13 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 1 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js new file mode 100644 index 0000000000000..c6cb16bb03451 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js @@ -0,0 +1,228 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +const a = 10; +const b = 10; +const c = 10; + +//// [/tsconfig.json] +{ "files": ["target.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /target.ts SVC-1-0 "const a = 10;\nconst b = 10;\nconst c = 10;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastes": [ + { + "text": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/", + "range": { + "start": { + "line": 2, + "offset": 14 + }, + "end": { + "line": 2, + "offset": 14 + } + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /target.ts SVC-1-2 "const a = 10;\nconst b = 10;\nconst c = 10;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 14 + }, + "end": { + "line": 2, + "offset": 14 + }, + "newText": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js new file mode 100644 index 0000000000000..ddc26b007de3e --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js @@ -0,0 +1,254 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export interface Test1 {} +export interface Test2 {} +export interface Test3 {} +export interface Test4 {} + +//// [/file2.ts] +const a = 10; +const b = 10; +const c = 10; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/file2.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /file2.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-1-0 "const a = 10;\nconst b = 10;\nconst c = 10;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + file2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/file2.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/file2.ts", + "pastes": [ + { + "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }", + "range": { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + } + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-1-2 "const a = 10;\nconst b = 10;\nconst c = 10;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { Test1, Test2, Test3, Test4 } from \"./file1\";\n\n" + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" + } + ] + } + ] + } + } \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index a4287e99ab189..e73659845bd61 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -216,10 +216,6 @@ declare namespace FourSlashInterface { line: number; offset: number; } - interface CopyRange { - start: Location; - end: Location; - } class test_ { markers(): Marker[]; markerNames(): string[]; @@ -452,12 +448,10 @@ declare namespace FourSlashInterface { toggleMultilineComment(newFileContent: string): void; commentSelection(newFileContent: string): void; uncommentSelection(newFileContent: string): void; - postPasteImportFix(options: { + postPasteImportFixes(options: { newFileContents: { readonly [fileName: string]: string }; - targetFile: string, - pastes: Array<{text: string; range: {pos: number, end: number}}> - originalFile?: string, - copyRange?: CopyRange, + pastes: Array<{ text: string; range: { pos: number, end: number }}>; + copySpan?: { file: string, start: Location, end: Location }, }): void; } class edit { diff --git a/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts b/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts new file mode 100644 index 0000000000000..82aeef5f7d998 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts @@ -0,0 +1,38 @@ +/// + +// @Filename: /target.ts +//// import { t } from "./other"; +//// import { t3 } from "./other3"; +//// const a = t + 1; +//// [|const b = 10;|] +//// const c = 10; + +// @Filename: /other.ts +//// export const t = 1; + +// @Filename: /other2.ts +//// export const t2 = 1; + +// @Filename: /other3.ts +//// export const t3 = 1; + +// @Filename: /tsconfig.json +////{ "files": ["target.ts", "other.ts", "other2.ts", "other3.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `const m = t3 + t2 + 1;`, + range: range[0], + }], + newFileContents: { + "/target.ts": +`import { t } from "./other"; +import { t2 } from "./other2"; +import { t3 } from "./other3"; +const a = t + 1; +const m = t3 + t2 + 1; +const c = 10;` + } +}); diff --git a/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts b/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts new file mode 100644 index 0000000000000..3ad98da93f4cb --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts @@ -0,0 +1,46 @@ +/// + +// @Filename: /target.ts +//// import { t } from "./other"; +//// import { t3 } from "./other3"; +//// const a = t + 1; +//// [|const b = 10;|] +//// const c = 10; + +// @Filename: /other.ts +//// export const t = 1; + +// @Filename: /other2.ts +//// export const t2 = 1; + +// @Filename: /other3.ts +//// export const t3 = 1; + +// @Filename: /originalFile.ts +//// import { t2 } from "./other2"; +//// import { t3 } from "./other3"; +//// export const n = 10; +//// export const m = t3 + t2 + n; + +// @Filename: /tsconfig.json +////{ "files": ["target.ts", "originalFile.ts", "other.ts", "other2.ts", "other3.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `const m = t3 + t2 + n;`, + range: range[0], + }], + newFileContents: { + "/target.ts": +`import { n } from "./originalFile"; +import { t } from "./other"; +import { t2 } from "./other2"; +import { t3 } from "./other3"; +const a = t + 1; +const m = t3 + t2 + n; +const c = 10;` + }, + copySpan: { file: "originalFile.ts", start: { line : 3, offset: 0}, end : { line: 3, offset: 30}}, +}); diff --git a/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts b/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts new file mode 100644 index 0000000000000..97722efb4ea37 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts @@ -0,0 +1,46 @@ +/// + +// @Filename: /target.ts +//// export const tt = 2; +//// [|function f();|] +//// const p = 1; + +// @Filename: /file1.ts +////export const b = 2; + +// @Filename: /file2.ts +////import { b } from './file1'; +////const a = 1; +////const c = a + b; +////const t = 9; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "file2.ts", "target.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `const c = a + b; +const t = 9;`, + range: range[0], + }], + copySpan: { file:"file2.ts", start: { line : 2, offset: 0}, end : { line: 3, offset: 0}}, + newFileContents: { + "/file2.ts": +`import { b } from './file1'; +export const a = 1; +const c = a + b; +const t = 9;`, + + "/target.ts": +`import { a } from "./file2"; + +import { b } from './file1'; + +export const tt = 2; +const c = a + b; +const t = 9; +const p = 1;`, + } +}); diff --git a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts new file mode 100644 index 0000000000000..bef58f87b1899 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts @@ -0,0 +1,54 @@ +/// + +// @Filename: /target.ts +//// const a = 1; +//// [||] +//// const b = 2; +//// const c = 3; +//// [||] +//// const d = 4; + +// @Filename: /file1.ts +//// export const p = 10; +//// export const q = 12; + +// @Filename: /file3.ts +//// export const r = 10; +//// export const s = 12; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "target.ts", "file3.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `const g = p + q; +function e(); +const f = r + s;`, + range: range[0], + }, + { + text: `const g = p + q; +function e(); +const f = r + s;`, + range: range[1], + + }], + newFileContents: { + "/target.ts": +`import { p, q } from "./file1"; +import { r, s } from "./file3"; + +const a = 1; +const g = p + q; +function e(); +const f = r + s; +const b = 2; +const c = 3; +const g = p + q; +function e(); +const f = r + s; +const d = 4;` + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts new file mode 100644 index 0000000000000..93ea4de93e5bf --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts @@ -0,0 +1,53 @@ +/// + +// @Filename: /target.ts +//// const a = 1; +//// [|const b = 2;|] +//// const c = 3; +//// [||] +//// const d = 4; + +// @Filename: /file1.ts +//// import { aa, bb } from "./other"; +//// export const r = 10; +//// export const s = 12; +//// export const t = aa + bb + r + s; +//// const u = 1; + +// @Filename: /other.ts +//// export const aa = 1; +//// export const bb = 2; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "target.ts", "other.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `export const t = aa + bb + r + s; +const u = 1;`, + range: range[0], + }, + { + text: `export const t = aa + bb + r + s; +const u = 1;`, + range: range[1], + + }], + newFileContents: { + "/target.ts": +`import { r, s } from "./file1"; + +import { aa, bb } from "./other"; + +const a = 1; +export const t = aa + bb + r + s; +const u = 1; +const c = 3; +export const t = aa + bb + r + s; +const u = 1; +const d = 4;` + }, + copySpan: { file: "file1.ts", start: { line : 3, offset: 0}, end : { line: 4, offset: 12}}, +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts b/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts new file mode 100644 index 0000000000000..60c272e5d9447 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts @@ -0,0 +1,34 @@ +/// + +// @Filename: /target.ts +//// const a = 10; +//// const b = 10;[||] +//// const c = 10; + +// @Filename: /tsconfig.json +////{ "files": ["target.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `/** +* Testing comment line 1 +* line 2 +* line 3 +* line 4 +*/`, + range: range[0], + }], + newFileContents: { + "/target.ts": +`const a = 10; +const b = 10;/** +* Testing comment line 1 +* line 2 +* line 3 +* line 4 +*/ +const c = 10;` + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts b/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts new file mode 100644 index 0000000000000..009d847fdca3c --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts @@ -0,0 +1,42 @@ +/// + +// @Filename: /file2.ts +//// const a = 10; +//// const b = 10; +//// [||]const c = 10; + +// @Filename: /file1.ts +//// export interface Test1 {} +//// export interface Test2 {} +//// export interface Test3 {} +//// export interface Test4 {} + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "file2.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + pastes: [{ + text: `interface Testing { + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; + }`, + range: range[0], + }], + newFileContents: { + "/file2.ts": +`import { Test1, Test2, Test3, Test4 } from "./file1"; + +const a = 10; +const b = 10; +interface Testing { + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; + }const c = 10;` + } +}); \ No newline at end of file From 1b89d2ee726496c8ba758b406c326aa08e38c0e1 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Fri, 9 Feb 2024 13:21:54 -0800 Subject: [PATCH 07/41] Removing deleted files --- src/services/postPasteImportFix.ts | 143 ------------------ .../postPasteImportFix_knownSourceFile.ts | 48 ------ .../postPasteImportFix_multiplePastes1.ts | 52 ------- .../postPasteImportFix_multiplePastes2.ts | 54 ------- .../postPasteImportFix_unknownSourceFile.ts | 43 ------ 5 files changed, 340 deletions(-) delete mode 100644 src/services/postPasteImportFix.ts delete mode 100644 tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts delete mode 100644 tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts delete mode 100644 tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts delete mode 100644 tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts diff --git a/src/services/postPasteImportFix.ts b/src/services/postPasteImportFix.ts deleted file mode 100644 index 46afbf1dcb9a8..0000000000000 --- a/src/services/postPasteImportFix.ts +++ /dev/null @@ -1,143 +0,0 @@ -import { addRange, append } from "../compiler/core"; -import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange, CancellationToken, ImportClause, ObjectBindingPattern, TypeOnlyAliasDeclaration, SymbolFlags } from "../compiler/types"; -import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; -import { codefix, Debug, factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, ImportKind, insertImports, nodeSeenTracker, Symbol, SymbolExportInfo, textChanges, isIdentifier } from "./_namespaces/ts"; -import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; -import { CodeFixContextBase, CopyRange, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; - -/** @internal */ -export function postPastImportFixProvider( - targetFile: SourceFile, - host: LanguageServiceHost, - pastes: Array<{text: string; range: TextRange}>, - preferences: UserPreferences, - formatContext: formatting.FormatContext, - cancellationToken: CancellationToken, - originalFile?: SourceFile, - copyLocation?: CopyRange): PostPasteImportFixes { - - let changes: FileTextChanges[] = []; - changes = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, host, pastes, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)); - - return { edits: changes }; -} - -function postPasteFixes ( - targetFile: SourceFile, - host: LanguageServiceHost, - pastes: Array<{text: string; range: TextRange}>, - preferences: UserPreferences, - formatContext: formatting.FormatContext, - cancellationToken: CancellationToken, - changes: textChanges.ChangeTracker, - originalFile?: SourceFile, - copyLocation?: CopyRange) { - - const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastes[0].range.pos) + pastes[0].text + targetFile.getText().slice(0, pastes[0].range.end)); - let statements: Statement[] = []; - Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); - - if (originalFile) { - addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); - const usage = getUsageInfo(originalFile, statements, updatedTargetFile.originalProgram.getTypeChecker()); - const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); - - const imports = getImportsFromKnownOriginalFile(originalFile, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); - if (imports.length > 0) { - insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); - } - importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); - //changes.replaceRangeWithText(targetFile, pastedRange, pastedText); - host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); - } - else { - const context: CodeFixContextBase = { - sourceFile: updatedTargetFile.updatedFile, - program: updatedTargetFile.originalProgram, - cancellationToken: cancellationToken, - host: host, - preferences: preferences, - formatContext: formatContext - } - const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); - forEachChild(updatedTargetFile.updatedFile, function cb(node) { - if (isIdentifier(node)) { - if (!updatedTargetFile.updatedProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ true) && - !updatedTargetFile.originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { - //generate imports - importAdder.addImportsForUnknownSymbols(context, node, /*useAutoImportProvider*/ true); - } - } - else { - node.forEachChild(cb); - } - }); - //changes.replaceRangeWithText(targetFile, pastedRange, pastedText); - importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); - host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); - } - pastes.forEach(({ text, range}) => { - changes.replaceRangeWithText(targetFile, range, text); - }); -} - -function getImportsFromKnownOriginalFile( - originalFile: SourceFile, - targetFile: SourceFile, - program: Program, - importAdder: codefix.ImportAdder, - importsToCopy: Map, - targetFileImportsFromOldFile: Set, - changes: textChanges.ChangeTracker, - preferences: UserPreferences, - host: LanguageServiceHost, - checker: TypeChecker) { - const copiedOldImports: AnyImportOrRequireStatement[] = []; - importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { - try { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); - } - catch { - for (const oldStatement of originalFile.statements) { - forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - }); - } - } - }); - - const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, program, host, !!originalFile.commonJsModuleIndicator); - const quotePreference = getQuotePreference(targetFile, preferences); - // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. - let oldFileDefault: Identifier | undefined; - const oldFileNamedImports: string[] = []; - const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. - targetFileImportsFromOldFile.forEach(symbol => { - if (!symbol.declarations) { - return; - } - for (const decl of symbol.declarations) { - if (!isTopLevelDeclaration(decl)) continue; - const name = nameOfTopLevelDeclaration(decl); - if (!name) continue; - - const top = getTopLevelDeclarationStatement(decl); - if (markSeenTop(top)) { - addExportToChanges(originalFile, top, name, changes, useEsModuleSyntax); - } - if (importAdder && checker.isUnknownSymbol(symbol)) { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); - } - else { - if (hasSyntacticModifier(decl, ModifierFlags.Default)) { - oldFileDefault = name; - } - else { - oldFileNamedImports.push(name.text); - } - } - } - }); - - return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)) -} \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts b/tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts deleted file mode 100644 index 3e7c621ba2a54..0000000000000 --- a/tests/cases/fourslash/server/postPasteImportFix_knownSourceFile.ts +++ /dev/null @@ -1,48 +0,0 @@ -/// - -// @Filename: /file1.ts -////export const b = 2; - -// @Filename: /file2.ts -////import { b } from './file1'; -////const a = 1; -////const c = a + b; -////const t = 9; - -// @Filename: /target.ts -//// /*a*/export const tt = 2;/*b*/ -//// function f(); -//// const p = 1; - -// @Filename: /tsconfig.json -////{ "files": ["file1.ts", "file2.ts", "target.ts"] } - -goTo.select("a", "b"); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFix({ - targetFile: "target.ts", - pastes: [{ - text: `const c = a + b; -const t = 9;`, - range: { pos: 21, end: 34 }, - }], - originalFile: "file2.ts", - copyRange: { start: { line : 2, offset: 0}, end : { line: 3, offset: 0}}, - newFileContents: { - "/file2.ts": -`import { b } from './file1'; -export const a = 1; -const c = a + b; -const t = 9;`, - - "/target.ts": -`import { a } from "./file2"; - -import { b } from './file1'; - -export const tt = 2; -const c = a + b; -const t = 9; -const p = 1;`, - } -}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts deleted file mode 100644 index acf943cf272c0..0000000000000 --- a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes1.ts +++ /dev/null @@ -1,52 +0,0 @@ -/// - -// @Filename: /file1.ts -//// export const p = 10; -//// export const q = 12; - -// @Filename: /file3.ts -//// export const r = 10; -//// export const s = 12; - -// @Filename: /file2.ts -//// /*a*/const a = 1; -//// /*b*/const b = 2; -//// const c = 3; -//// const d = 4; - -// @Filename: /tsconfig.json -////{ "files": ["file1.ts", "file2.ts", "file3.ts"] } - -goTo.select("a", "b"); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFix({ - targetFile: "file2.ts", - pastes: [{ - text: `const g = p + q; -function e(); -const f = r + s;\n`, - range: { pos: 13, end: 26 }, - }, - { - text: `const g = p + q; -function e(); -const f = r + s;\n`, - range: { pos: 39, end: 51 }, - - }], - newFileContents: { - "/file2.ts": -`import { p, q } from "./file1"; -import { r, s } from "./file3"; - -const a = 1; -const g = p + q; -function e(); -const f = r + s; -const c = 3; -const g = p + q; -function e(); -const f = r + s; -` - } -}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts b/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts deleted file mode 100644 index d0e28c1452139..0000000000000 --- a/tests/cases/fourslash/server/postPasteImportFix_multiplePastes2.ts +++ /dev/null @@ -1,54 +0,0 @@ -/// - -// @Filename: /file1.ts -//// import { aa, bb } from "./other"; -//// export const r = 10; -//// export const s = 12; -//// export const t = aa + bb + r + s; -//// const u = 1; - -// @Filename: /target.ts -//// /*a*/const a = 1; -//// /*b*/const b = 2; -//// const c = 3; -//// const d = 4; - -// @Filename: /other.ts -//// export const aa = 1; -//// export const bb = 2; - -// @Filename: /tsconfig.json -////{ "files": ["file1.ts", "target.ts", "other.ts"] } - -goTo.select("a", "b"); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFix({ - targetFile: "target.ts", - pastes: [{ - text: `export const t = aa + bb + r + s; -const u = 1;\n`, - range: { pos: 13, end: 26 }, - }, - { - text: `export const t = aa + bb + r + s; -const u = 1;\n`, - range: { pos: 39, end: 51 }, - - }], - newFileContents: { - "/target.ts": -`import { r, s } from "./file1"; - -import { aa, bb } from "./other"; - -const a = 1; -export const t = aa + bb + r + s; -const u = 1; -const c = 3; -export const t = aa + bb + r + s; -const u = 1; -` - }, - originalFile: "file1.ts", - copyRange: { start: { line : 3, offset: 0}, end : { line: 4, offset: 12}}, -}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts b/tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts deleted file mode 100644 index 74181e4a5c1eb..0000000000000 --- a/tests/cases/fourslash/server/postPasteImportFix_unknownSourceFile.ts +++ /dev/null @@ -1,43 +0,0 @@ -/// - -// @Filename: /file1.ts -//// export interface Test1 {} -//// export interface Test2 {} -//// export interface Test3 {} -//// export interface Test4 {} - -// @Filename: /file2.ts -//// /*a*/const a = 10; -//// /*b*/const b = 10; -//// const c = 10; - -// @Filename: /tsconfig.json -////{ "files": ["file1.ts", "file2.ts"] } - -goTo.select("a", "b"); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFix({ - targetFile: "file2.ts", - pastes: [{ - text: `interface Testing { - test1: Test1; - test2: Test2; - test3: Test3; - test4: Test4; - }`, - range: { pos: 14, end: 27 }, - }], - newFileContents: { - "/file2.ts": -`import { Test1, Test2, Test3, Test4 } from "./file1"; - -const a = 10; -interface Testing { - test1: Test1; - test2: Test2; - test3: Test3; - test4: Test4; - } -const c = 10;` - } -}); \ No newline at end of file From e6515ea51085e890cd6e3ee66e97698bdcaba09c Mon Sep 17 00:00:00 2001 From: navya9singh Date: Fri, 9 Feb 2024 13:25:39 -0800 Subject: [PATCH 08/41] Removing deleted files --- .../postPasteImportFix_knownSourceFile.js | 347 ----------------- .../postPasteImportFix_multiplePastes1.js | 327 ---------------- .../postPasteImportFix_multiplePastes2.js | 356 ------------------ .../postPasteImportFix_unknownSourceFile.js | 292 -------------- 4 files changed, 1322 deletions(-) delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js deleted file mode 100644 index 23d494bd3ac86..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_knownSourceFile.js +++ /dev/null @@ -1,347 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -export const b = 2; - -//// [/file2.ts] -import { b } from './file1'; -const a = 1; -const c = a + b; -const t = 9; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/target.ts] -export const tt = 2; -function f(); -const p = 1; - -//// [/tsconfig.json] -{ "files": ["file1.ts", "file2.ts", "target.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/file1.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /file1.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/file2.ts", - "/target.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export const b = 2;" - /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts Text-1 "export const tt = 2;\nfunction f();\nconst p = 1;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - file1.ts - Part of 'files' list in tsconfig.json - Imported via './file1' from file 'file2.ts' - file2.ts - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/file1.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file2.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/target.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file2.ts: - {"pollingInterval":500} -/lib.d.ts: - {"pollingInterval":500} -/lib.decorators.d.ts: - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: - {"pollingInterval":500} -/tsconfig.json: - {"pollingInterval":2000} - -watchedFiles *deleted*:: -/target.ts: - {"pollingInterval":500} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 2, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 3, - "type": "request", - "arguments": { - "file": "/target.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 2, - "endOffset": 14, - "targetFile": "/target.ts", - "pastes": [ - { - "text": "const c = a + b;\nconst t = 9;", - "range": { - "file": "/target.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 2, - "endOffset": 14 - } - } - ], - "originalFile": "file2.ts", - "copyRange": { - "start": { - "line": 2, - "offset": 0 - }, - "end": { - "line": 3, - "offset": 0 - } - } - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export const b = 2;" - /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-2-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;export const tt = 2;\nfunction f();;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results -Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export const b = 2;" - /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-2-2 "export const tt = 2;\nfunction f();\nconst p = 1;;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 3, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/file2.ts", - "textChanges": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "export " - } - ] - }, - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { a } from \"./file2\";\n\n" - }, - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { b } from './file1';\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 14 - }, - "newText": "const c = a + b;\nconst t = 9;" - } - ] - } - ] - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js deleted file mode 100644 index 5cbb6a734470d..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes1.js +++ /dev/null @@ -1,327 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -export const p = 10; -export const q = 12; - -//// [/file2.ts] -const a = 1; -const b = 2; -const c = 3; -const d = 4; - -//// [/file3.ts] -export const r = 10; -export const s = 12; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/tsconfig.json] -{ "files": ["file1.ts", "file2.ts", "file3.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/file1.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /file1.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/file2.ts", - "/file3.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file3.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export const p = 10;\nexport const q = 12;" - /file2.ts Text-1 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;" - /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - file1.ts - Part of 'files' list in tsconfig.json - file2.ts - Part of 'files' list in tsconfig.json - file3.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/file1.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file2.ts: *new* - {"pollingInterval":500} -/file3.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "file": "/file2.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file3.ts: - {"pollingInterval":500} -/lib.d.ts: - {"pollingInterval":500} -/lib.decorators.d.ts: - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: - {"pollingInterval":500} -/tsconfig.json: - {"pollingInterval":2000} - -watchedFiles *deleted*:: -/file2.ts: - {"pollingInterval":500} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 2, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 3, - "type": "request", - "arguments": { - "file": "/file2.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 3, - "endOffset": 1, - "targetFile": "/file2.ts", - "pastes": [ - { - "text": "const g = p + q;\nfunction e();\nconst f = r + s;\n", - "range": { - "file": "/file2.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 3, - "endOffset": 1 - } - }, - { - "text": "const g = p + q;\nfunction e();\nconst f = r + s;\n", - "range": { - "file": "/file2.ts", - "startLine": 4, - "startOffset": 1, - "endLine": 4, - "endOffset": 13 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export const p = 10;\nexport const q = 12;" - /file2.ts SVC-2-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst a = 1;\nconst b = 2;\n;" - /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export const p = 10;\nexport const q = 12;" - /file2.ts SVC-2-2 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;;" - /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 3, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/file2.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { p, q } from \"./file1\";\nimport { r, s } from \"./file3\";\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 1 - }, - "newText": "const g = p + q;\nfunction e();\nconst f = r + s;\n" - }, - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 13 - }, - "newText": "const g = p + q;\nfunction e();\nconst f = r + s;\n" - } - ] - } - ] - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js deleted file mode 100644 index 52bad6f959f07..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_multiplePastes2.js +++ /dev/null @@ -1,356 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -import { aa, bb } from "./other"; -export const r = 10; -export const s = 12; -export const t = aa + bb + r + s; -const u = 1; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/other.ts] -export const aa = 1; -export const bb = 2; - -//// [/target.ts] -const a = 1; -const b = 2; -const c = 3; -const d = 4; - -//// [/tsconfig.json] -{ "files": ["file1.ts", "target.ts", "other.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/file1.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /file1.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/target.ts", - "/other.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" - /file1.ts SVC-1-0 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts Text-1 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - other.ts - Imported via "./other" from file 'file1.ts' - Part of 'files' list in tsconfig.json - file1.ts - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/file1.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/other.ts: *new* - {"pollingInterval":500} -/target.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /target.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: - {"pollingInterval":500} -/lib.decorators.d.ts: - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: - {"pollingInterval":500} -/other.ts: - {"pollingInterval":500} -/tsconfig.json: - {"pollingInterval":2000} - -watchedFiles *deleted*:: -/target.ts: - {"pollingInterval":500} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 2, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 3, - "type": "request", - "arguments": { - "file": "/target.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 3, - "endOffset": 1, - "targetFile": "/target.ts", - "pastes": [ - { - "text": "export const t = aa + bb + r + s;\nconst u = 1;\n", - "range": { - "file": "/target.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 3, - "endOffset": 1 - } - }, - { - "text": "export const t = aa + bb + r + s;\nconst u = 1;\n", - "range": { - "file": "/target.ts", - "startLine": 4, - "startOffset": 1, - "endLine": 4, - "endOffset": 13 - } - } - ], - "originalFile": "file1.ts", - "copyRange": { - "start": { - "line": 3, - "offset": 0 - }, - "end": { - "line": 4, - "offset": 12 - } - } - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" - /file1.ts SVC-1-0 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-2-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst a = 1;\nconst b = 2;\n;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results -Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" - /file1.ts SVC-1-0 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-2-2 "const a = 1;\nconst b = 2;\nconst c = 3;\nconst d = 4;;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 3, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { r, s } from \"./file1\";\n\n" - }, - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { aa, bb } from \"./other\";\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 1 - }, - "newText": "export const t = aa + bb + r + s;\nconst u = 1;\n" - }, - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 13 - }, - "newText": "export const t = aa + bb + r + s;\nconst u = 1;\n" - } - ] - } - ] - } - } \ No newline at end of file diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js deleted file mode 100644 index 3e21b762917c8..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFix_unknownSourceFile.js +++ /dev/null @@ -1,292 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -export interface Test1 {} -export interface Test2 {} -export interface Test3 {} -export interface Test4 {} - -//// [/file2.ts] -const a = 10; -const b = 10; -const c = 10; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/tsconfig.json] -{ "files": ["file1.ts", "file2.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/file1.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file1.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /file1.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/file2.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts Text-1 "const a = 10;\nconst b = 10;\nconst c = 10;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - file1.ts - Part of 'files' list in tsconfig.json - file2.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/file1.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file2.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "file": "/file2.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] FileWatcher:: Close:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file1.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: - {"pollingInterval":500} -/lib.decorators.d.ts: - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: - {"pollingInterval":500} -/tsconfig.json: - {"pollingInterval":2000} - -watchedFiles *deleted*:: -/file2.ts: - {"pollingInterval":500} - -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 2, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 3, - "type": "request", - "arguments": { - "file": "/file2.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 2, - "endOffset": 14, - "targetFile": "/file2.ts", - "pastes": [ - { - "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }", - "range": { - "file": "/file2.ts", - "startLine": 2, - "startOffset": 1, - "endLine": 2, - "endOffset": 14 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-2-1 "const a = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const a = 10;\nconst b = 10;;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts SVC-1-0 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-2-2 "const a = 10;\nconst b = 10;\nconst c = 10;;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 3, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/file2.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { Test1, Test2, Test3, Test4 } from \"./file1\";\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 14 - }, - "newText": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" - } - ] - } - ] - } - } \ No newline at end of file From bfe79a969de1549e2b560f1cc37e45863ee2f0d4 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Fri, 9 Feb 2024 14:18:45 -0800 Subject: [PATCH 09/41] fixing eslint errors --- src/harness/client.ts | 6 +++--- src/harness/fourslashImpl.ts | 1 - src/harness/fourslashInterfaceImpl.ts | 4 ++-- src/server/project.ts | 6 ------ src/server/protocol.ts | 2 +- src/server/session.ts | 2 +- src/services/postPasteImportFixes.ts | 18 +++++++++--------- src/services/services.ts | 6 +++--- src/services/types.ts | 4 +--- ...mportNameCodeFix_add_all_missing_imports.ts | 9 ++------- 10 files changed, 22 insertions(+), 36 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index ae166c06ed207..149e43631d69f 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1013,7 +1013,7 @@ export class SessionClient implements LanguageService { getPostPasteImportFixes( targetFile: string, - pastes: Array<{ text: string; range: TextRange }>, + pastes: { text: string; range: TextRange }[], _preferences: UserPreferences, _formatOptions: FormatCodeSettings, copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number } }): PostPasteImportFixes { @@ -1021,7 +1021,7 @@ export class SessionClient implements LanguageService { const args: protocol.GetPostPasteImportFixesRequestArgs = { file: targetFile, pastes: arrayFrom(pastes.map(paste => ({text: paste.text, range: { start: this.positionToOneBasedLineOffset(targetFile, paste.range.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.range.end)}}))), - copySpan: copySpan + copySpan } const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); @@ -1029,7 +1029,7 @@ export class SessionClient implements LanguageService { return { edits: []}; } const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); - return { edits: edits }; + return { edits }; } getProgram(): Program { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 7bfa915f924e2..5518a2526d2ef 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -10,7 +10,6 @@ import { } from "./tsserverLogger"; import ArrayOrSingle = FourSlashInterface.ArrayOrSingle; -import { arrayFrom } from "./_namespaces/ts"; export const enum FourSlashTestType { Native, diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 72fa4a5e047ea..1906512f76a9e 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1886,7 +1886,7 @@ export interface VerifyCodeFixAllOptions { export interface VerifyPostPasteImportFix { targetFile: string; - pastes: Array<{text: string; range: ts.TextRange}>; + pastes: { text: string; range: ts.TextRange }[]; preferences: ts.UserPreferences; copySpan?: { file: string, start: Location, end: Location } } @@ -1933,7 +1933,7 @@ export interface MoveToFileOptions { export interface PostPasteImportFixOptions { readonly newFileContents: { readonly [fileName: string]: string; }; - readonly pastes: Array<{text: string; range: ts.TextRange}>; + readonly pastes: { text: string; range: ts.TextRange }[]; readonly preferences: ts.UserPreferences; readonly copySpan?: { file: string, start: Location, end: Location }; } diff --git a/src/server/project.ts b/src/server/project.ts index 35d12cec6071f..a7e1871623698 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -1,6 +1,3 @@ -import { info } from "console"; -import { FormatContext } from "../services/_namespaces/ts.formatting"; -import { FixInfo, ImportFixWithModuleSpecifier, sortFixInfo } from "../services/codefixes/importFixes"; import * as ts from "./_namespaces/ts"; import { addRange, @@ -23,7 +20,6 @@ import { containsPath, createCacheableExportInfoMap, createLanguageService, - createPackageJsonImportFilter, createResolutionCache, createSymlinkCache, Debug, @@ -69,7 +65,6 @@ import { HasInvalidatedLibResolutions, HasInvalidatedResolutions, HostCancellationToken, - ImportClause, inferredTypesContainingFile, InstallPackageOptions, IScriptSnapshot, @@ -125,7 +120,6 @@ import { StringLiteralLike, stripQuotes, StructureIsReused, - SymbolExportInfo, SymlinkCache, ThrottledCancellationToken, timestamp, diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 9ea16d803c8e4..e82a954a4564d 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -641,7 +641,7 @@ export interface GetPostPasteImportFixesRequest extends Request { } export type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { - pastes: Array<{ text: string; range: TextSpan }>, + pastes: {text: string; range: TextSpan}[], copySpan?: FileSpan, } export interface GetPostPasteImportFixesResponse extends Response { diff --git a/src/server/session.ts b/src/server/session.ts index a14467fd0345e..8a8d444a04b2d 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2799,7 +2799,7 @@ export class Session implements EventSender { private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - const pastes = arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange({file: file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset}, project.getScriptInfoForNormalizedPath(file)!)})) + const pastes = arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange({ file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset }, project.getScriptInfoForNormalizedPath(file)!)})) const result = project.getLanguageService().getPostPasteImportFixes( file, pastes, this.getPreferences(file), this.getFormatOptions(file), args.copySpan); if (result === undefined) { return undefined; diff --git a/src/services/postPasteImportFixes.ts b/src/services/postPasteImportFixes.ts index 611e564e74b4f..e144c4ede50f6 100644 --- a/src/services/postPasteImportFixes.ts +++ b/src/services/postPasteImportFixes.ts @@ -1,7 +1,7 @@ import { addRange, append } from "../compiler/core"; -import { SourceFile, Statement, UserPreferences, TypeChecker, AnyImportOrRequireStatement, Identifier, ModifierFlags, Program, TextRange, CancellationToken, ImportClause, ObjectBindingPattern, TypeOnlyAliasDeclaration, SymbolFlags } from "../compiler/types"; +import { AnyImportOrRequireStatement, CancellationToken, Identifier, ModifierFlags, Program, SourceFile, Statement, SymbolFlags,TextRange, TypeChecker, UserPreferences } from "../compiler/types"; import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; -import { codefix, Debug, factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, ImportKind, insertImports, nodeSeenTracker, Symbol, SymbolExportInfo, textChanges, isIdentifier } from "./_namespaces/ts"; +import { codefix, Debug, factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, insertImports, isIdentifier,nodeSeenTracker, Symbol, textChanges } from "./_namespaces/ts"; import { addExportToChanges, filterImport, forEachImportInStatement, getExistingLocals, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; import { CodeFixContextBase, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; @@ -9,7 +9,7 @@ import { CodeFixContextBase, FileTextChanges, LanguageServiceHost, PostPasteImpo export function postPasteImportFixesProvider( targetFile: SourceFile, host: LanguageServiceHost, - pastes: Array<{ text: string; range: TextRange }>, + pastes: { text: string; range: TextRange }[], preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, @@ -24,7 +24,7 @@ export function postPasteImportFixesProvider( function postPasteFixes ( targetFile: SourceFile, host: LanguageServiceHost, - pastes: Array<{ text: string; range: TextRange }>, + pastes: { text: string; range: TextRange }[], preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, @@ -32,7 +32,7 @@ function postPasteFixes ( originalFile?: SourceFile, copyLocation?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}) { const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastes[0].range.pos) + pastes[0].text + targetFile.getText().slice(pastes[0].range.end)); - let statements: Statement[] = []; + const statements: Statement[] = []; Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); if (originalFile) { @@ -51,10 +51,10 @@ function postPasteFixes ( const context: CodeFixContextBase = { sourceFile: updatedTargetFile.updatedFile, program: updatedTargetFile.originalProgram, - cancellationToken: cancellationToken, - host: host, - preferences: preferences, - formatContext: formatContext + cancellationToken, + host, + preferences, + formatContext } const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); forEachChild(updatedTargetFile.updatedFile, function cb(node) { diff --git a/src/services/services.ts b/src/services/services.ts index aad974e869165..9733e6e616b90 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -241,6 +241,8 @@ import { Path, positionIsSynthesized, PossibleProgramFileInfo, + PostPasteImportFixes, + postPasteImportFixes, PragmaMap, PrivateIdentifier, Program, @@ -319,8 +321,6 @@ import { updateSourceFile, UserPreferences, VariableDeclaration, - postPasteImportFixes, - PostPasteImportFixes, } from "./_namespaces/ts"; import * as NavigateTo from "./_namespaces/ts.NavigateTo"; import * as NavigationBar from "./_namespaces/ts.NavigationBar"; @@ -2093,7 +2093,7 @@ export function createLanguageService( function getPostPasteImportFixes ( targetFile: string, - pastes: Array<{ text: string; range: TextRange }>, + pastes: { text: string; range: TextRange }[], preferences: UserPreferences, formatOptions: FormatCodeSettings, copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }} diff --git a/src/services/types.ts b/src/services/types.ts index 94d7425445528..3093f6aac8814 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -42,8 +42,6 @@ import { TextSpan, UserPreferences, } from "./_namespaces/ts"; -import { FixInfo } from "./_namespaces/ts.codefix"; -import { FormatContext } from "./formatting/formatting"; declare module "../compiler/types" { // Module transform: converted from interface augmentation @@ -689,7 +687,7 @@ export interface LanguageService { dispose(): void; getPostPasteImportFixes( targetFile: string, - pastes: Array<{ text: string; range: TextRange }>, + pastes: { text: string; range: TextRange }[], preferences: UserPreferences, formatOptions: FormatCodeSettings, copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}): PostPasteImportFixes; diff --git a/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts b/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts index 0386beb369950..524a4979f1bc7 100644 --- a/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts +++ b/tests/cases/fourslash/importNameCodeFix_add_all_missing_imports.ts @@ -2,19 +2,15 @@ // @Filename: /a.ts ////export const a: number; -////export const k: number; + // @Filename: /b.ts ////export const b: number; // @Filename: /c.ts ////export const c: number; -// @Filename: /d.ts -////export const k: number; - // @Filename: /main.ts ////a; -////k; ////b; ////c; @@ -23,12 +19,11 @@ verify.codeFixAll({ fixId: "fixMissingImport", fixAllDescription: "Add all missing imports", newFileContent: -`import { a, k } from "./a"; +`import { a } from "./a"; import { b } from "./b"; import { c } from "./c"; a; -k; b; c;`, }); From ab542b5db8c81733dbedc1a70dc1f0ed2f12f5f0 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 12 Feb 2024 11:13:09 -0800 Subject: [PATCH 10/41] fiixng formatting and baseline changes --- src/harness/client.ts | 18 +- src/harness/fourslashImpl.ts | 2 +- src/harness/fourslashInterfaceImpl.ts | 12 +- src/server/project.ts | 2 +- src/server/protocol.ts | 6 +- src/server/session.ts | 6 +- .../_namespaces/ts.postPasteImportFixes.ts | 2 +- src/services/codefixes/importFixes.ts | 4 +- src/services/postPasteImportFixes.ts | 103 ++++++--- src/services/services.ts | 12 +- src/services/types.ts | 13 +- src/testRunner/tests.ts | 2 +- .../tsserver/postPasteImportFixes.ts | 8 +- .../reference/APILibCheck.errors.txt | 47 ++++ tests/baselines/reference/api/typescript.d.ts | 73 +++++++ .../Returns-the-same-file-unchanged-.js | 203 ++++++++++++++++++ 16 files changed, 444 insertions(+), 69 deletions(-) create mode 100644 tests/baselines/reference/APILibCheck.errors.txt create mode 100644 tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js diff --git a/src/harness/client.ts b/src/harness/client.ts index 149e43631d69f..1e022eb7be7f6 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1013,20 +1013,20 @@ export class SessionClient implements LanguageService { getPostPasteImportFixes( targetFile: string, - pastes: { text: string; range: TextRange }[], - _preferences: UserPreferences, - _formatOptions: FormatCodeSettings, - copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number } }): PostPasteImportFixes { - + pastes: { text: string; range: TextRange; }[], + _preferences: UserPreferences, + _formatOptions: FormatCodeSettings, + copySpan?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, + ): PostPasteImportFixes { const args: protocol.GetPostPasteImportFixesRequestArgs = { file: targetFile, - pastes: arrayFrom(pastes.map(paste => ({text: paste.text, range: { start: this.positionToOneBasedLineOffset(targetFile, paste.range.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.range.end)}}))), - copySpan - } + pastes: arrayFrom(pastes.map(paste => ({ text: paste.text, range: { start: this.positionToOneBasedLineOffset(targetFile, paste.range.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.range.end) } }))), + copySpan, + }; const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); if (!response.body) { - return { edits: []}; + return { edits: [] }; } const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); return { edits }; diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 5518a2526d2ef..f6c6aaa316ad5 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3563,7 +3563,7 @@ export class TestState { } public verifyPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void { - const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.copySpan); + const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.copySpan); this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 1906512f76a9e..b6a7e5b76ead4 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1,4 +1,6 @@ -import { Location } from "../server/protocol"; +import { + Location, +} from "../server/protocol"; import * as FourSlash from "./_namespaces/FourSlash"; import * as ts from "./_namespaces/ts"; @@ -1886,9 +1888,9 @@ export interface VerifyCodeFixAllOptions { export interface VerifyPostPasteImportFix { targetFile: string; - pastes: { text: string; range: ts.TextRange }[]; + pastes: { text: string; range: ts.TextRange; }[]; preferences: ts.UserPreferences; - copySpan?: { file: string, start: Location, end: Location } + copySpan?: { file: string; start: Location; end: Location; }; } export interface VerifyRefactorOptions { @@ -1933,9 +1935,9 @@ export interface MoveToFileOptions { export interface PostPasteImportFixOptions { readonly newFileContents: { readonly [fileName: string]: string; }; - readonly pastes: { text: string; range: ts.TextRange }[]; + readonly pastes: { text: string; range: ts.TextRange; }[]; readonly preferences: ts.UserPreferences; - readonly copySpan?: { file: string, start: Location, end: Location }; + readonly copySpan?: { file: string; start: Location; end: Location; }; } export type RenameLocationsOptions = readonly RenameLocationOptions[] | { diff --git a/src/server/project.ts b/src/server/project.ts index a7e1871623698..80ca6d30398c7 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2213,7 +2213,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: ts.Program | undefined } { + updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: ts.Program | undefined; } { const originalProgram = this.program; this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); this.updateGraph(); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index e82a954a4564d..7f6fee9920b13 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -641,9 +641,9 @@ export interface GetPostPasteImportFixesRequest extends Request { } export type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { - pastes: {text: string; range: TextSpan}[], - copySpan?: FileSpan, -} + pastes: { text: string; range: TextSpan; }[]; + copySpan?: FileSpan; +}; export interface GetPostPasteImportFixesResponse extends Response { body: PostPasteImportAction; } diff --git a/src/server/session.ts b/src/server/session.ts index 8a8d444a04b2d..050323155381c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2799,8 +2799,8 @@ export class Session implements EventSender { private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - const pastes = arrayFrom(args.pastes).map(paste => ({text: paste.text, range: this.getRange({ file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset }, project.getScriptInfoForNormalizedPath(file)!)})) - const result = project.getLanguageService().getPostPasteImportFixes( file, pastes, this.getPreferences(file), this.getFormatOptions(file), args.copySpan); + const pastes = arrayFrom(args.pastes).map(paste => ({ text: paste.text, range: this.getRange({ file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset }, project.getScriptInfoForNormalizedPath(file)!) })); + const result = project.getLanguageService().getPostPasteImportFixes(file, pastes, this.getPreferences(file), this.getFormatOptions(file), args.copySpan); if (result === undefined) { return undefined; } @@ -2941,7 +2941,7 @@ export class Session implements EventSender { } private mapPostPasteAction({ edits }: PostPasteImportFixes): protocol.PostPasteImportAction { - return { edits: this.mapTextChangesToCodeEdits(edits)}; + return { edits: this.mapTextChangesToCodeEdits(edits) }; } private mapTextChangesToCodeEdits(textChanges: readonly FileTextChanges[]): protocol.FileCodeEdits[] { diff --git a/src/services/_namespaces/ts.postPasteImportFixes.ts b/src/services/_namespaces/ts.postPasteImportFixes.ts index b75b8ec1d96cc..0f1f3e8189d63 100644 --- a/src/services/_namespaces/ts.postPasteImportFixes.ts +++ b/src/services/_namespaces/ts.postPasteImportFixes.ts @@ -1 +1 @@ -export * from "../postPasteImportFixes"; \ No newline at end of file +export * from "../postPasteImportFixes"; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 66a4896e0f97b..ce2ee8c6ea3ed 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -244,7 +244,7 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu if (!info || !info.length) return; addImport(first(info)); } - + function addImportFromDiagnostic(diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) { const info = getFixInfos(context, diagnostic.code, diagnostic.start, useAutoImportProvider); if (!info || !info.length) return; @@ -1017,7 +1017,7 @@ export function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModul compareModuleSpecifiers(a.fix, b.fix, sourceFile, program, packageJsonImportFilter.allowsImportingSpecifier, _toPath)); } -function getFixInfosWithoutDiagnostic(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly FixInfo[] | undefined { +function getFixInfosWithoutDiagnostic(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly FixInfo[] | undefined { const info = getFixesInfoForNonUMDImport(context, symbolToken, useAutoImportProvider); const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host); return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); diff --git a/src/services/postPasteImportFixes.ts b/src/services/postPasteImportFixes.ts index e144c4ede50f6..220369ae1cc8c 100644 --- a/src/services/postPasteImportFixes.ts +++ b/src/services/postPasteImportFixes.ts @@ -1,43 +1,91 @@ -import { addRange, append } from "../compiler/core"; -import { AnyImportOrRequireStatement, CancellationToken, Identifier, ModifierFlags, Program, SourceFile, Statement, SymbolFlags,TextRange, TypeChecker, UserPreferences } from "../compiler/types"; -import { hasSyntacticModifier, skipAlias } from "../compiler/utilities"; -import { codefix, Debug, factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, insertImports, isIdentifier,nodeSeenTracker, Symbol, textChanges } from "./_namespaces/ts"; -import { addExportToChanges, filterImport, forEachImportInStatement, getExistingLocals, getTopLevelDeclarationStatement, getUsageInfo, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; -import { CodeFixContextBase, FileTextChanges, LanguageServiceHost, PostPasteImportFixes } from "./types"; +import { + addRange, + append, +} from "../compiler/core"; +import { + AnyImportOrRequireStatement, + CancellationToken, + Identifier, + ModifierFlags, + Program, + SourceFile, + Statement, + SymbolFlags, + TextRange, + TypeChecker, + UserPreferences, +} from "../compiler/types"; +import { + hasSyntacticModifier, + skipAlias, +} from "../compiler/utilities"; +import { + codefix, + Debug, + factory, + fileShouldUseJavaScriptRequire, + forEachChild, + formatting, + getQuotePreference, + insertImports, + isIdentifier, + nodeSeenTracker, + Symbol, + textChanges, +} from "./_namespaces/ts"; +import { + addExportToChanges, + filterImport, + forEachImportInStatement, + getExistingLocals, + getTopLevelDeclarationStatement, + getUsageInfo, + isTopLevelDeclaration, + makeImportOrRequire, + moduleSpecifierFromImport, + nameOfTopLevelDeclaration, +} from "./refactors/moveToFile"; +import { + CodeFixContextBase, + FileTextChanges, + LanguageServiceHost, + PostPasteImportFixes, +} from "./types"; /** @internal */ export function postPasteImportFixesProvider( - targetFile: SourceFile, + targetFile: SourceFile, host: LanguageServiceHost, - pastes: { text: string; range: TextRange }[], + pastes: { text: string; range: TextRange; }[], preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, originalFile?: SourceFile, - copyLocation?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}): PostPasteImportFixes { - + copyLocation?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, +): PostPasteImportFixes { const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, host, pastes, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)); - return { edits: changes }; + return { edits: changes }; } -function postPasteFixes ( - targetFile: SourceFile, +function postPasteFixes( + targetFile: SourceFile, host: LanguageServiceHost, - pastes: { text: string; range: TextRange }[], + pastes: { text: string; range: TextRange; }[], preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, changes: textChanges.ChangeTracker, originalFile?: SourceFile, - copyLocation?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}) { + copyLocation?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, +) { const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastes[0].range.pos) + pastes[0].text + targetFile.getText().slice(pastes[0].range.end)); const statements: Statement[] = []; Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); - + if (originalFile) { - addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); - const usage = getUsageInfo(originalFile, statements, updatedTargetFile.originalProgram.getTypeChecker(), getExistingLocals(updatedTargetFile.updatedFile, statements, updatedTargetFile.originalProgram.getTypeChecker())); + addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); + const usage = getUsageInfo(originalFile, statements, updatedTargetFile.originalProgram.getTypeChecker(), getExistingLocals(updatedTargetFile.updatedFile, statements, updatedTargetFile.originalProgram.getTypeChecker())); const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); const imports = getImportsFromKnownOriginalFile(originalFile, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); @@ -45,7 +93,7 @@ function postPasteFixes ( insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); - host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); + host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } else { const context: CodeFixContextBase = { @@ -53,14 +101,14 @@ function postPasteFixes ( program: updatedTargetFile.originalProgram, cancellationToken, host, - preferences, - formatContext - } + preferences, + formatContext, + }; const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); forEachChild(updatedTargetFile.updatedFile, function cb(node) { if (isIdentifier(node)) { if (!updatedTargetFile.originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { - //generate imports + // generate imports importAdder.addImportsForUnknownSymbols(context, node, /*useAutoImportProvider*/ true); } } @@ -71,7 +119,7 @@ function postPasteFixes ( importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } - pastes.forEach(({ text, range}) => { + pastes.forEach(({ text, range }) => { range.pos === range.end ? changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text) : changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text); }); } @@ -86,7 +134,8 @@ function getImportsFromKnownOriginalFile( changes: textChanges.ChangeTracker, preferences: UserPreferences, host: LanguageServiceHost, - checker: TypeChecker) { + checker: TypeChecker, +) { const copiedOldImports: AnyImportOrRequireStatement[] = []; importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { try { @@ -134,5 +183,5 @@ function getImportsFromKnownOriginalFile( } }); - return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)) -} \ No newline at end of file + return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)); +} diff --git a/src/services/services.ts b/src/services/services.ts index 9733e6e616b90..d0bdc5ba92946 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2091,16 +2091,16 @@ export function createLanguageService( }; } - function getPostPasteImportFixes ( + function getPostPasteImportFixes( targetFile: string, - pastes: { text: string; range: TextRange }[], + pastes: { text: string; range: TextRange; }[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }} - ): PostPasteImportFixes{ + copySpan?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, + ): PostPasteImportFixes { synchronizeHostData(); const originalSourceFile = copySpan ? getValidSourceFile(copySpan.file) : undefined; - const edits = postPasteImportFixes.postPasteImportFixesProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host),cancellationToken, originalSourceFile, copySpan); + const edits = postPasteImportFixes.postPasteImportFixesProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), cancellationToken, originalSourceFile, copySpan); return edits; } @@ -3175,7 +3175,7 @@ export function createLanguageService( uncommentSelection, provideInlayHints, getSupportedCodeFixes, - getPostPasteImportFixes + getPostPasteImportFixes, }; switch (languageServiceMode) { diff --git a/src/services/types.ts b/src/services/types.ts index 3093f6aac8814..8276d39fca5fd 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -431,7 +431,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ updateTargetFile?(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined, updatedProgram: Program | undefined, originalProgram: Program | undefined }; + /** @internal */ updateTargetFile?(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: Program | undefined; }; /** @internal */ revertUpdatedFile?(rootFile: string, updatedText: string, originalText: string): void; jsDocParsingMode?: JSDocParsingMode | undefined; } @@ -687,10 +687,11 @@ export interface LanguageService { dispose(): void; getPostPasteImportFixes( targetFile: string, - pastes: { text: string; range: TextRange }[], - preferences: UserPreferences, - formatOptions: FormatCodeSettings, - copySpan?: { file: string, start: { line: number, offset: number }, end: { line: number, offset: number }}): PostPasteImportFixes; + pastes: { text: string; range: TextRange; }[], + preferences: UserPreferences, + formatOptions: FormatCodeSettings, + copySpan?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, + ): PostPasteImportFixes; } export interface JsxClosingTagInfo { @@ -715,7 +716,7 @@ export const enum OrganizeImportsMode { export interface PostPasteImportFixes { edits: readonly FileTextChanges[]; -} +} export interface OrganizeImportsArgs extends CombinedCodeFixScope { /** @deprecated Use `mode` instead */ diff --git a/src/testRunner/tests.ts b/src/testRunner/tests.ts index a7fc40d26c7ff..4be8d6dd1d3f8 100644 --- a/src/testRunner/tests.ts +++ b/src/testRunner/tests.ts @@ -214,4 +214,4 @@ import "./unittests/debugDeprecation"; import "./unittests/tsserver/inconsistentErrorInEditor"; import "./unittests/tsserver/getMoveToRefactoringFileSuggestions"; import "./unittests/skipJSDocParsing"; -import "./unittests/tsserver/postPasteImportFixes"; \ No newline at end of file +import "./unittests/tsserver/postPasteImportFixes"; diff --git a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts index ecb55a5f84af6..6935f487b4d37 100644 --- a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts +++ b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts @@ -12,11 +12,11 @@ import { describe("unittests:: tsserver:: postPasteImportFixes", () => { it("returns the same file unchanged, after updating and reverting changes added to a file", () => { const target: File = { - path : "/project/a/target.ts", + path: "/project/a/target.ts", content: `const a = 1; const b = 2; const c = 3;`, - } + }; const tsconfig: File = { path: "/project/tsconfig.json", content: "{}", @@ -33,10 +33,10 @@ const c = 3;`; const originalContent = target.content; const originalProgram = session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getProgram(); - + const hostProject = session.getProjectService().configuredProjects.get(tsconfig.path)!; const updatedContent = hostProject.updateTargetFile(target.path, target.content, pastedText); - + if (updatedContent.updatedFile !== undefined) { hostProject.revertUpdatedFile(target.path, updatedContent.updatedFile.getText(), originalContent); } diff --git a/tests/baselines/reference/APILibCheck.errors.txt b/tests/baselines/reference/APILibCheck.errors.txt new file mode 100644 index 0000000000000..b81eac4cd40b5 --- /dev/null +++ b/tests/baselines/reference/APILibCheck.errors.txt @@ -0,0 +1,47 @@ +typescript.d.ts(10425,55): error TS2304: Cannot find name 'SymbolExportInfo'. +typescript.d.ts(10426,90): error TS2304: Cannot find name 'SymbolExportInfo'. +typescript.d.ts(10426,120): error TS2304: Cannot find name 'FixAddToExistingImportInfo'. +typescript.d.ts(10438,38): error TS2304: Cannot find name 'PackageJsonImportFilter'. +typescript.d.ts(10443,45): error TS2552: Cannot find name 'FixUseNamespaceImport'. Did you mean 'NamespaceImport'? +typescript.d.ts(10443,69): error TS2304: Cannot find name 'FixAddJsdocTypeImport'. +typescript.d.ts(10443,93): error TS2304: Cannot find name 'FixAddToExistingImport'. +typescript.d.ts(10443,118): error TS2304: Cannot find name 'FixAddNewImport'. +typescript.d.ts(10445,27): error TS2304: Cannot find name 'ImportFix'. +typescript.internal.d.ts(25311,120): error TS2304: Cannot find name 'FixAddToExistingImportInfo'. +typescript.internal.d.ts(25365,45): error TS2304: Cannot find name 'FixUseNamespaceImport'. +typescript.internal.d.ts(25365,69): error TS2304: Cannot find name 'FixAddJsdocTypeImport'. +typescript.internal.d.ts(25365,93): error TS2304: Cannot find name 'FixAddToExistingImport'. +typescript.internal.d.ts(25365,118): error TS2304: Cannot find name 'FixAddNewImport'. +typescript.internal.d.ts(25367,27): error TS2304: Cannot find name 'ImportFix'. + + +==== index.ts (0 errors) ==== + import ts = require("typescript"); + import tsInternal = require("typescript-internal"); + import tsserverlibrary = require("tsserverlibrary"); + import tsserverlibraryInternal = require("tsserverlibrary-internal"); + +==== node_modules/typescript/package.json (0 errors) ==== + { + "name": "typescript", + "types": "/.ts/typescript.d.ts" + } + +==== node_modules/typescript-internal/package.json (0 errors) ==== + { + "name": "typescript-internal", + "types": "/.ts/typescript.internal.d.ts" + } + +==== node_modules/tsserverlibrary/package.json (0 errors) ==== + { + "name": "tsserverlibrary", + "types": "/.ts/tsserverlibrary.d.ts" + } + +==== node_modules/tsserverlibrary-internal/package.json (0 errors) ==== + { + "name": "tsserverlibrary-internal", + "types": "/.ts/tsserverlibrary.internal.d.ts" + } + \ No newline at end of file diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 100081fb8cccf..e9868ed0a6ddc 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -161,6 +161,7 @@ declare namespace ts { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", + GetPostPasteImportFixes = "getPostPasteImportFixes", OrganizeImports = "organizeImports", GetEditsForFileRename = "getEditsForFileRename", ConfigurePlugin = "configurePlugin", @@ -545,6 +546,26 @@ declare namespace ts { files: string[]; }; } + /** + * Request refactorings at a given position post pasting text from some other location. + */ + interface GetPostPasteImportFixesRequest extends Request { + command: CommandTypes.GetPostPasteImportFixes; + arguments: GetPostPasteImportFixesRequestArgs; + } + type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { + pastes: { + text: string; + range: TextSpan; + }[]; + copySpan?: FileSpan; + }; + interface GetPostPasteImportFixesResponse extends Response { + body: PostPasteImportAction; + } + interface PostPasteImportAction { + edits: FileCodeEdits[]; + } /** * A set of one or more available refactoring actions, grouped under a parent refactoring. */ @@ -4100,6 +4121,7 @@ declare namespace ts { private getApplicableRefactors; private getEditsForRefactor; private getMoveToRefactoringFileSuggestions; + private getPostPasteImportFixes; private organizeImports; private getEditsForFileRename; private getCodeFixes; @@ -4108,6 +4130,7 @@ declare namespace ts { private getStartAndEndPosition; private mapCodeAction; private mapCodeFixAction; + private mapPostPasteAction; private mapTextChangesToCodeEdits; private mapTextChangeToCodeEdit; private convertTextChangeToCodeEdit; @@ -10398,6 +10421,33 @@ declare namespace ts { readDirectory(rootDir: string, extensions: readonly string[], excludes: readonly string[] | undefined, includes: readonly string[] | undefined, depth?: number): string[]; } } + namespace codefix { + function getImportFixes(exportInfos: readonly SymbolExportInfo[], usagePosition: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, program: Program, sourceFile: SourceFile, host: LanguageServiceHost, preferences: UserPreferences, importMap?: { + getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo) => readonly FixAddToExistingImportInfo[]; + }, fromCacheOnly?: boolean): { + computedWithoutCacheCount: number; + fixes: readonly ImportFixWithModuleSpecifier[]; + }; + function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean; + function sortFixInfo( + fixes: readonly (FixInfo & { + fix: ImportFixWithModuleSpecifier; + })[], + sourceFile: SourceFile, + program: Program, + packageJsonImportFilter: PackageJsonImportFilter, + host: LanguageServiceHost, + ): readonly (FixInfo & { + fix: ImportFixWithModuleSpecifier; + })[]; + type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; + interface FixInfo { + readonly fix: ImportFix; + readonly symbolName: string; + readonly errorIdentifierText: string | undefined; + readonly isJsxNamespaceFix?: boolean; + } + } function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatCodeSettings; /** * Represents an immutable snapshot of a script at a specified time.Once acquired, the @@ -10672,6 +10722,26 @@ declare namespace ts { uncommentSelection(fileName: string, textRange: TextRange): TextChange[]; getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; + getPostPasteImportFixes( + targetFile: string, + pastes: { + text: string; + range: TextRange; + }[], + preferences: UserPreferences, + formatOptions: FormatCodeSettings, + copySpan?: { + file: string; + start: { + line: number; + offset: number; + }; + end: { + line: number; + offset: number; + }; + }, + ): PostPasteImportFixes; } interface JsxClosingTagInfo { readonly newText: string; @@ -10689,6 +10759,9 @@ declare namespace ts { SortAndCombine = "SortAndCombine", RemoveUnused = "RemoveUnused", } + interface PostPasteImportFixes { + edits: readonly FileTextChanges[]; + } interface OrganizeImportsArgs extends CombinedCodeFixScope { /** @deprecated Use `mode` instead */ skipDestructiveCodeActions?: boolean; diff --git a/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js b/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js new file mode 100644 index 0000000000000..c74eca0d1f6e0 --- /dev/null +++ b/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js @@ -0,0 +1,203 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +Before request +//// [/project/a/target.ts] +const a = 1; +const b = 2; +const c = 3; + +//// [/project/tsconfig.json] +{} + + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/project/a/target.ts" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] Search path: /project/a +Info seq [hh:mm:ss:mss] For info: /project/a/target.ts :: Config file name: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/project/tsconfig.json", + "reason": "Creating possible configured project for /project/a/target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { + "rootNames": [ + "/project/a/target.ts" + ], + "options": { + "configFilePath": "/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" + + + a/target.ts + Matched by default include pattern '**/*' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "telemetry", + "body": { + "telemetryEventName": "projectInfo", + "payload": { + "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", + "fileStats": { + "js": 0, + "jsSize": 0, + "jsx": 0, + "jsxSize": 0, + "ts": 1, + "tsSize": 38, + "tsx": 0, + "tsxSize": 0, + "dts": 0, + "dtsSize": 0, + "deferred": 0, + "deferredSize": 0 + }, + "compilerOptions": {}, + "typeAcquisition": { + "enable": false, + "include": false, + "exclude": false + }, + "extends": false, + "files": false, + "include": false, + "exclude": false, + "compileOnSave": false, + "configFileName": "tsconfig.json", + "projectType": "configured", + "languageServiceEnabled": true, + "version": "FakeVersion" + } + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/project/a/target.ts", + "configFile": "/project/tsconfig.json", + "diagnostics": [ + { + "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +PolledWatches:: +/a/lib/lib.d.ts: *new* + {"pollingInterval":500} + +FsWatches:: +/project/tsconfig.json: *new* + {} + +FsWatchesRecursive:: +/project: *new* + {} + +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-1 "const a = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-2 "const a = 1;\nconst b = 2;\nconst c = 3;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- \ No newline at end of file From 9ef3d85d5453399b2d45973352c814c021c4922b Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 12 Feb 2024 12:15:40 -0800 Subject: [PATCH 11/41] Minor fixes --- src/server/session.ts | 3 +- src/services/codefixes/importFixes.ts | 10 ++-- src/services/services.ts | 3 +- .../reference/APILibCheck.errors.txt | 47 ------------------- tests/baselines/reference/api/typescript.d.ts | 27 ----------- 5 files changed, 7 insertions(+), 83 deletions(-) delete mode 100644 tests/baselines/reference/APILibCheck.errors.txt diff --git a/src/server/session.ts b/src/server/session.ts index 050323155381c..c7811dd2d47ca 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2804,8 +2804,7 @@ export class Session implements EventSender { if (result === undefined) { return undefined; } - const allResults = this.mapPostPasteAction(result); - return allResults; + return this.mapPostPasteAction(result); } private organizeImports(args: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): readonly protocol.FileCodeEdits[] | readonly FileTextChanges[] { diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index ce2ee8c6ea3ed..b785f68b6671b 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -481,7 +481,7 @@ const enum AddAsTypeOnly { NotAllowed = 1 << 2, } type ImportFix = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport | FixPromoteTypeOnlyImport; -export type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; +type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; // Properties are be undefined if fix is derived from an existing import interface ImportFixBase { @@ -633,7 +633,7 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } } -export function getImportFixes( +function getImportFixes( exportInfos: readonly SymbolExportInfo[], usagePosition: number | undefined, isValidTypeOnlyUseSite: boolean, @@ -840,7 +840,7 @@ function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile }; } -export function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean { +function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean { // 1. TypeScript files don't use require variable declarations if (!isSourceFileJS(sourceFile)) { return false; @@ -981,7 +981,7 @@ function newImportInfoFromExistingSpecifier( } } -export interface FixInfo { +interface FixInfo { readonly fix: ImportFix; readonly symbolName: string; readonly errorIdentifierText: string | undefined; @@ -1009,7 +1009,7 @@ function getFixInfos(context: CodeFixContextBase, errorCode: number, pos: number return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); } -export function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] { +function sortFixInfo(fixes: readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[], sourceFile: SourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): readonly (FixInfo & { fix: ImportFixWithModuleSpecifier; })[] { const _toPath = (fileName: string) => toPath(fileName, host.getCurrentDirectory(), hostGetCanonicalFileName(host)); return sort(fixes, (a, b) => compareBooleans(!!a.isJsxNamespaceFix, !!b.isJsxNamespaceFix) || diff --git a/src/services/services.ts b/src/services/services.ts index d0bdc5ba92946..876ea3bc496b1 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2100,8 +2100,7 @@ export function createLanguageService( ): PostPasteImportFixes { synchronizeHostData(); const originalSourceFile = copySpan ? getValidSourceFile(copySpan.file) : undefined; - const edits = postPasteImportFixes.postPasteImportFixesProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), cancellationToken, originalSourceFile, copySpan); - return edits; + return postPasteImportFixes.postPasteImportFixesProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), cancellationToken, originalSourceFile, copySpan); } function getNodeForQuickInfo(node: Node): Node { diff --git a/tests/baselines/reference/APILibCheck.errors.txt b/tests/baselines/reference/APILibCheck.errors.txt deleted file mode 100644 index b81eac4cd40b5..0000000000000 --- a/tests/baselines/reference/APILibCheck.errors.txt +++ /dev/null @@ -1,47 +0,0 @@ -typescript.d.ts(10425,55): error TS2304: Cannot find name 'SymbolExportInfo'. -typescript.d.ts(10426,90): error TS2304: Cannot find name 'SymbolExportInfo'. -typescript.d.ts(10426,120): error TS2304: Cannot find name 'FixAddToExistingImportInfo'. -typescript.d.ts(10438,38): error TS2304: Cannot find name 'PackageJsonImportFilter'. -typescript.d.ts(10443,45): error TS2552: Cannot find name 'FixUseNamespaceImport'. Did you mean 'NamespaceImport'? -typescript.d.ts(10443,69): error TS2304: Cannot find name 'FixAddJsdocTypeImport'. -typescript.d.ts(10443,93): error TS2304: Cannot find name 'FixAddToExistingImport'. -typescript.d.ts(10443,118): error TS2304: Cannot find name 'FixAddNewImport'. -typescript.d.ts(10445,27): error TS2304: Cannot find name 'ImportFix'. -typescript.internal.d.ts(25311,120): error TS2304: Cannot find name 'FixAddToExistingImportInfo'. -typescript.internal.d.ts(25365,45): error TS2304: Cannot find name 'FixUseNamespaceImport'. -typescript.internal.d.ts(25365,69): error TS2304: Cannot find name 'FixAddJsdocTypeImport'. -typescript.internal.d.ts(25365,93): error TS2304: Cannot find name 'FixAddToExistingImport'. -typescript.internal.d.ts(25365,118): error TS2304: Cannot find name 'FixAddNewImport'. -typescript.internal.d.ts(25367,27): error TS2304: Cannot find name 'ImportFix'. - - -==== index.ts (0 errors) ==== - import ts = require("typescript"); - import tsInternal = require("typescript-internal"); - import tsserverlibrary = require("tsserverlibrary"); - import tsserverlibraryInternal = require("tsserverlibrary-internal"); - -==== node_modules/typescript/package.json (0 errors) ==== - { - "name": "typescript", - "types": "/.ts/typescript.d.ts" - } - -==== node_modules/typescript-internal/package.json (0 errors) ==== - { - "name": "typescript-internal", - "types": "/.ts/typescript.internal.d.ts" - } - -==== node_modules/tsserverlibrary/package.json (0 errors) ==== - { - "name": "tsserverlibrary", - "types": "/.ts/tsserverlibrary.d.ts" - } - -==== node_modules/tsserverlibrary-internal/package.json (0 errors) ==== - { - "name": "tsserverlibrary-internal", - "types": "/.ts/tsserverlibrary.internal.d.ts" - } - \ No newline at end of file diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index e9868ed0a6ddc..3b1eb21d70971 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -10421,33 +10421,6 @@ declare namespace ts { readDirectory(rootDir: string, extensions: readonly string[], excludes: readonly string[] | undefined, includes: readonly string[] | undefined, depth?: number): string[]; } } - namespace codefix { - function getImportFixes(exportInfos: readonly SymbolExportInfo[], usagePosition: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, program: Program, sourceFile: SourceFile, host: LanguageServiceHost, preferences: UserPreferences, importMap?: { - getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo) => readonly FixAddToExistingImportInfo[]; - }, fromCacheOnly?: boolean): { - computedWithoutCacheCount: number; - fixes: readonly ImportFixWithModuleSpecifier[]; - }; - function shouldUseRequire(sourceFile: SourceFile, program: Program): boolean; - function sortFixInfo( - fixes: readonly (FixInfo & { - fix: ImportFixWithModuleSpecifier; - })[], - sourceFile: SourceFile, - program: Program, - packageJsonImportFilter: PackageJsonImportFilter, - host: LanguageServiceHost, - ): readonly (FixInfo & { - fix: ImportFixWithModuleSpecifier; - })[]; - type ImportFixWithModuleSpecifier = FixUseNamespaceImport | FixAddJsdocTypeImport | FixAddToExistingImport | FixAddNewImport; - interface FixInfo { - readonly fix: ImportFix; - readonly symbolName: string; - readonly errorIdentifierText: string | undefined; - readonly isJsxNamespaceFix?: boolean; - } - } function getDefaultFormatCodeSettings(newLineCharacter?: string): FormatCodeSettings; /** * Represents an immutable snapshot of a script at a specified time.Once acquired, the From 7f41f3098f361a57c763775937a35c544fced3b0 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 12 Feb 2024 15:41:16 -0800 Subject: [PATCH 12/41] Fixing baselines --- .../postPasteImportFixes_existingImports1.js | 78 ++++++++++++++++- .../postPasteImportFixes_existingImports2.js | 86 ++++++++++++++++++- .../postPasteImportFixes_knownSourceFile.js | 70 ++++++++++++++- .../postPasteImportFixes_multiplePastes1.js | 70 ++++++++++++++- .../postPasteImportFixes_multiplePastes2.js | 70 ++++++++++++++- .../postPasteImportFixes_pasteComments.js | 54 +++++++++++- .../postPasteImportFixes_unknownSourceFile.js | 62 ++++++++++++- .../Returns-the-same-file-unchanged-.js | 17 +++- 8 files changed, 476 insertions(+), 31 deletions(-) diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js index 8477babc0f4b3..b1045e92c98af 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js @@ -70,7 +70,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (7) /lib.d.ts Text-1 lib.d.ts-Text @@ -144,6 +144,41 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -210,7 +245,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (7) /lib.d.ts Text-1 lib.d.ts-Text @@ -223,7 +258,7 @@ Info seq [hh:mm:ss:mss] Files (7) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (7) /lib.d.ts Text-1 lib.d.ts-Text @@ -276,4 +311,39 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js index 8b9854f9637de..a821cde26a378 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js @@ -78,7 +78,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (8) /lib.d.ts Text-1 lib.d.ts-Text @@ -159,6 +159,45 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/originalFile.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -236,7 +275,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (8) /lib.d.ts Text-1 lib.d.ts-Text @@ -252,7 +291,7 @@ Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (8) /lib.d.ts Text-1 lib.d.ts-Text @@ -317,4 +356,43 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/originalFile.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js index 60fb7ede7b610..5bc51ef0860f4 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js @@ -66,7 +66,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -134,6 +134,37 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -211,7 +242,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -225,7 +256,7 @@ Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -304,4 +335,35 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js index 727d587a6636e..ab8f2527e700b 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js @@ -68,7 +68,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -135,6 +135,37 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -214,7 +245,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -226,7 +257,7 @@ Info seq [hh:mm:ss:mss] Files (6) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -289,4 +320,35 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js index abd684c7c5130..56cfa5f0d74a3 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js @@ -70,7 +70,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -138,6 +138,37 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -228,7 +259,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -243,7 +274,7 @@ Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (6) /lib.d.ts Text-1 lib.d.ts-Text @@ -317,4 +348,35 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js index c6cb16bb03451..6bca87a4addb3 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js @@ -53,7 +53,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (4) /lib.d.ts Text-1 lib.d.ts-Text @@ -110,6 +110,29 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -176,7 +199,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (4) /lib.d.ts Text-1 lib.d.ts-Text @@ -186,7 +209,7 @@ Info seq [hh:mm:ss:mss] Files (4) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (4) /lib.d.ts Text-1 lib.d.ts-Text @@ -225,4 +248,27 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js index ddc26b007de3e..596ea7611195c 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js @@ -61,7 +61,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (5) /lib.d.ts Text-1 lib.d.ts-Text @@ -123,6 +123,33 @@ watchedFiles:: /tsconfig.json: *new* {"pollingInterval":2000} +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json + Info seq [hh:mm:ss:mss] request: { "seq": 1, @@ -189,7 +216,7 @@ Info seq [hh:mm:ss:mss] request: "command": "getPostPasteImportFixes" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (5) /lib.d.ts Text-1 lib.d.ts-Text @@ -200,7 +227,7 @@ Info seq [hh:mm:ss:mss] Files (5) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (5) /lib.d.ts Text-1 lib.d.ts-Text @@ -251,4 +278,31 @@ Info seq [hh:mm:ss:mss] response: } ] } - } \ No newline at end of file + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json diff --git a/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js b/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js index c74eca0d1f6e0..cd4e9f43ba699 100644 --- a/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js +++ b/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js @@ -45,7 +45,7 @@ Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefi Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json Version: 1 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (1) /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" @@ -187,15 +187,26 @@ FsWatchesRecursive:: /project: *new* {} +Projects:: +/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/project/a/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /project/tsconfig.json *default* + Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json Version: 2 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (1) /project/a/target.ts SVC-1-1 "const a = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json Version: 3 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (1) /project/a/target.ts SVC-1-2 "const a = 1;\nconst b = 2;\nconst c = 3;" From d3816d3ac2c042e0f1bea8956b2854de8d6c8c07 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 19 Feb 2024 21:54:34 -0800 Subject: [PATCH 13/41] changes based on reviews 1 --- src/harness/client.ts | 11 +++--- src/harness/fourslashImpl.ts | 2 +- src/harness/fourslashInterfaceImpl.ts | 9 ++--- src/server/project.ts | 5 ++- src/server/protocol.ts | 9 +++-- src/server/session.ts | 11 +++++- src/services/codefixes/importFixes.ts | 4 +- src/services/postPasteImportFixes.ts | 39 +++++++++++-------- src/services/services.ts | 15 +++++-- src/services/types.ts | 6 +-- .../tsserver/postPasteImportFixes.ts | 2 +- tests/cases/fourslash/fourslash.ts | 8 +--- .../postPasteImportFixes_existingImports1.ts | 6 +-- .../postPasteImportFixes_existingImports2.ts | 11 ++---- .../postPasteImportFixes_knownSourceFile.ts | 11 +++--- .../postPasteImportFixes_multiplePastes1.ts | 11 +----- .../postPasteImportFixes_multiplePastes2.ts | 18 +++------ .../postPasteImportFixes_pasteComments.ts | 6 +-- .../postPasteImportFixes_unknownSourceFile.ts | 4 +- 19 files changed, 93 insertions(+), 95 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 1e022eb7be7f6..90ba9dbf76459 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1,6 +1,5 @@ import { ApplicableRefactorInfo, - arrayFrom, CallHierarchyIncomingCall, CallHierarchyItem, CallHierarchyOutgoingCall, @@ -1013,15 +1012,15 @@ export class SessionClient implements LanguageService { getPostPasteImportFixes( targetFile: string, - pastes: { text: string; range: TextRange; }[], + copies: { text: string; copyRange?: { file: string; range: TextRange;} }[], + pastes: TextRange[], _preferences: UserPreferences, - _formatOptions: FormatCodeSettings, - copySpan?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, + _formatOptions: FormatCodeSettings ): PostPasteImportFixes { const args: protocol.GetPostPasteImportFixesRequestArgs = { file: targetFile, - pastes: arrayFrom(pastes.map(paste => ({ text: paste.text, range: { start: this.positionToOneBasedLineOffset(targetFile, paste.range.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.range.end) } }))), - copySpan, + copies: copies.map(copy => ({ text: copy.text, range: copy.copyRange ? { file: copy.copyRange.file, start: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.pos), end: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.end) } : undefined })), + pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end) })), }; const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index f6c6aaa316ad5..ea10010e21971 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3563,7 +3563,7 @@ export class TestState { } public verifyPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void { - const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.pastes, options.preferences, this.formatCodeSettings, options.copySpan); + const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.copies, options.pastes, options.preferences, this.formatCodeSettings); this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index b6a7e5b76ead4..744c1cbdb4b3c 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1,6 +1,3 @@ -import { - Location, -} from "../server/protocol"; import * as FourSlash from "./_namespaces/FourSlash"; import * as ts from "./_namespaces/ts"; @@ -1889,8 +1886,8 @@ export interface VerifyCodeFixAllOptions { export interface VerifyPostPasteImportFix { targetFile: string; pastes: { text: string; range: ts.TextRange; }[]; + copySpan?: { file: string; range: ts.TextRange; }; preferences: ts.UserPreferences; - copySpan?: { file: string; start: Location; end: Location; }; } export interface VerifyRefactorOptions { @@ -1935,9 +1932,9 @@ export interface MoveToFileOptions { export interface PostPasteImportFixOptions { readonly newFileContents: { readonly [fileName: string]: string; }; - readonly pastes: { text: string; range: ts.TextRange; }[]; + readonly copies: { text: string; copyRange?: { file: string; range: ts.TextRange;} }[], + readonly pastes: ts.TextRange[], readonly preferences: ts.UserPreferences; - readonly copySpan?: { file: string; start: Location; end: Location; }; } export type RenameLocationsOptions = readonly RenameLocationOptions[] | { diff --git a/src/server/project.ts b/src/server/project.ts index 555bbdb9091e2..c3a4ae7616cbf 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2216,9 +2216,10 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - updateTargetFile(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: ts.Program | undefined; } { + runWithTemporaryFileUpdate(rootFile: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: ts.Program | undefined; } { const originalProgram = this.program; - this.getScriptInfo(rootFile)?.editContent(0, targetFileText.length, pastedText); + Debug.assert(this.program && this.program.getSourceFile(rootFile)); + this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, pastedText); this.updateGraph(); return { updatedFile: (this.program?.getSourceFile(rootFile)), updatedProgram: this.program, originalProgram }; } diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 7f6fee9920b13..76967b4fc6ac1 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -641,9 +641,12 @@ export interface GetPostPasteImportFixesRequest extends Request { } export type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { - pastes: { text: string; range: TextSpan; }[]; - copySpan?: FileSpan; -}; + copies: { + text: string; + range?: FileSpan; + }[]; + pastes: TextSpan[]; + }; export interface GetPostPasteImportFixesResponse extends Response { body: PostPasteImportAction; } diff --git a/src/server/session.ts b/src/server/session.ts index a9b5f1196d519..e0e151958a2d0 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2799,8 +2799,15 @@ export class Session implements EventSender { private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - const pastes = arrayFrom(args.pastes).map(paste => ({ text: paste.text, range: this.getRange({ file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset }, project.getScriptInfoForNormalizedPath(file)!) })); - const result = project.getLanguageService().getPostPasteImportFixes(file, pastes, this.getPreferences(file), this.getFormatOptions(file), args.copySpan); + //const pastes = args.pastes.map(paste => ({ text: paste.text, range: this.getRange({ file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset }, project.getScriptInfoForNormalizedPath(file)!) })); + //const pastes = args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)); + const copyFile = args.copies[0].range ? args.copies[0].range.file : undefined; + const result = project.getLanguageService().getPostPasteImportFixes( + file, + args.copies.map(copy => ({ text: copy.text, copyRange: copy.range && copyFile ? { file: copy.range.file, range: this.getRange({ file: copyFile, startLine: copy.range.start.line, startOffset: copy.range.start.offset, endLine: copy.range.end.line, endOffset: copy.range.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!) }: undefined })), + args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), + this.getPreferences(file), + this.getFormatOptions(file)); if (result === undefined) { return undefined; } diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 98de7dac81d99..9980d418fa7a1 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -210,8 +210,8 @@ export interface ImportAdder { hasFixes(): boolean; addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void; addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) => void; + addImportForUnresolvedIdentifier: (context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) => void; writeFixes: (changeTracker: textChanges.ChangeTracker, oldFileQuotePreference?: QuotePreference) => void; - addImportsForUnknownSymbols: (context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) => void; } /** @internal */ @@ -236,7 +236,7 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu type NewImportsKey = `${0 | 1}|${string}`; /** Use `getNewImportEntry` for access */ const newImports = new Map>(); - return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes, addImportsForUnknownSymbols }; + return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes, addImportForUnresolvedIdentifier: addImportsForUnknownSymbols }; function addImportsForUnknownSymbols(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) { const info = getFixInfosWithoutDiagnostic(context, symbolToken, useAutoImportProvider); diff --git a/src/services/postPasteImportFixes.ts b/src/services/postPasteImportFixes.ts index 220369ae1cc8c..0030b727d94de 100644 --- a/src/services/postPasteImportFixes.ts +++ b/src/services/postPasteImportFixes.ts @@ -16,6 +16,7 @@ import { UserPreferences, } from "../compiler/types"; import { + getLineOfLocalPosition, hasSyntacticModifier, skipAlias, } from "../compiler/utilities"; @@ -55,44 +56,47 @@ import { /** @internal */ export function postPasteImportFixesProvider( targetFile: SourceFile, + //pastes: { text: string; range: TextRange; }[], + copies: { text: string; copyRange?: { file: SourceFile; range: TextRange;} }[], + pastes: TextRange[], host: LanguageServiceHost, - pastes: { text: string; range: TextRange; }[], preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, - originalFile?: SourceFile, - copyLocation?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, + //originalFile?: SourceFile, + //copyLocation?: { file: string; range: TextRange; }, ): PostPasteImportFixes { - const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, host, pastes, preferences, formatContext, cancellationToken, changeTracker, originalFile, copyLocation)); - + const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, copies, pastes, host, preferences, formatContext, cancellationToken, changeTracker)); return { edits: changes }; } function postPasteFixes( targetFile: SourceFile, + copies: { text: string; copyRange?: { file: SourceFile; range: TextRange;} }[], + pastes: TextRange[], host: LanguageServiceHost, - pastes: { text: string; range: TextRange; }[], preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, changes: textChanges.ChangeTracker, - originalFile?: SourceFile, - copyLocation?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, ) { - const updatedTargetFile = host.updateTargetFile?.(targetFile.fileName, targetFile.getText(), targetFile.getText().slice(0, pastes[0].range.pos) + pastes[0].text + targetFile.getText().slice(pastes[0].range.end)); + const copy = copies[0]; + const updatedTargetFile = host.runWithTemporaryFileUpdate?.(targetFile.fileName, targetFile.getText().slice(0, pastes[0].pos) + copy.text + targetFile.getText().slice(pastes[0].end)); const statements: Statement[] = []; Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); - if (originalFile) { - addRange(statements, originalFile.statements, copyLocation?.start.line, copyLocation ? copyLocation.end.line + 1 : undefined); - const usage = getUsageInfo(originalFile, statements, updatedTargetFile.originalProgram.getTypeChecker(), getExistingLocals(updatedTargetFile.updatedFile, statements, updatedTargetFile.originalProgram.getTypeChecker())); + if (copy.copyRange) { + const _start = getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos); + const _end = getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end); + addRange(statements, copy.copyRange.file.statements, getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos), getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end) + 1); + const usage = getUsageInfo(copy.copyRange.file, statements, updatedTargetFile.originalProgram.getTypeChecker(), getExistingLocals(updatedTargetFile.updatedFile, statements, updatedTargetFile.originalProgram.getTypeChecker())); const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); - const imports = getImportsFromKnownOriginalFile(originalFile, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); + const imports = getImportsFromKnownOriginalFile(copy.copyRange.file, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); if (imports.length > 0) { insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } - importAdder.writeFixes(changes, getQuotePreference(originalFile, preferences)); + importAdder.writeFixes(changes, getQuotePreference(copy.copyRange.file, preferences)); host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } else { @@ -109,7 +113,7 @@ function postPasteFixes( if (isIdentifier(node)) { if (!updatedTargetFile.originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { // generate imports - importAdder.addImportsForUnknownSymbols(context, node, /*useAutoImportProvider*/ true); + importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true); } } else { @@ -119,8 +123,9 @@ function postPasteFixes( importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); } - pastes.forEach(({ text, range }) => { - range.pos === range.end ? changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text) : changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text); + pastes.forEach((paste) => { + changes.replaceRangeWithText(targetFile, { pos: paste.pos, end: paste.end }, copy.text); + //range.pos === range.end ? changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text) : changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text); }); } diff --git a/src/services/services.ts b/src/services/services.ts index 876ea3bc496b1..526caf59ebd85 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2093,14 +2093,21 @@ export function createLanguageService( function getPostPasteImportFixes( targetFile: string, - pastes: { text: string; range: TextRange; }[], + // pastes: { text: string; range: TextRange; }[], + // copySpan: { file: string; range: TextRange; } | undefined, + copies: { text: string; copyRange?: { file: string; range: TextRange;} }[], + pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - copySpan?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, ): PostPasteImportFixes { synchronizeHostData(); - const originalSourceFile = copySpan ? getValidSourceFile(copySpan.file) : undefined; - return postPasteImportFixes.postPasteImportFixesProvider(getValidSourceFile(targetFile), host, pastes, preferences, formatting.getFormatContext(formatOptions, host), cancellationToken, originalSourceFile, copySpan); + return postPasteImportFixes.postPasteImportFixesProvider( + getValidSourceFile(targetFile), + copies.map(({ text, copyRange }) => ({ text, copyRange: copyRange ? { file: getValidSourceFile(copyRange.file), range: copyRange.range } : undefined })), + pastes, + host, + preferences, + formatting.getFormatContext(formatOptions, host), cancellationToken); } function getNodeForQuickInfo(node: Node): Node { diff --git a/src/services/types.ts b/src/services/types.ts index 8276d39fca5fd..21af24777c4ad 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -431,7 +431,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ updateTargetFile?(rootFile: string, targetFileText: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: Program | undefined; }; + /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: Program | undefined; }; /** @internal */ revertUpdatedFile?(rootFile: string, updatedText: string, originalText: string): void; jsDocParsingMode?: JSDocParsingMode | undefined; } @@ -687,10 +687,10 @@ export interface LanguageService { dispose(): void; getPostPasteImportFixes( targetFile: string, - pastes: { text: string; range: TextRange; }[], + copies: { text: string; range?: { file: string; range: TextRange;} }[], + pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - copySpan?: { file: string; start: { line: number; offset: number; }; end: { line: number; offset: number; }; }, ): PostPasteImportFixes; } diff --git a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts index 6935f487b4d37..765792936db5b 100644 --- a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts +++ b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts @@ -35,7 +35,7 @@ const c = 3;`; const originalProgram = session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getProgram(); const hostProject = session.getProjectService().configuredProjects.get(tsconfig.path)!; - const updatedContent = hostProject.updateTargetFile(target.path, target.content, pastedText); + const updatedContent = hostProject.runWithTemporaryFileUpdate(target.path, pastedText); if (updatedContent.updatedFile !== undefined) { hostProject.revertUpdatedFile(target.path, updatedContent.updatedFile.getText(), originalContent); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index e73659845bd61..539e1c15659fd 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -212,10 +212,6 @@ declare namespace FourSlashInterface { start: number; end: number; } - interface Location { - line: number; - offset: number; - } class test_ { markers(): Marker[]; markerNames(): string[]; @@ -450,8 +446,8 @@ declare namespace FourSlashInterface { uncommentSelection(newFileContent: string): void; postPasteImportFixes(options: { newFileContents: { readonly [fileName: string]: string }; - pastes: Array<{ text: string; range: { pos: number, end: number }}>; - copySpan?: { file: string, start: Location, end: Location }, + copies: { text: string; copyRange?: { file: string; range: { pos: number, end: number };} }[], + pastes: { pos: number, end: number }[], }): void; } class edit { diff --git a/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts b/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts index 82aeef5f7d998..552829ebe6ae3 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts @@ -22,10 +22,8 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ - text: `const m = t3 + t2 + 1;`, - range: range[0], - }], + copies: [{ text: `const m = t3 + t2 + 1;`}], + pastes: [{ pos: range[0].pos, end: range[0].end }], newFileContents: { "/target.ts": `import { t } from "./other"; diff --git a/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts b/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts index 3ad98da93f4cb..6b991fbdc6904 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts @@ -20,7 +20,7 @@ //// import { t2 } from "./other2"; //// import { t3 } from "./other3"; //// export const n = 10; -//// export const m = t3 + t2 + n; +//// [|export const m = t3 + t2 + n;|] // @Filename: /tsconfig.json ////{ "files": ["target.ts", "originalFile.ts", "other.ts", "other2.ts", "other3.ts"] } @@ -28,10 +28,8 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ - text: `const m = t3 + t2 + n;`, - range: range[0], - }], + copies: [{ text: `const m = t3 + t2 + n;`, copyRange: { file: "originalFile.ts", range: range[1]}}], + pastes: [range[0]], newFileContents: { "/target.ts": `import { n } from "./originalFile"; @@ -41,6 +39,5 @@ import { t3 } from "./other3"; const a = t + 1; const m = t3 + t2 + n; const c = 10;` - }, - copySpan: { file: "originalFile.ts", start: { line : 3, offset: 0}, end : { line: 3, offset: 30}}, + } }); diff --git a/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts b/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts index 97722efb4ea37..a7135d64e53ac 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts @@ -11,21 +11,22 @@ // @Filename: /file2.ts ////import { b } from './file1'; ////const a = 1; -////const c = a + b; -////const t = 9; +////[|const c = a + b; +////const t = 9;|] // @Filename: /tsconfig.json ////{ "files": ["file1.ts", "file2.ts", "target.ts"] } const range = test.ranges(); +const t = range[0]; format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ + copies: [{ text: `const c = a + b; const t = 9;`, - range: range[0], + copyRange: { file: "file2.ts", range: range[1]} }], - copySpan: { file:"file2.ts", start: { line : 2, offset: 0}, end : { line: 3, offset: 0}}, + pastes: [range[0]], newFileContents: { "/file2.ts": `import { b } from './file1'; diff --git a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts index bef58f87b1899..ff1c5bf8e5d92 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts @@ -22,19 +22,12 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ + copies: [{ text: `const g = p + q; function e(); const f = r + s;`, - range: range[0], - }, - { - text: `const g = p + q; -function e(); -const f = r + s;`, - range: range[1], - }], + pastes: [range[0], range[1]], newFileContents: { "/target.ts": `import { p, q } from "./file1"; diff --git a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts index 93ea4de93e5bf..b7838b907fc80 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts @@ -11,8 +11,8 @@ //// import { aa, bb } from "./other"; //// export const r = 10; //// export const s = 12; -//// export const t = aa + bb + r + s; -//// const u = 1; +//// [|export const t = aa + bb + r + s; +//// const u = 1;|] // @Filename: /other.ts //// export const aa = 1; @@ -24,17 +24,12 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ + copies: [{ text: `export const t = aa + bb + r + s; const u = 1;`, - range: range[0], - }, - { - text: `export const t = aa + bb + r + s; -const u = 1;`, - range: range[1], - + copyRange: { file: "file1.ts", range: range[2]} }], + pastes: [range[0], range[1]], newFileContents: { "/target.ts": `import { r, s } from "./file1"; @@ -48,6 +43,5 @@ const c = 3; export const t = aa + bb + r + s; const u = 1; const d = 4;` - }, - copySpan: { file: "file1.ts", start: { line : 3, offset: 0}, end : { line: 4, offset: 12}}, + }, }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts b/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts index 60c272e5d9447..71c80fb71acb7 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts @@ -11,15 +11,15 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ + copies: [{ text: `/** * Testing comment line 1 * line 2 * line 3 * line 4 -*/`, - range: range[0], +*/` }], + pastes: [range[0]], newFileContents: { "/target.ts": `const a = 10; diff --git a/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts b/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts index 009d847fdca3c..0da558ec4c045 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts +++ b/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts @@ -17,15 +17,15 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.postPasteImportFixes({ - pastes: [{ + copies: [{ text: `interface Testing { test1: Test1; test2: Test2; test3: Test3; test4: Test4; }`, - range: range[0], }], + pastes: [range[0]], newFileContents: { "/file2.ts": `import { Test1, Test2, Test3, Test4 } from "./file1"; From 3914539cc23cf648250383bd2ca510290347592a Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 20 Feb 2024 12:52:48 -0800 Subject: [PATCH 14/41] changes based on review 2 --- src/harness/client.ts | 2 +- src/server/project.ts | 14 +- src/server/session.ts | 5 +- src/services/postPasteImportFixes.ts | 160 ++++-------------- src/services/refactors/moveToFile.ts | 92 +--------- src/services/services.ts | 2 - src/services/types.ts | 3 +- src/services/utilities.ts | 95 +++++++++++ .../tsserver/postPasteImportFixes.ts | 12 +- 9 files changed, 145 insertions(+), 240 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 90ba9dbf76459..142e3871f9899 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1020,7 +1020,7 @@ export class SessionClient implements LanguageService { const args: protocol.GetPostPasteImportFixesRequestArgs = { file: targetFile, copies: copies.map(copy => ({ text: copy.text, range: copy.copyRange ? { file: copy.copyRange.file, start: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.pos), end: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.end) } : undefined })), - pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end) })), + pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end)})), }; const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); diff --git a/src/server/project.ts b/src/server/project.ts index c3a4ae7616cbf..7838357e8bb78 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2216,17 +2216,15 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - runWithTemporaryFileUpdate(rootFile: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: ts.Program | undefined; } { + runWithTemporaryFileUpdate(rootFile: string, pastedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedFile: SourceFile) => void) { const originalProgram = this.program; - Debug.assert(this.program && this.program.getSourceFile(rootFile)); + const originalText = this.program?.getSourceFile(rootFile)?.getText(); + Debug.assert(this.program && this.program.getSourceFile(rootFile) && originalText); + this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, pastedText); this.updateGraph(); - return { updatedFile: (this.program?.getSourceFile(rootFile)), updatedProgram: this.program, originalProgram }; - } - - /** @internal */ - revertUpdatedFile(rootFile: string, updatedText: string, originalText: string) { - this.getScriptInfo(rootFile)?.editContent(0, updatedText.length, originalText); + cb(this.program, originalProgram, (this.program?.getSourceFile(rootFile))!); + this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, originalText); this.updateGraph(); } diff --git a/src/server/session.ts b/src/server/session.ts index e0e151958a2d0..33cd757296493 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2799,12 +2799,11 @@ export class Session implements EventSender { private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { const { file, project } = this.getFileAndProject(args); - //const pastes = args.pastes.map(paste => ({ text: paste.text, range: this.getRange({ file, startLine: paste.range.start.line, startOffset: paste.range.start.offset, endLine: paste.range.end.line, endOffset: paste.range.end.offset }, project.getScriptInfoForNormalizedPath(file)!) })); - //const pastes = args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)); const copyFile = args.copies[0].range ? args.copies[0].range.file : undefined; const result = project.getLanguageService().getPostPasteImportFixes( file, - args.copies.map(copy => ({ text: copy.text, copyRange: copy.range && copyFile ? { file: copy.range.file, range: this.getRange({ file: copyFile, startLine: copy.range.start.line, startOffset: copy.range.start.offset, endLine: copy.range.end.line, endOffset: copy.range.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!) }: undefined })), + args.copies.map(copy => ({ text: copy.text, copyRange: copy.range && copyFile + ? { file: copy.range.file, range: this.getRange({ file: copyFile, startLine: copy.range.start.line, startOffset: copy.range.start.offset, endLine: copy.range.end.line, endOffset: copy.range.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!) }: undefined })), args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), this.getPreferences(file), this.getFormatOptions(file)); diff --git a/src/services/postPasteImportFixes.ts b/src/services/postPasteImportFixes.ts index 0030b727d94de..c2d8ffaf3ba92 100644 --- a/src/services/postPasteImportFixes.ts +++ b/src/services/postPasteImportFixes.ts @@ -1,50 +1,31 @@ import { addRange, - append, } from "../compiler/core"; import { - AnyImportOrRequireStatement, CancellationToken, - Identifier, - ModifierFlags, - Program, SourceFile, Statement, SymbolFlags, TextRange, - TypeChecker, UserPreferences, } from "../compiler/types"; import { getLineOfLocalPosition, - hasSyntacticModifier, - skipAlias, } from "../compiler/utilities"; import { codefix, - Debug, - factory, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, + getTargetFileImportsAndAddExportInOldFile, insertImports, isIdentifier, - nodeSeenTracker, - Symbol, textChanges, } from "./_namespaces/ts"; import { - addExportToChanges, - filterImport, - forEachImportInStatement, getExistingLocals, - getTopLevelDeclarationStatement, getUsageInfo, - isTopLevelDeclaration, - makeImportOrRequire, - moduleSpecifierFromImport, - nameOfTopLevelDeclaration, } from "./refactors/moveToFile"; import { CodeFixContextBase, @@ -56,15 +37,12 @@ import { /** @internal */ export function postPasteImportFixesProvider( targetFile: SourceFile, - //pastes: { text: string; range: TextRange; }[], copies: { text: string; copyRange?: { file: SourceFile; range: TextRange;} }[], pastes: TextRange[], host: LanguageServiceHost, preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, - //originalFile?: SourceFile, - //copyLocation?: { file: string; range: TextRange; }, ): PostPasteImportFixes { const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, copies, pastes, host, preferences, formatContext, cancellationToken, changeTracker)); return { edits: changes }; @@ -81,112 +59,46 @@ function postPasteFixes( changes: textChanges.ChangeTracker, ) { const copy = copies[0]; - const updatedTargetFile = host.runWithTemporaryFileUpdate?.(targetFile.fileName, targetFile.getText().slice(0, pastes[0].pos) + copy.text + targetFile.getText().slice(pastes[0].end)); const statements: Statement[] = []; - Debug.assert(updatedTargetFile && updatedTargetFile.updatedFile && updatedTargetFile.originalProgram && updatedTargetFile.updatedProgram); - - if (copy.copyRange) { - const _start = getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos); - const _end = getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end); - addRange(statements, copy.copyRange.file.statements, getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos), getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end) + 1); - const usage = getUsageInfo(copy.copyRange.file, statements, updatedTargetFile.originalProgram.getTypeChecker(), getExistingLocals(updatedTargetFile.updatedFile, statements, updatedTargetFile.originalProgram.getTypeChecker())); - const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); - - const imports = getImportsFromKnownOriginalFile(copy.copyRange.file, targetFile, updatedTargetFile.updatedProgram, importAdder, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, preferences, host, updatedTargetFile.originalProgram.getTypeChecker()); - if (imports.length > 0) { - insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); - } - importAdder.writeFixes(changes, getQuotePreference(copy.copyRange.file, preferences)); - host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); - } - else { - const context: CodeFixContextBase = { - sourceFile: updatedTargetFile.updatedFile, - program: updatedTargetFile.originalProgram, - cancellationToken, - host, - preferences, - formatContext, - }; - const importAdder = codefix.createImportAdder(updatedTargetFile.updatedFile, updatedTargetFile.updatedProgram, preferences, host); - forEachChild(updatedTargetFile.updatedFile, function cb(node) { - if (isIdentifier(node)) { - if (!updatedTargetFile.originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { - // generate imports - importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true); - } - } - else { - node.forEachChild(cb); - } - }); - importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); - host.revertUpdatedFile?.(targetFile.fileName, updatedTargetFile.updatedFile.text, targetFile.text); - } - pastes.forEach((paste) => { - changes.replaceRangeWithText(targetFile, { pos: paste.pos, end: paste.end }, copy.text); - //range.pos === range.end ? changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text) : changes.replaceRangeWithText(targetFile, { pos: range.pos, end: range.end }, text); - }); -} - -function getImportsFromKnownOriginalFile( - originalFile: SourceFile, - targetFile: SourceFile, - program: Program, - importAdder: codefix.ImportAdder, - importsToCopy: Map, - targetFileImportsFromOldFile: Set, - changes: textChanges.ChangeTracker, - preferences: UserPreferences, - host: LanguageServiceHost, - checker: TypeChecker, -) { - const copiedOldImports: AnyImportOrRequireStatement[] = []; - importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { - try { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); - } - catch { - for (const oldStatement of originalFile.statements) { - forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - }); + + host.runWithTemporaryFileUpdate?.(targetFile.fileName, targetFile.getText().slice(0, pastes[0].pos) + copy.text + targetFile.getText().slice(pastes[0].end), (updatedProgram, originalProgram, updatedFile) => { + if (copy.copyRange) { + addRange(statements, copy.copyRange.file.statements, getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos), getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end) + 1); + const usage = getUsageInfo(copy.copyRange.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); + const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); + + const imports = getTargetFileImportsAndAddExportInOldFile(copy.copyRange.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, + originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copy.copyRange.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); + if (imports.length > 0) { + insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } + importAdder.writeFixes(changes, getQuotePreference(copy.copyRange.file, preferences)); } - }); - - const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, program, host, !!originalFile.commonJsModuleIndicator); - const quotePreference = getQuotePreference(targetFile, preferences); - // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. - let oldFileDefault: Identifier | undefined; - const oldFileNamedImports: string[] = []; - const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. - targetFileImportsFromOldFile.forEach(symbol => { - if (!symbol.declarations) { - return; - } - for (const decl of symbol.declarations) { - if (!isTopLevelDeclaration(decl)) continue; - const name = nameOfTopLevelDeclaration(decl); - if (!name) continue; - - const top = getTopLevelDeclarationStatement(decl); - if (markSeenTop(top)) { - addExportToChanges(originalFile, top, name, changes, useEsModuleSyntax); - } - if (importAdder && checker.isUnknownSymbol(symbol)) { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); - } - else { - if (hasSyntacticModifier(decl, ModifierFlags.Default)) { - oldFileDefault = name; + else { + const context: CodeFixContextBase = { + sourceFile: updatedFile, + program: originalProgram!, + cancellationToken, + host, + preferences, + formatContext, + }; + const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); + forEachChild(updatedFile, function cb(node) { + if (isIdentifier(node)) { + if (!originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { + // generate imports + importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true); + } } else { - oldFileNamedImports.push(name.text); + node.forEachChild(cb); } - } + }); + importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); } + }); + pastes.forEach((paste) => { + changes.replaceRangeWithText(targetFile, { pos: paste.pos, end: paste.end }, copy.text); }); - - return append(copiedOldImports, makeImportOrRequire(targetFile, oldFileDefault, oldFileNamedImports, originalFile.fileName, program, host, useEsModuleSyntax, quotePreference)); -} +} \ No newline at end of file diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index c95163d4b71fd..22610c5ed63c6 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -3,7 +3,6 @@ import { } from "../../compiler/moduleSpecifiers"; import { AnyImportOrRequireStatement, - append, ApplicableRefactorInfo, arrayFrom, AssignmentDeclarationKind, @@ -58,6 +57,7 @@ import { getRelativePathFromFile, getSourceFileOfNode, getSynthesizedDeepClone, + getTargetFileImportsAndAddExportInOldFile, getUniqueName, hasJSFileExtension, hasSyntacticModifier, @@ -112,7 +112,6 @@ import { NamedImportBindings, Node, NodeFlags, - nodeSeenTracker, normalizePath, ObjectBindingElementWithoutPropertyName, Program, @@ -272,95 +271,6 @@ function getNewStatementsAndRemoveFromOldFile( ]; } -function getTargetFileImportsAndAddExportInOldFile( - oldFile: SourceFile, - targetFile: string, - importsToCopy: Map, - targetFileImportsFromOldFile: Set, - changes: textChanges.ChangeTracker, - checker: TypeChecker, - program: Program, - host: LanguageServiceHost, - useEsModuleSyntax: boolean, - quotePreference: QuotePreference, - importAdder?: codefix.ImportAdder, -): readonly AnyImportOrRequireStatement[] { - const copiedOldImports: AnyImportOrRequireStatement[] = []; - /** - * Recomputing the imports is preferred with importAdder because it manages multiple import additions for a file and writes then to a ChangeTracker, - * but sometimes it fails because of unresolved imports from files, or when a source file is not available for the target file (in this case when creating a new file). - * So in that case, fall back to copying the import verbatim. - */ - if (importAdder) { - importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { - try { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); - } - catch { - for (const oldStatement of oldFile.statements) { - forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - }); - } - } - }); - } - else { - const targetSourceFile = program.getSourceFile(targetFile); // Would be undefined for a new file - for (const oldStatement of oldFile.statements) { - forEachImportInStatement(oldStatement, i => { - // Recomputing module specifier - const moduleSpecifier = moduleSpecifierFromImport(i); - const compilerOptions = program.getCompilerOptions(); - const resolved = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier); - const fileName = resolved?.resolvedModule?.resolvedFileName; - if (fileName && targetSourceFile) { - const newModuleSpecifier = getModuleSpecifier(compilerOptions, targetSourceFile, targetSourceFile.fileName, fileName, createModuleSpecifierResolutionHost(program, host)); - append(copiedOldImports, filterImport(i, makeStringLiteral(newModuleSpecifier, quotePreference), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - } - else { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - } - }); - } - } - - // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. - const targetFileSourceFile = program.getSourceFile(targetFile); - let oldFileDefault: Identifier | undefined; - const oldFileNamedImports: string[] = []; - const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. - targetFileImportsFromOldFile.forEach(symbol => { - if (!symbol.declarations) { - return; - } - for (const decl of symbol.declarations) { - if (!isTopLevelDeclaration(decl)) continue; - const name = nameOfTopLevelDeclaration(decl); - if (!name) continue; - - const top = getTopLevelDeclarationStatement(decl); - if (markSeenTop(top)) { - addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); - } - if (importAdder && checker.isUnknownSymbol(symbol)) { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); - } - else { - if (hasSyntacticModifier(decl, ModifierFlags.Default)) { - oldFileDefault = name; - } - else { - oldFileNamedImports.push(name.text); - } - } - } - }); - return targetFileSourceFile - ? append(copiedOldImports, makeImportOrRequire(targetFileSourceFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)) - : append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); -} - /** @internal */ export function addNewFileToTsconfig(program: Program, changes: textChanges.ChangeTracker, oldFileName: string, newFileNameWithExtension: string, getCanonicalFileName: GetCanonicalFileName): void { const cfg = program.getCompilerOptions().configFile; diff --git a/src/services/services.ts b/src/services/services.ts index 526caf59ebd85..4e586c61b055e 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2093,8 +2093,6 @@ export function createLanguageService( function getPostPasteImportFixes( targetFile: string, - // pastes: { text: string; range: TextRange; }[], - // copySpan: { file: string; range: TextRange; } | undefined, copies: { text: string; copyRange?: { file: string; range: TextRange;} }[], pastes: TextRange[], preferences: UserPreferences, diff --git a/src/services/types.ts b/src/services/types.ts index 21af24777c4ad..e89d7025322e4 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -431,8 +431,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, pastedText: string): { updatedFile: SourceFile | undefined; updatedProgram: Program | undefined; originalProgram: Program | undefined; }; - /** @internal */ revertUpdatedFile?(rootFile: string, updatedText: string, originalText: string): void; + /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, pastedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void; jsDocParsingMode?: JSDocParsingMode | undefined; } diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 0b2072f449008..508919da251a1 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,9 +1,12 @@ +import { getModuleSpecifier } from "../compiler/_namespaces/ts.moduleSpecifiers"; import { __String, addEmitFlags, addSyntheticLeadingComment, addSyntheticTrailingComment, AnyImportOrRequireStatement, + append, + //append, assertType, AssignmentDeclarationKind, BinaryExpression, @@ -377,6 +380,8 @@ import { walkUpParenthesizedExpressions, YieldExpression, } from "./_namespaces/ts"; +import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./_namespaces/ts.refactor"; +//import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, isTopLevelDeclaration, makeImportOrRequire,moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./refactors/moveToFile"; // These utilities are common to multiple language service features. // #region @@ -4274,3 +4279,93 @@ export function fileShouldUseJavaScriptRequire(file: SourceFile | string, progra } return preferRequire; } + +/** @internal */ +export function getTargetFileImportsAndAddExportInOldFile( + oldFile: SourceFile, + targetFile: string, + importsToCopy: Map, + targetFileImportsFromOldFile: Set, + changes: textChanges.ChangeTracker, + checker: TypeChecker, + program: Program, + host: LanguageServiceHost, + useEsModuleSyntax: boolean, + quotePreference: QuotePreference, + importAdder?: codefix.ImportAdder, +): readonly AnyImportOrRequireStatement[] { + const copiedOldImports: AnyImportOrRequireStatement[] = []; + /** + * Recomputing the imports is preferred with importAdder because it manages multiple import additions for a file and writes then to a ChangeTracker, + * but sometimes it fails because of unresolved imports from files, or when a source file is not available for the target file (in this case when creating a new file). + * So in that case, fall back to copying the import verbatim. + */ + if (importAdder) { + importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { + try { + importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); + } + catch { + for (const oldStatement of oldFile.statements) { + forEachImportInStatement(oldStatement, i => { + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + }); + } + } + }); + } + else { + const targetSourceFile = program.getSourceFile(targetFile); // Would be undefined for a new file + for (const oldStatement of oldFile.statements) { + forEachImportInStatement(oldStatement, i => { + // Recomputing module specifier + const moduleSpecifier = moduleSpecifierFromImport(i); + const compilerOptions = program.getCompilerOptions(); + const resolved = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier); + const fileName = resolved?.resolvedModule?.resolvedFileName; + if (fileName && targetSourceFile) { + const newModuleSpecifier = getModuleSpecifier(compilerOptions, targetSourceFile, targetSourceFile.fileName, fileName, createModuleSpecifierResolutionHost(program, host)); + append(copiedOldImports, filterImport(i, makeStringLiteral(newModuleSpecifier, quotePreference), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + } + else { + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + } + }); + } + } + + // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. + const targetFileSourceFile = program.getSourceFile(targetFile); + let oldFileDefault: Identifier | undefined; + const oldFileNamedImports: string[] = []; + const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. + targetFileImportsFromOldFile.forEach(symbol => { + if (!symbol.declarations) { + return; + } + for (const decl of symbol.declarations) { + if (!isTopLevelDeclaration(decl)) continue; + const name = nameOfTopLevelDeclaration(decl); + if (!name) continue; + + const top = getTopLevelDeclarationStatement(decl); + if (markSeenTop(top)) { + addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); + } + if (importAdder && checker.isUnknownSymbol(symbol)) { + importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); + } + else { + if (hasSyntacticModifier(decl, ModifierFlags.Default)) { + oldFileDefault = name; + } + else { + oldFileNamedImports.push(name.text); + } + } + } + }); + return targetFileSourceFile + ? append(copiedOldImports, makeImportOrRequire(targetFileSourceFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)) + : append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); +} \ No newline at end of file diff --git a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts index 765792936db5b..0d6c504638637 100644 --- a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts +++ b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts @@ -31,16 +31,10 @@ const c = 3;`; const session = new TestSession(host); openFilesForSession([target], session); - const originalContent = target.content; - const originalProgram = session.getProjectService().configuredProjects.get(tsconfig.path)!.getLanguageService().getProgram(); - const hostProject = session.getProjectService().configuredProjects.get(tsconfig.path)!; - const updatedContent = hostProject.runWithTemporaryFileUpdate(target.path, pastedText); - - if (updatedContent.updatedFile !== undefined) { - hostProject.revertUpdatedFile(target.path, updatedContent.updatedFile.getText(), originalContent); - } - assert.strictEqual(hostProject.getCurrentProgram()?.getSourceFileByPath(target.path as ts.Path)?.getText(), originalProgram?.getSourceFileByPath(target.path as ts.Path)?.getText()); + hostProject.runWithTemporaryFileUpdate(target.path, pastedText, (_updatedProgram, _originalProgram, _updatedFile)=>{}); + + assert.strictEqual(hostProject.getCurrentProgram()?.getSourceFileByPath(target.path as ts.Path)?.getText(), target.content); baselineTsserverLogs("getPostPasteImportFixes", "Returns the same file unchanged ", session); }); }); From c6b6f2323ef3cdc864158ee31b72c764c8000f45 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 20 Feb 2024 13:10:25 -0800 Subject: [PATCH 15/41] fixing formatting --- src/harness/client.ts | 6 +++--- src/harness/fourslashInterfaceImpl.ts | 4 ++-- src/server/project.ts | 2 +- src/server/protocol.ts | 6 +++--- src/server/session.ts | 12 ++++++++---- src/services/postPasteImportFixes.ts | 17 ++++++++--------- src/services/services.ts | 10 ++++++---- src/services/types.ts | 2 +- src/services/utilities.ts | 17 ++++++++++++++--- .../unittests/tsserver/postPasteImportFixes.ts | 4 ++-- 10 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 142e3871f9899..a4da1f99ea034 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1012,15 +1012,15 @@ export class SessionClient implements LanguageService { getPostPasteImportFixes( targetFile: string, - copies: { text: string; copyRange?: { file: string; range: TextRange;} }[], + copies: { text: string; copyRange?: { file: string; range: TextRange; }; }[], pastes: TextRange[], _preferences: UserPreferences, - _formatOptions: FormatCodeSettings + _formatOptions: FormatCodeSettings, ): PostPasteImportFixes { const args: protocol.GetPostPasteImportFixesRequestArgs = { file: targetFile, copies: copies.map(copy => ({ text: copy.text, range: copy.copyRange ? { file: copy.copyRange.file, start: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.pos), end: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.end) } : undefined })), - pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end)})), + pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end) })), }; const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); const response = this.processResponse(request); diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 4926fb1c49bd8..93c8b999871a6 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1936,8 +1936,8 @@ export interface MoveToFileOptions { export interface PostPasteImportFixOptions { readonly newFileContents: { readonly [fileName: string]: string; }; - readonly copies: { text: string; copyRange?: { file: string; range: ts.TextRange;} }[], - readonly pastes: ts.TextRange[], + readonly copies: { text: string; copyRange?: { file: string; range: ts.TextRange; }; }[]; + readonly pastes: ts.TextRange[]; readonly preferences: ts.UserPreferences; } diff --git a/src/server/project.ts b/src/server/project.ts index 7838357e8bb78..540dc65140de0 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2220,7 +2220,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo const originalProgram = this.program; const originalText = this.program?.getSourceFile(rootFile)?.getText(); Debug.assert(this.program && this.program.getSourceFile(rootFile) && originalText); - + this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, pastedText); this.updateGraph(); cb(this.program, originalProgram, (this.program?.getSourceFile(rootFile))!); diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 76967b4fc6ac1..de9a4d1e75d7f 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -642,11 +642,11 @@ export interface GetPostPasteImportFixesRequest extends Request { export type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { copies: { - text: string; - range?: FileSpan; + text: string; + range?: FileSpan; }[]; pastes: TextSpan[]; - }; +}; export interface GetPostPasteImportFixesResponse extends Response { body: PostPasteImportAction; } diff --git a/src/server/session.ts b/src/server/session.ts index 33cd757296493..1aa461bb2db54 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2802,11 +2802,15 @@ export class Session implements EventSender { const copyFile = args.copies[0].range ? args.copies[0].range.file : undefined; const result = project.getLanguageService().getPostPasteImportFixes( file, - args.copies.map(copy => ({ text: copy.text, copyRange: copy.range && copyFile - ? { file: copy.range.file, range: this.getRange({ file: copyFile, startLine: copy.range.start.line, startOffset: copy.range.start.offset, endLine: copy.range.end.line, endOffset: copy.range.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!) }: undefined })), - args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), + args.copies.map(copy => ({ + text: copy.text, + copyRange: copy.range && copyFile + ? { file: copy.range.file, range: this.getRange({ file: copyFile, startLine: copy.range.start.line, startOffset: copy.range.start.offset, endLine: copy.range.end.line, endOffset: copy.range.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!) } : undefined, + })), + args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), this.getPreferences(file), - this.getFormatOptions(file)); + this.getFormatOptions(file), + ); if (result === undefined) { return undefined; } diff --git a/src/services/postPasteImportFixes.ts b/src/services/postPasteImportFixes.ts index c2d8ffaf3ba92..029aa78aed44a 100644 --- a/src/services/postPasteImportFixes.ts +++ b/src/services/postPasteImportFixes.ts @@ -37,7 +37,7 @@ import { /** @internal */ export function postPasteImportFixesProvider( targetFile: SourceFile, - copies: { text: string; copyRange?: { file: SourceFile; range: TextRange;} }[], + copies: { text: string; copyRange?: { file: SourceFile; range: TextRange; }; }[], pastes: TextRange[], host: LanguageServiceHost, preferences: UserPreferences, @@ -50,7 +50,7 @@ export function postPasteImportFixesProvider( function postPasteFixes( targetFile: SourceFile, - copies: { text: string; copyRange?: { file: SourceFile; range: TextRange;} }[], + copies: { text: string; copyRange?: { file: SourceFile; range: TextRange; }; }[], pastes: TextRange[], host: LanguageServiceHost, preferences: UserPreferences, @@ -60,15 +60,14 @@ function postPasteFixes( ) { const copy = copies[0]; const statements: Statement[] = []; - + host.runWithTemporaryFileUpdate?.(targetFile.fileName, targetFile.getText().slice(0, pastes[0].pos) + copy.text + targetFile.getText().slice(pastes[0].end), (updatedProgram, originalProgram, updatedFile) => { if (copy.copyRange) { addRange(statements, copy.copyRange.file.statements, getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos), getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end) + 1); const usage = getUsageInfo(copy.copyRange.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); - - const imports = getTargetFileImportsAndAddExportInOldFile(copy.copyRange.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, - originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copy.copyRange.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); + + const imports = getTargetFileImportsAndAddExportInOldFile(copy.copyRange.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copy.copyRange.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); if (imports.length > 0) { insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } @@ -97,8 +96,8 @@ function postPasteFixes( }); importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); } - }); - pastes.forEach((paste) => { + }); + pastes.forEach(paste => { changes.replaceRangeWithText(targetFile, { pos: paste.pos, end: paste.end }, copy.text); }); -} \ No newline at end of file +} diff --git a/src/services/services.ts b/src/services/services.ts index 59904c6820f67..166e2b7c85243 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2095,7 +2095,7 @@ export function createLanguageService( function getPostPasteImportFixes( targetFile: string, - copies: { text: string; copyRange?: { file: string; range: TextRange;} }[], + copies: { text: string; copyRange?: { file: string; range: TextRange; }; }[], pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, @@ -2105,9 +2105,11 @@ export function createLanguageService( getValidSourceFile(targetFile), copies.map(({ text, copyRange }) => ({ text, copyRange: copyRange ? { file: getValidSourceFile(copyRange.file), range: copyRange.range } : undefined })), pastes, - host, - preferences, - formatting.getFormatContext(formatOptions, host), cancellationToken); + host, + preferences, + formatting.getFormatContext(formatOptions, host), + cancellationToken, + ); } function getNodeForQuickInfo(node: Node): Node { diff --git a/src/services/types.ts b/src/services/types.ts index e89d7025322e4..33ed3ede6baca 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -686,7 +686,7 @@ export interface LanguageService { dispose(): void; getPostPasteImportFixes( targetFile: string, - copies: { text: string; range?: { file: string; range: TextRange;} }[], + copies: { text: string; range?: { file: string; range: TextRange; }; }[], pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 67499e0382a1b..e476ceb506cf0 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,4 +1,6 @@ -import { getModuleSpecifier } from "../compiler/_namespaces/ts.moduleSpecifiers"; +import { + getModuleSpecifier, +} from "../compiler/_namespaces/ts.moduleSpecifiers"; import { __String, addEmitFlags, @@ -380,7 +382,16 @@ import { walkUpParenthesizedExpressions, YieldExpression, } from "./_namespaces/ts"; -import { addExportToChanges, filterImport, forEachImportInStatement, getTopLevelDeclarationStatement, isTopLevelDeclaration, makeImportOrRequire, moduleSpecifierFromImport, nameOfTopLevelDeclaration } from "./_namespaces/ts.refactor"; +import { + addExportToChanges, + filterImport, + forEachImportInStatement, + getTopLevelDeclarationStatement, + isTopLevelDeclaration, + makeImportOrRequire, + moduleSpecifierFromImport, + nameOfTopLevelDeclaration, +} from "./_namespaces/ts.refactor"; // These utilities are common to multiple language service features. // #region @@ -4380,4 +4391,4 @@ export function getTargetFileImportsAndAddExportInOldFile( return targetFileSourceFile ? append(copiedOldImports, makeImportOrRequire(targetFileSourceFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)) : append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); -} \ No newline at end of file +} diff --git a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts index 0d6c504638637..90c0c4c3bc954 100644 --- a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts +++ b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts @@ -32,8 +32,8 @@ const c = 3;`; openFilesForSession([target], session); const hostProject = session.getProjectService().configuredProjects.get(tsconfig.path)!; - hostProject.runWithTemporaryFileUpdate(target.path, pastedText, (_updatedProgram, _originalProgram, _updatedFile)=>{}); - + hostProject.runWithTemporaryFileUpdate(target.path, pastedText, (_updatedProgram, _originalProgram, _updatedFile) => {}); + assert.strictEqual(hostProject.getCurrentProgram()?.getSourceFileByPath(target.path as ts.Path)?.getText(), target.content); baselineTsserverLogs("getPostPasteImportFixes", "Returns the same file unchanged ", session); }); From c8c3e295549bbbcf2b4aace8189a45afb082c89e Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 20 Feb 2024 13:42:29 -0800 Subject: [PATCH 16/41] baseline changes --- .../postPasteImportFixes_existingImports1.js | 22 +++++---- .../postPasteImportFixes_existingImports2.js | 26 +++++----- .../postPasteImportFixes_knownSourceFile.js | 30 ++++++------ .../postPasteImportFixes_multiplePastes1.js | 39 +++++++-------- .../postPasteImportFixes_multiplePastes2.js | 49 +++++++++---------- .../postPasteImportFixes_pasteComments.js | 22 +++++---- .../postPasteImportFixes_unknownSourceFile.js | 22 +++++---- 7 files changed, 109 insertions(+), 101 deletions(-) diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js index b1045e92c98af..c3fd7c5c37059 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js @@ -226,18 +226,20 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", + "copies": [ + { + "text": "const m = t3 + t2 + 1;" + } + ], "pastes": [ { - "text": "const m = t3 + t2 + 1;", - "range": { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 14 - } + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 } } ] diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js index a821cde26a378..83a2be3d8686b 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js @@ -245,32 +245,34 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "pastes": [ + "copies": [ { "text": "const m = t3 + t2 + n;", "range": { + "file": "originalFile.ts", "start": { "line": 4, "offset": 1 }, "end": { "line": 4, - "offset": 14 + "offset": 30 } } } ], - "copySpan": { - "file": "originalFile.ts", - "start": { - "line": 3, - "offset": 0 - }, - "end": { - "line": 3, - "offset": 30 + "pastes": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + } } - } + ] }, "command": "getPostPasteImportFixes" } diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js index 5bc51ef0860f4..ab094df47d509 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js @@ -212,32 +212,34 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "pastes": [ + "copies": [ { "text": "const c = a + b;\nconst t = 9;", "range": { + "file": "file2.ts", "start": { - "line": 2, + "line": 3, "offset": 1 }, "end": { - "line": 2, - "offset": 14 + "line": 4, + "offset": 13 } } } ], - "copySpan": { - "file": "file2.ts", - "start": { - "line": 2, - "offset": 0 - }, - "end": { - "line": 3, - "offset": 0 + "pastes": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + } } - } + ] }, "command": "getPostPasteImportFixes" } diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js index ab8f2527e700b..441bd1d77d1be 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js @@ -213,31 +213,30 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", + "copies": [ + { + "text": "const g = p + q;\nfunction e();\nconst f = r + s;" + } + ], "pastes": [ { - "text": "const g = p + q;\nfunction e();\nconst f = r + s;", - "range": { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - } + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 } }, { - "text": "const g = p + q;\nfunction e();\nconst f = r + s;", - "range": { - "start": { - "line": 5, - "offset": 1 - }, - "end": { - "line": 5, - "offset": 1 - } + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 } } ] diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js index 56cfa5f0d74a3..45ed3072ffe8e 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js @@ -216,45 +216,44 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "pastes": [ - { - "text": "export const t = aa + bb + r + s;\nconst u = 1;", - "range": { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 13 - } - } - }, + "copies": [ { "text": "export const t = aa + bb + r + s;\nconst u = 1;", "range": { + "file": "file1.ts", "start": { "line": 4, "offset": 1 }, "end": { - "line": 4, - "offset": 1 + "line": 5, + "offset": 13 } } } ], - "copySpan": { - "file": "file1.ts", - "start": { - "line": 3, - "offset": 0 + "pastes": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 13 + } }, - "end": { - "line": 4, - "offset": 12 + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 1 + } } - } + ] }, "command": "getPostPasteImportFixes" } diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js index 6bca87a4addb3..e4edb335e213e 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js @@ -180,18 +180,20 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", + "copies": [ + { + "text": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" + } + ], "pastes": [ { - "text": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/", - "range": { - "start": { - "line": 2, - "offset": 14 - }, - "end": { - "line": 2, - "offset": 14 - } + "start": { + "line": 2, + "offset": 14 + }, + "end": { + "line": 2, + "offset": 14 } } ] diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js index 596ea7611195c..2a8374ac6ce0a 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js @@ -197,18 +197,20 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/file2.ts", + "copies": [ + { + "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" + } + ], "pastes": [ { - "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }", - "range": { - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 1 - } + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 } } ] From 5192ff29cff758f360f8ed264b5b1914b603802d Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 20 Feb 2024 15:19:47 -0800 Subject: [PATCH 17/41] accepting baselines --- tests/baselines/reference/api/typescript.d.ts | 25 +++++++------------ 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 7bbb6029440df..dbcb4cf3d7f28 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -554,11 +554,11 @@ declare namespace ts { arguments: GetPostPasteImportFixesRequestArgs; } type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { - pastes: { + copies: { text: string; - range: TextSpan; + range?: FileSpan; }[]; - copySpan?: FileSpan; + pastes: TextSpan[]; }; interface GetPostPasteImportFixesResponse extends Response { body: PostPasteImportAction; @@ -10686,23 +10686,16 @@ declare namespace ts { dispose(): void; getPostPasteImportFixes( targetFile: string, - pastes: { + copies: { text: string; - range: TextRange; + range?: { + file: string; + range: TextRange; + }; }[], + pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - copySpan?: { - file: string; - start: { - line: number; - offset: number; - }; - end: { - line: number; - offset: number; - }; - }, ): PostPasteImportFixes; } interface JsxClosingTagInfo { From 215e77854f49eb0e8c1552a4fc35b7dd20a9b7c5 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 22 Feb 2024 13:19:31 -0800 Subject: [PATCH 18/41] Removing updateGraph for reverting the file --- src/server/project.ts | 1 - src/testRunner/tests.ts | 1 - .../tsserver/postPasteImportFixes.ts | 40 - .../postPasteImportFixes_existingImports1.js | 14 +- .../postPasteImportFixes_existingImports2.js | 15 +- .../postPasteImportFixes_knownSourceFile.js | 13 +- .../postPasteImportFixes_multiplePastes1.js | 13 +- .../postPasteImportFixes_multiplePastes2.js | 13 +- .../postPasteImportFixes_pasteComments.js | 11 +- .../postPasteImportFixes_revertUpdatedFile.js | 1244 +++++++++++++++++ .../postPasteImportFixes_unknownSourceFile.js | 12 +- .../postPasteImportFixes_revertUpdatedFile.ts | 37 + 12 files changed, 1288 insertions(+), 126 deletions(-) delete mode 100644 src/testRunner/unittests/tsserver/postPasteImportFixes.ts create mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js create mode 100644 tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts diff --git a/src/server/project.ts b/src/server/project.ts index 540dc65140de0..ff7e5a4a84d1f 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2225,7 +2225,6 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo this.updateGraph(); cb(this.program, originalProgram, (this.program?.getSourceFile(rootFile))!); this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, originalText); - this.updateGraph(); } /** @internal */ diff --git a/src/testRunner/tests.ts b/src/testRunner/tests.ts index 4be8d6dd1d3f8..01d5ddea11d4d 100644 --- a/src/testRunner/tests.ts +++ b/src/testRunner/tests.ts @@ -214,4 +214,3 @@ import "./unittests/debugDeprecation"; import "./unittests/tsserver/inconsistentErrorInEditor"; import "./unittests/tsserver/getMoveToRefactoringFileSuggestions"; import "./unittests/skipJSDocParsing"; -import "./unittests/tsserver/postPasteImportFixes"; diff --git a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts b/src/testRunner/unittests/tsserver/postPasteImportFixes.ts deleted file mode 100644 index 90c0c4c3bc954..0000000000000 --- a/src/testRunner/unittests/tsserver/postPasteImportFixes.ts +++ /dev/null @@ -1,40 +0,0 @@ -import * as ts from "../../_namespaces/ts"; -import { - baselineTsserverLogs, - openFilesForSession, - TestSession, -} from "../helpers/tsserver"; -import { - createServerHost, - File, -} from "../helpers/virtualFileSystemWithWatch"; - -describe("unittests:: tsserver:: postPasteImportFixes", () => { - it("returns the same file unchanged, after updating and reverting changes added to a file", () => { - const target: File = { - path: "/project/a/target.ts", - content: `const a = 1; -const b = 2; -const c = 3;`, - }; - const tsconfig: File = { - path: "/project/tsconfig.json", - content: "{}", - }; - const pastedText = `const a = 1; -function e(); -const f = r + s; -const b = 2; -const c = 3;`; - - const host = createServerHost([target, tsconfig]); - const session = new TestSession(host); - openFilesForSession([target], session); - - const hostProject = session.getProjectService().configuredProjects.get(tsconfig.path)!; - hostProject.runWithTemporaryFileUpdate(target.path, pastedText, (_updatedProgram, _originalProgram, _updatedFile) => {}); - - assert.strictEqual(hostProject.getCurrentProgram()?.getSourceFileByPath(target.path as ts.Path)?.getText(), target.content); - baselineTsserverLogs("getPostPasteImportFixes", "Returns the same file unchanged ", session); - }); -}); diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js index c3fd7c5c37059..8360609c95b49 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js @@ -258,19 +258,6 @@ Info seq [hh:mm:ss:mss] Files (7) /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10;" /other2.ts Text-1 "export const t2 = 1;" -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (7) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-2 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" - /other2.ts Text-1 "export const t2 = 1;" - Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { @@ -319,6 +306,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /lib.d.ts diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js index 83a2be3d8686b..01d324bffe176 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js @@ -292,20 +292,6 @@ Info seq [hh:mm:ss:mss] Files (8) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (8) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-2 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" - /other2.ts Text-1 "export const t2 = 1;" - /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { "seq": 0, @@ -364,6 +350,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /lib.d.ts diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js index ab094df47d509..2ae72b6f0467c 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js @@ -257,18 +257,6 @@ Info seq [hh:mm:ss:mss] Files (6) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export const b = 2;" - /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-1-2 "export const tt = 2;\nfunction f();\nconst p = 1;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { "seq": 0, @@ -343,6 +331,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /file1.ts diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js index 441bd1d77d1be..780462985057d 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js @@ -254,18 +254,6 @@ Info seq [hh:mm:ss:mss] Files (6) /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" - /target.ts SVC-1-2 "const a = 1;\n\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" - /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" - Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { @@ -325,6 +313,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /file1.ts diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js index 45ed3072ffe8e..fa52a13e95f3b 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js @@ -272,18 +272,6 @@ Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" - /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-1-2 "const a = 1;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { "seq": 0, @@ -353,6 +341,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /file1.ts diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js index e4edb335e213e..6304a811cddbc 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js @@ -209,16 +209,6 @@ Info seq [hh:mm:ss:mss] Files (4) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10;" -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (4) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /target.ts SVC-1-2 "const a = 10;\nconst b = 10;\nconst c = 10;" - Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { @@ -256,6 +246,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /lib.d.ts diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js new file mode 100644 index 0000000000000..057b4f3e70df0 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js @@ -0,0 +1,1244 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const t = 1; + +//// [/other2.ts] +export const t2 = 1; + +//// [/target.ts] +import { t } from "./other"; +const a = t + 1; +const b = 10; +type T = number; +var x; +var y = x as + +//// [/tsconfig.json] +{ "files": ["target.ts", "other.ts", "other2.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts", + "/other.ts", + "/other2.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /target.ts SVC-1-0 "import { t } from \"./other\";\nconst a = t + 1;\nconst b = 10;\ntype T = number;\nvar x;\nvar y = x as " + /other2.ts Text-1 "export const t2 = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'target.ts' + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + other2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/other2.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "const m = t2 + 1;" + } + ], + "pastes": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 14 + } + } + ] + }, + "command": "getPostPasteImportFixes" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as " + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPostPasteImportFixes", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { t2 } from \"./other2\";\n" + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 14 + }, + "newText": "const m = t2 + 1;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "preferences": {} + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 3, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/target.ts", + "line": 6, + "offset": 14 + }, + "command": "completionInfo" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /target.ts SVC-1-2 "import { t } from \"./other\";\nconst a = t + 1;\nconst b = 10;\ntype T = number;\nvar x;\nvar y = x as " + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getCompletionData: Get current token: * +Info seq [hh:mm:ss:mss] getCompletionData: Is inside comment: * +Info seq [hh:mm:ss:mss] getCompletionData: Get previous token: * +Info seq [hh:mm:ss:mss] getCompletionsAtPosition: isCompletionListBlocker: * +Info seq [hh:mm:ss:mss] getCompletionData: Semantic work: * +Info seq [hh:mm:ss:mss] getCompletionsAtPosition: getCompletionEntriesFromSymbols: * +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "completionInfo", + "request_seq": 4, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "flags": 0, + "isGlobalCompletion": true, + "isMemberCompletion": false, + "isNewIdentifierLocation": false, + "entries": [ + { + "name": "T", + "kind": "type", + "kindModifiers": "", + "sortText": "11" + }, + { + "name": "any", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBuffer", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferLike", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferTypes", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferView", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayLike", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "asserts", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Awaited", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "bigint", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "boolean", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Boolean", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "BooleanConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "CallableFunction", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Capitalize", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassAccessorDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassAccessorDecoratorResult", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassAccessorDecoratorTarget", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassFieldDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassGetterDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassMemberDecoratorContext", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassMethodDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassSetterDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ConcatArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "const", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "ConstructorParameters", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DataView", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DataViewConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Date", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DateConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DecoratorContext", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DecoratorMetadata", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DecoratorMetadataObject", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Error", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "EvalError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "EvalErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Exclude", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Extract", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "false", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Float32Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Float32ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Float64Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Float64ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Function", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "FunctionConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "globalThis", + "kind": "module", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "IArguments", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportAttributes", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportCallOptions", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportMeta", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "infer", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "InstanceType", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int16Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int16ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int32Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int32ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int8Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int8ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Intl", + "kind": "module", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "JSON", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "keyof", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Lowercase", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Math", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "MethodDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "never", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "NewableFunction", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "NoInfer", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "NonNullable", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "null", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "number", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Number", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "NumberConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "object", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Object", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ObjectConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Omit", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "OmitThisParameter", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ParameterDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Parameters", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Partial", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Pick", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Promise", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PromiseConstructorLike", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PromiseLike", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyDescriptor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyDescriptorMap", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyKey", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RangeError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RangeErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "readonly", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Readonly", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReadonlyArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Record", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReferenceError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReferenceErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExp", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExpConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExpExecArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExpMatchArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Required", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReturnType", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "string", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "String", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "StringConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "symbol", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Symbol", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "SyntaxError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "SyntaxErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "TemplateStringsArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ThisParameterType", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ThisType", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "true", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "TypedPropertyDescriptor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "TypeError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "TypeErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "typeof", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Uint16Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint16ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint32Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint32ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8ClampedArray", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8ClampedArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uncapitalize", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "undefined", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "unique", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "unknown", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Uppercase", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "URIError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "URIErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "void", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "WeakKey", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "WeakKeyTypes", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportAssertions", + "kind": "interface", + "kindModifiers": "deprecated,declare", + "sortText": "z15" + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 + projectProgramVersion: 1 + dirty: false *changed* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js index 2a8374ac6ce0a..ec192f526b399 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js @@ -227,17 +227,6 @@ Info seq [hh:mm:ss:mss] Files (5) /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10;" -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-1-2 "const a = 10;\nconst b = 10;\nconst c = 10;" - Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: { @@ -286,6 +275,7 @@ Projects:: /tsconfig.json (Configured) *changed* projectStateVersion: 3 *changed* projectProgramVersion: 1 + dirty: true *changed* ScriptInfos:: /file1.ts diff --git a/tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts b/tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts new file mode 100644 index 0000000000000..3fb7b2514a1e4 --- /dev/null +++ b/tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts @@ -0,0 +1,37 @@ +/// + +// @Filename: /target.ts +//// import { t } from "./other"; +//// const a = t + 1; +//// [|const b = 10;|] +//// type T = number; +//// var x; +//// var y = x as /*1*/ + +// @Filename: /other.ts +//// export const t = 1; + +// @Filename: /other2.ts +//// export const t2 = 1; + +// @Filename: /tsconfig.json +////{ "files": ["target.ts", "other.ts", "other2.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.postPasteImportFixes({ + copies: [{ text: `const m = t2 + 1;`}], + pastes: [{ pos: range[0].pos, end: range[0].end }], + newFileContents: { + "/target.ts": +`import { t } from "./other"; +import { t2 } from "./other2"; +const a = t + 1; +const m = t2 + 1; +type T = number; +var x; +var y = x as ` + } +}); +verify.completions({ marker: "1", includes: "T" }); + From 1fe2754b4827189847680965671188f25340b9d9 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 4 Mar 2024 13:15:09 -0800 Subject: [PATCH 19/41] changing protocol name --- src/harness/client.ts | 12 +- src/harness/fourslashImpl.ts | 4 +- src/harness/fourslashInterfaceImpl.ts | 8 +- src/server/protocol.ts | 16 +- src/server/session.ts | 14 +- src/services/_namespaces/ts.PasteEdits.ts | 1 + .../_namespaces/ts.postPasteImportFixes.ts | 1 - src/services/_namespaces/ts.ts | 4 +- ...{postPasteImportFixes.ts => pasteEdits.ts} | 10 +- src/services/services.ts | 12 +- src/services/types.ts | 6 +- tests/baselines/reference/api/typescript.d.ts | 26 +- .../pasteEdits_existingImports1.js | 339 +++++ .../pasteEdits_existingImports2.js | 387 +++++ .../pasteEdits_knownSourceFile.js | 360 +++++ .../pasteEdits_multiplePastes1.js | 342 +++++ .../pasteEdits_multiplePastes2.js | 370 +++++ .../pasteEdits_pasteComments.js | 267 ++++ .../pasteEdits_revertUpdatedFile.js | 1244 +++++++++++++++++ .../pasteEdits_unknownSourceFile.js | 300 ++++ .../Returns-the-same-file-unchanged-.js | 214 --- tests/cases/fourslash/fourslash.ts | 2 +- ...rts1.ts => pasteEdits_existingImports1.ts} | 2 +- ...rts2.ts => pasteEdits_existingImports2.ts} | 2 +- ...eFile.ts => pasteEdits_knownSourceFile.ts} | 2 +- ...stes1.ts => pasteEdits_multiplePastes1.ts} | 2 +- ...stes2.ts => pasteEdits_multiplePastes2.ts} | 2 +- ...omments.ts => pasteEdits_pasteComments.ts} | 2 +- ...ile.ts => pasteEdits_revertUpdatedFile.ts} | 2 +- ...ile.ts => pasteEdits_unknownSourceFile.ts} | 2 +- 30 files changed, 3675 insertions(+), 280 deletions(-) create mode 100644 src/services/_namespaces/ts.PasteEdits.ts delete mode 100644 src/services/_namespaces/ts.postPasteImportFixes.ts rename src/services/{postPasteImportFixes.ts => pasteEdits.ts} (91%) create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js delete mode 100644 tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js rename tests/cases/fourslash/server/{postPasteImportFixes_existingImports1.ts => pasteEdits_existingImports1.ts} (92%) rename tests/cases/fourslash/server/{postPasteImportFixes_existingImports2.ts => pasteEdits_existingImports2.ts} (93%) rename tests/cases/fourslash/server/{postPasteImportFixes_knownSourceFile.ts => pasteEdits_knownSourceFile.ts} (92%) rename tests/cases/fourslash/server/{postPasteImportFixes_multiplePastes1.ts => pasteEdits_multiplePastes1.ts} (92%) rename tests/cases/fourslash/server/{postPasteImportFixes_multiplePastes2.ts => pasteEdits_multiplePastes2.ts} (93%) rename tests/cases/fourslash/server/{postPasteImportFixes_pasteComments.ts => pasteEdits_pasteComments.ts} (89%) rename tests/cases/fourslash/server/{postPasteImportFixes_revertUpdatedFile.ts => pasteEdits_revertUpdatedFile.ts} (92%) rename tests/cases/fourslash/server/{postPasteImportFixes_unknownSourceFile.ts => pasteEdits_unknownSourceFile.ts} (92%) diff --git a/src/harness/client.ts b/src/harness/client.ts index a4da1f99ea034..e5547e6fa851a 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -49,8 +49,8 @@ import { notImplemented, OrganizeImportsArgs, OutliningSpan, + PasteEdits, PatternMatchKind, - PostPasteImportFixes, Program, QuickInfo, RefactorEditInfo, @@ -1010,20 +1010,20 @@ export class SessionClient implements LanguageService { return getSupportedCodeFixes(); } - getPostPasteImportFixes( + getPasteEdits( targetFile: string, copies: { text: string; copyRange?: { file: string; range: TextRange; }; }[], pastes: TextRange[], _preferences: UserPreferences, _formatOptions: FormatCodeSettings, - ): PostPasteImportFixes { - const args: protocol.GetPostPasteImportFixesRequestArgs = { + ): PasteEdits { + const args: protocol.GetPasteEditsRequestArgs = { file: targetFile, copies: copies.map(copy => ({ text: copy.text, range: copy.copyRange ? { file: copy.copyRange.file, start: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.pos), end: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.end) } : undefined })), pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end) })), }; - const request = this.processRequest(protocol.CommandTypes.GetPostPasteImportFixes, args); - const response = this.processResponse(request); + const request = this.processRequest(protocol.CommandTypes.GetPasteEdits, args); + const response = this.processResponse(request); if (!response.body) { return { edits: [] }; } diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 77db29c222208..7957cd30e4ccb 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3562,8 +3562,8 @@ export class TestState { assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers); } - public verifyPostPasteImportFixes(options: FourSlashInterface.PostPasteImportFixOptions): void { - const editInfo = this.languageService.getPostPasteImportFixes(this.activeFile.fileName, options.copies, options.pastes, options.preferences, this.formatCodeSettings); + public verifyPasteEdits(options: FourSlashInterface.PasteEditsOptions): void { + const editInfo = this.languageService.getPasteEdits(this.activeFile.fileName, options.copies, options.pastes, options.preferences, this.formatCodeSettings); this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 93c8b999871a6..98849c8fd1055 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -621,8 +621,8 @@ export class Verify extends VerifyNegatable { this.state.verifyOrganizeImports(newContent, mode, preferences); } - public postPasteImportFixes(options: PostPasteImportFixOptions): void { - this.state.verifyPostPasteImportFixes(options); + public pasteEdits(options: PasteEditsOptions): void { + this.state.verifyPasteEdits(options); } } @@ -1887,7 +1887,7 @@ export interface VerifyCodeFixAllOptions { preferences?: ts.UserPreferences; } -export interface VerifyPostPasteImportFix { +export interface VerifyPasteEdits { targetFile: string; pastes: { text: string; range: ts.TextRange; }[]; copySpan?: { file: string; range: ts.TextRange; }; @@ -1934,7 +1934,7 @@ export interface MoveToFileOptions { readonly preferences?: ts.UserPreferences; } -export interface PostPasteImportFixOptions { +export interface PasteEditsOptions { readonly newFileContents: { readonly [fileName: string]: string; }; readonly copies: { text: string; copyRange?: { file: string; range: ts.TextRange; }; }[]; readonly pastes: ts.TextRange[]; diff --git a/src/server/protocol.ts b/src/server/protocol.ts index d5c255d320207..b23e0fe85ca08 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -144,7 +144,7 @@ export const enum CommandTypes { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", - GetPostPasteImportFixes = "getPostPasteImportFixes", + GetPasteEdits = "GetPasteEdits", /** @internal */ GetEditsForRefactorFull = "getEditsForRefactor-full", @@ -635,22 +635,22 @@ export interface GetMoveToRefactoringFileSuggestions extends Response { * Request refactorings at a given position post pasting text from some other location. */ -export interface GetPostPasteImportFixesRequest extends Request { - command: CommandTypes.GetPostPasteImportFixes; - arguments: GetPostPasteImportFixesRequestArgs; +export interface GetPasteEditsRequest extends Request { + command: CommandTypes.GetPasteEdits; + arguments: GetPasteEditsRequestArgs; } -export type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { +export type GetPasteEditsRequestArgs = FileRequestArgs & { copies: { text: string; range?: FileSpan; }[]; pastes: TextSpan[]; }; -export interface GetPostPasteImportFixesResponse extends Response { - body: PostPasteImportAction; +export interface GetPasteEditsResponse extends Response { + body: PasteEditsAction; } -export interface PostPasteImportAction { +export interface PasteEditsAction { edits: FileCodeEdits[]; } diff --git a/src/server/session.ts b/src/server/session.ts index d8b8be9115cf5..b07b3d25642b0 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -101,11 +101,11 @@ import { OperationCanceledException, OrganizeImportsMode, OutliningSpan, + PasteEdits, Path, perfLogger, PerformanceEvent, PossibleProgramFileInfo, - PostPasteImportFixes, Program, QuickInfo, RefactorEditInfo, @@ -2796,10 +2796,10 @@ export class Session implements EventSender { return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); } - private getPostPasteImportFixes(args: protocol.GetPostPasteImportFixesRequestArgs): protocol.PostPasteImportAction | undefined { + private getPasteEdits(args: protocol.GetPasteEditsRequestArgs): protocol.PasteEditsAction | undefined { const { file, project } = this.getFileAndProject(args); const copyFile = args.copies[0].range ? args.copies[0].range.file : undefined; - const result = project.getLanguageService().getPostPasteImportFixes( + const result = project.getLanguageService().getPasteEdits( file, args.copies.map(copy => ({ text: copy.text, @@ -2813,7 +2813,7 @@ export class Session implements EventSender { if (result === undefined) { return undefined; } - return this.mapPostPasteAction(result); + return this.mapPasteEditsAction(result); } private organizeImports(args: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): readonly protocol.FileCodeEdits[] | readonly FileTextChanges[] { @@ -2948,7 +2948,7 @@ export class Session implements EventSender { return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription }; } - private mapPostPasteAction({ edits }: PostPasteImportFixes): protocol.PostPasteImportAction { + private mapPasteEditsAction({ edits }: PasteEdits): protocol.PasteEditsAction { return { edits: this.mapTextChangesToCodeEdits(edits) }; } @@ -3545,8 +3545,8 @@ export class Session implements EventSender { [protocol.CommandTypes.GetMoveToRefactoringFileSuggestions]: (request: protocol.GetMoveToRefactoringFileSuggestionsRequest) => { return this.requiredResponse(this.getMoveToRefactoringFileSuggestions(request.arguments)); }, - [protocol.CommandTypes.GetPostPasteImportFixes]: (request: protocol.GetPostPasteImportFixesRequest) => { - return this.requiredResponse(this.getPostPasteImportFixes(request.arguments)); + [protocol.CommandTypes.GetPasteEdits]: (request: protocol.GetPasteEditsRequest) => { + return this.requiredResponse(this.getPasteEdits(request.arguments)); }, [protocol.CommandTypes.GetEditsForRefactorFull]: (request: protocol.GetEditsForRefactorRequest) => { return this.requiredResponse(this.getEditsForRefactor(request.arguments, /*simplifiedResult*/ false)); diff --git a/src/services/_namespaces/ts.PasteEdits.ts b/src/services/_namespaces/ts.PasteEdits.ts new file mode 100644 index 0000000000000..6765b467d802f --- /dev/null +++ b/src/services/_namespaces/ts.PasteEdits.ts @@ -0,0 +1 @@ +export * from "../pasteEdits"; diff --git a/src/services/_namespaces/ts.postPasteImportFixes.ts b/src/services/_namespaces/ts.postPasteImportFixes.ts deleted file mode 100644 index 0f1f3e8189d63..0000000000000 --- a/src/services/_namespaces/ts.postPasteImportFixes.ts +++ /dev/null @@ -1 +0,0 @@ -export * from "../postPasteImportFixes"; diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts index a0fb6bf9ca8ff..486fdf983ac78 100644 --- a/src/services/_namespaces/ts.ts +++ b/src/services/_namespaces/ts.ts @@ -56,5 +56,5 @@ import * as textChanges from "./ts.textChanges"; export { textChanges }; import * as formatting from "./ts.formatting"; export { formatting }; -import * as postPasteImportFixes from "./ts.postPasteImportFixes"; -export { postPasteImportFixes }; +import * as pasteEdits from "./ts.PasteEdits"; +export { pasteEdits }; diff --git a/src/services/postPasteImportFixes.ts b/src/services/pasteEdits.ts similarity index 91% rename from src/services/postPasteImportFixes.ts rename to src/services/pasteEdits.ts index 029aa78aed44a..bff563a5a07bd 100644 --- a/src/services/postPasteImportFixes.ts +++ b/src/services/pasteEdits.ts @@ -31,11 +31,11 @@ import { CodeFixContextBase, FileTextChanges, LanguageServiceHost, - PostPasteImportFixes, + PasteEdits, } from "./types"; /** @internal */ -export function postPasteImportFixesProvider( +export function pasteEditsProvider( targetFile: SourceFile, copies: { text: string; copyRange?: { file: SourceFile; range: TextRange; }; }[], pastes: TextRange[], @@ -43,12 +43,12 @@ export function postPasteImportFixesProvider( preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, -): PostPasteImportFixes { - const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => postPasteFixes(targetFile, copies, pastes, host, preferences, formatContext, cancellationToken, changeTracker)); +): PasteEdits { + const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => pasteEdits(targetFile, copies, pastes, host, preferences, formatContext, cancellationToken, changeTracker)); return { edits: changes }; } -function postPasteFixes( +function pasteEdits( targetFile: SourceFile, copies: { text: string; copyRange?: { file: SourceFile; range: TextRange; }; }[], pastes: TextRange[], diff --git a/src/services/services.ts b/src/services/services.ts index 166e2b7c85243..1db068a8e1b57 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -238,11 +238,11 @@ import { ParseConfigFileHost, ParsedCommandLine, parseJsonSourceFileConfigFileContent, + PasteEdits, + pasteEdits, Path, positionIsSynthesized, PossibleProgramFileInfo, - PostPasteImportFixes, - postPasteImportFixes, PragmaMap, PrivateIdentifier, Program, @@ -2093,15 +2093,15 @@ export function createLanguageService( }; } - function getPostPasteImportFixes( + function getPasteEdits( targetFile: string, copies: { text: string; copyRange?: { file: string; range: TextRange; }; }[], pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - ): PostPasteImportFixes { + ): PasteEdits { synchronizeHostData(); - return postPasteImportFixes.postPasteImportFixesProvider( + return pasteEdits.pasteEditsProvider( getValidSourceFile(targetFile), copies.map(({ text, copyRange }) => ({ text, copyRange: copyRange ? { file: getValidSourceFile(copyRange.file), range: copyRange.range } : undefined })), pastes, @@ -3190,7 +3190,7 @@ export function createLanguageService( uncommentSelection, provideInlayHints, getSupportedCodeFixes, - getPostPasteImportFixes, + getPasteEdits, }; switch (languageServiceMode) { diff --git a/src/services/types.ts b/src/services/types.ts index 33ed3ede6baca..c3d88e5fa4bc0 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -684,13 +684,13 @@ export interface LanguageService { getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; - getPostPasteImportFixes( + getPasteEdits( targetFile: string, copies: { text: string; range?: { file: string; range: TextRange; }; }[], pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - ): PostPasteImportFixes; + ): PasteEdits; } export interface JsxClosingTagInfo { @@ -713,7 +713,7 @@ export const enum OrganizeImportsMode { RemoveUnused = "RemoveUnused", } -export interface PostPasteImportFixes { +export interface PasteEdits { edits: readonly FileTextChanges[]; } diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3bdb6dfad85b2..030e14bd711e3 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -161,7 +161,7 @@ declare namespace ts { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", - GetPostPasteImportFixes = "getPostPasteImportFixes", + GetPasteEdits = "GetPasteEdits", OrganizeImports = "organizeImports", GetEditsForFileRename = "getEditsForFileRename", ConfigurePlugin = "configurePlugin", @@ -549,21 +549,21 @@ declare namespace ts { /** * Request refactorings at a given position post pasting text from some other location. */ - interface GetPostPasteImportFixesRequest extends Request { - command: CommandTypes.GetPostPasteImportFixes; - arguments: GetPostPasteImportFixesRequestArgs; + interface GetPasteEditsRequest extends Request { + command: CommandTypes.GetPasteEdits; + arguments: GetPasteEditsRequestArgs; } - type GetPostPasteImportFixesRequestArgs = FileRequestArgs & { + type GetPasteEditsRequestArgs = FileRequestArgs & { copies: { text: string; range?: FileSpan; }[]; pastes: TextSpan[]; }; - interface GetPostPasteImportFixesResponse extends Response { - body: PostPasteImportAction; + interface GetPasteEditsResponse extends Response { + body: PasteEditsAction; } - interface PostPasteImportAction { + interface PasteEditsAction { edits: FileCodeEdits[]; } /** @@ -4116,7 +4116,7 @@ declare namespace ts { private getApplicableRefactors; private getEditsForRefactor; private getMoveToRefactoringFileSuggestions; - private getPostPasteImportFixes; + private getPasteEdits; private organizeImports; private getEditsForFileRename; private getCodeFixes; @@ -4125,7 +4125,7 @@ declare namespace ts { private getStartAndEndPosition; private mapCodeAction; private mapCodeFixAction; - private mapPostPasteAction; + private mapPasteEditsAction; private mapTextChangesToCodeEdits; private mapTextChangeToCodeEdit; private convertTextChangeToCodeEdit; @@ -10604,7 +10604,7 @@ declare namespace ts { uncommentSelection(fileName: string, textRange: TextRange): TextChange[]; getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; - getPostPasteImportFixes( + getPasteEdits( targetFile: string, copies: { text: string; @@ -10616,7 +10616,7 @@ declare namespace ts { pastes: TextRange[], preferences: UserPreferences, formatOptions: FormatCodeSettings, - ): PostPasteImportFixes; + ): PasteEdits; } interface JsxClosingTagInfo { readonly newText: string; @@ -10634,7 +10634,7 @@ declare namespace ts { SortAndCombine = "SortAndCombine", RemoveUnused = "RemoveUnused", } - interface PostPasteImportFixes { + interface PasteEdits { edits: readonly FileTextChanges[]; } interface OrganizeImportsArgs extends CombinedCodeFixScope { diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js new file mode 100644 index 0000000000000..181913b06c978 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js @@ -0,0 +1,339 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const t = 1; + +//// [/other2.ts] +export const t2 = 1; + +//// [/other3.ts] +export const t3 = 1; + +//// [/target.ts] +import { t } from "./other"; +import { t3 } from "./other3"; +const a = t + 1; +const b = 10; +const c = 10; + +//// [/tsconfig.json] +{ "files": ["target.ts", "other.ts", "other2.ts", "other3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts", + "/other.ts", + "/other2.ts", + "/other3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-0 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'target.ts' + Part of 'files' list in tsconfig.json + other3.ts + Imported via "./other3" from file 'target.ts' + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + other2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/other2.ts: *new* + {"pollingInterval":500} +/other3.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "const m = t3 + t2 + 1;" + } + ], + "pastes": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (7) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { t2 } from \"./other2\";\n" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + }, + "newText": "const m = t3 + t2 + 1;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js new file mode 100644 index 0000000000000..749a48cb8e5fa --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -0,0 +1,387 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/originalFile.ts] +import { t2 } from "./other2"; +import { t3 } from "./other3"; +export const n = 10; +export const m = t3 + t2 + n; + +//// [/other.ts] +export const t = 1; + +//// [/other2.ts] +export const t2 = 1; + +//// [/other3.ts] +export const t3 = 1; + +//// [/target.ts] +import { t } from "./other"; +import { t3 } from "./other3"; +const a = t + 1; +const b = 10; +const c = 10; + +//// [/tsconfig.json] +{ "files": ["target.ts", "originalFile.ts", "other.ts", "other2.ts", "other3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts", + "/originalFile.ts", + "/other.ts", + "/other2.ts", + "/other3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /originalFile.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-0 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'target.ts' + Part of 'files' list in tsconfig.json + other3.ts + Imported via "./other3" from file 'target.ts' + Imported via "./other3" from file 'originalFile.ts' + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + other2.ts + Imported via "./other2" from file 'originalFile.ts' + Part of 'files' list in tsconfig.json + originalFile.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/originalFile.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/other2.ts: *new* + {"pollingInterval":500} +/other3.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/originalFile.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "const m = t3 + t2 + n;", + "range": { + "file": "originalFile.ts", + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 30 + } + } + } + ], + "pastes": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (8) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /other3.ts Text-1 "export const t3 = 1;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10;" + /other2.ts Text-1 "export const t2 = 1;" + /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { n } from \"./originalFile\";\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { t2 } from \"./other2\";\n" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + }, + "newText": "const m = t3 + t2 + n;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/originalFile.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js new file mode 100644 index 0000000000000..6e21e418043f0 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -0,0 +1,360 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const b = 2; + +//// [/file2.ts] +import { b } from './file1'; +const a = 1; +const c = a + b; +const t = 9; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +export const tt = 2; +function f(); +const p = 1; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts", "target.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts", + "/target.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-1-0 "export const tt = 2;\nfunction f();\nconst p = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + Imported via './file1' from file 'file2.ts' + file2.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/file2.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "const c = a + b;\nconst t = 9;", + "range": { + "file": "file2.ts", + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 13 + } + } + } + ], + "pastes": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const b = 2;" + /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" + /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "export " + } + ] + }, + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { a } from \"./file2\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { b } from './file1';\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + }, + "newText": "const c = a + b;\nconst t = 9;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js new file mode 100644 index 0000000000000..98693518a9dc7 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js @@ -0,0 +1,342 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const p = 10; +export const q = 12; + +//// [/file3.ts] +export const r = 10; +export const s = 12; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +const a = 1; + +const b = 2; +const c = 3; + +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "file3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/file3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-0 "const a = 1;\n\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + file3.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/file3.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "const g = p + q;\nfunction e();\nconst f = r + s;" + } + ], + "pastes": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + } + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { p, q } from \"./file1\";\nimport { r, s } from \"./file3\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "const g = p + q;\nfunction e();\nconst f = r + s;" + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + }, + "newText": "const g = p + q;\nfunction e();\nconst f = r + s;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js new file mode 100644 index 0000000000000..e5c5c48a18f0d --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -0,0 +1,370 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +import { aa, bb } from "./other"; +export const r = 10; +export const s = 12; +export const t = aa + bb + r + s; +const u = 1; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const aa = 1; +export const bb = 2; + +//// [/target.ts] +const a = 1; +const b = 2; +const c = 3; + +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "other.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/other.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'file1.ts' + Part of 'files' list in tsconfig.json + file1.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "export const t = aa + bb + r + s;\nconst u = 1;", + "range": { + "file": "file1.ts", + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 13 + } + } + } + ], + "pastes": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 13 + } + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 1 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" + /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\n\nconst d = 4;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { r, s } from \"./file1\";\n\n" + }, + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { aa, bb } from \"./other\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 13 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;" + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 1 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js new file mode 100644 index 0000000000000..2b380b61b03b8 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js @@ -0,0 +1,267 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +const a = 10; +const b = 10; +const c = 10; + +//// [/tsconfig.json] +{ "files": ["target.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /target.ts SVC-1-0 "const a = 10;\nconst b = 10;\nconst c = 10;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" + } + ], + "pastes": [ + { + "start": { + "line": 2, + "offset": 14 + }, + "end": { + "line": 2, + "offset": 14 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (4) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 14 + }, + "end": { + "line": 2, + "offset": 14 + }, + "newText": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js new file mode 100644 index 0000000000000..b988efc6cebdd --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -0,0 +1,1244 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const t = 1; + +//// [/other2.ts] +export const t2 = 1; + +//// [/target.ts] +import { t } from "./other"; +const a = t + 1; +const b = 10; +type T = number; +var x; +var y = x as + +//// [/tsconfig.json] +{ "files": ["target.ts", "other.ts", "other2.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/target.ts", + "/other.ts", + "/other2.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /target.ts SVC-1-0 "import { t } from \"./other\";\nconst a = t + 1;\nconst b = 10;\ntype T = number;\nvar x;\nvar y = x as " + /other2.ts Text-1 "export const t2 = 1;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'target.ts' + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + other2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/other2.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "copies": [ + { + "text": "const m = t2 + 1;" + } + ], + "pastes": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 14 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as " + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { t2 } from \"./other2\";\n" + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 14 + }, + "newText": "const m = t2 + 1;" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other2.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 3, + "type": "request", + "arguments": { + "preferences": {} + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 3, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 4, + "type": "request", + "arguments": { + "file": "/target.ts", + "line": 6, + "offset": 14 + }, + "command": "completionInfo" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const t = 1;" + /target.ts SVC-1-2 "import { t } from \"./other\";\nconst a = t + 1;\nconst b = 10;\ntype T = number;\nvar x;\nvar y = x as " + /other2.ts Text-1 "export const t2 = 1;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getCompletionData: Get current token: * +Info seq [hh:mm:ss:mss] getCompletionData: Is inside comment: * +Info seq [hh:mm:ss:mss] getCompletionData: Get previous token: * +Info seq [hh:mm:ss:mss] getCompletionsAtPosition: isCompletionListBlocker: * +Info seq [hh:mm:ss:mss] getCompletionData: Semantic work: * +Info seq [hh:mm:ss:mss] getCompletionsAtPosition: getCompletionEntriesFromSymbols: * +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "completionInfo", + "request_seq": 4, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "flags": 0, + "isGlobalCompletion": true, + "isMemberCompletion": false, + "isNewIdentifierLocation": false, + "entries": [ + { + "name": "T", + "kind": "type", + "kindModifiers": "", + "sortText": "11" + }, + { + "name": "any", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBuffer", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferLike", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferTypes", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayBufferView", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ArrayLike", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "asserts", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Awaited", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "bigint", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "boolean", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Boolean", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "BooleanConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "CallableFunction", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Capitalize", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassAccessorDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassAccessorDecoratorResult", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassAccessorDecoratorTarget", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassFieldDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassGetterDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassMemberDecoratorContext", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassMethodDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ClassSetterDecoratorContext", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ConcatArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "const", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "ConstructorParameters", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DataView", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DataViewConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Date", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DateConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DecoratorContext", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DecoratorMetadata", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "DecoratorMetadataObject", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Error", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "EvalError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "EvalErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Exclude", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Extract", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "false", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Float32Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Float32ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Float64Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Float64ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Function", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "FunctionConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "globalThis", + "kind": "module", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "IArguments", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportAttributes", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportCallOptions", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportMeta", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "infer", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "InstanceType", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int16Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int16ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int32Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int32ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int8Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int8ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Intl", + "kind": "module", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "JSON", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "keyof", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Lowercase", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Math", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "MethodDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "never", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "NewableFunction", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "NoInfer", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "NonNullable", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "null", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "number", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Number", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "NumberConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "object", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Object", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ObjectConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Omit", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "OmitThisParameter", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ParameterDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Parameters", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Partial", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Pick", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Promise", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PromiseConstructorLike", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PromiseLike", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyDecorator", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyDescriptor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyDescriptorMap", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "PropertyKey", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RangeError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RangeErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "readonly", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Readonly", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReadonlyArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Record", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReferenceError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReferenceErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExp", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExpConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExpExecArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "RegExpMatchArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Required", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ReturnType", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "string", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "String", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "StringConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "symbol", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Symbol", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "SyntaxError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "SyntaxErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "TemplateStringsArray", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ThisParameterType", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ThisType", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "true", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "TypedPropertyDescriptor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "TypeError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "TypeErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "typeof", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Uint16Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint16ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint32Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint32ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8ArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8ClampedArray", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uint8ClampedArrayConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Uncapitalize", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "undefined", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "unique", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "unknown", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "Uppercase", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "URIError", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "URIErrorConstructor", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "void", + "kind": "keyword", + "kindModifiers": "", + "sortText": "15" + }, + { + "name": "WeakKey", + "kind": "type", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "WeakKeyTypes", + "kind": "interface", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "ImportAssertions", + "kind": "interface", + "kindModifiers": "deprecated,declare", + "sortText": "z15" + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 + projectProgramVersion: 1 + dirty: false *changed* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js new file mode 100644 index 0000000000000..66066479e313e --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js @@ -0,0 +1,300 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export interface Test1 {} +export interface Test2 {} +export interface Test3 {} +export interface Test4 {} + +//// [/file2.ts] +const a = 10; +const b = 10; +const c = 10; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/tsconfig.json] +{ "files": ["file1.ts", "file2.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/file2.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /file2.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/file2.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-1-0 "const a = 10;\nconst b = 10;\nconst c = 10;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + file2.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/file2.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/file2.ts", + "copies": [ + { + "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" + } + ], + "pastes": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + } + } + ] + }, + "command": "GetPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (5) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" + /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "GetPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { Test1, Test2, Test3, Test4 } from \"./file1\";\n\n" + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" + } + ] + } + ] + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file2.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json diff --git a/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js b/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js deleted file mode 100644 index cd4e9f43ba699..0000000000000 --- a/tests/baselines/reference/tsserver/getPostPasteImportFixes/Returns-the-same-file-unchanged-.js +++ /dev/null @@ -1,214 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -Before request -//// [/project/a/target.ts] -const a = 1; -const b = 2; -const c = 3; - -//// [/project/tsconfig.json] -{} - - -Info seq [hh:mm:ss:mss] request: - { - "command": "open", - "arguments": { - "file": "/project/a/target.ts" - }, - "seq": 1, - "type": "request" - } -Info seq [hh:mm:ss:mss] Search path: /project/a -Info seq [hh:mm:ss:mss] For info: /project/a/target.ts :: Config file name: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/project/tsconfig.json", - "reason": "Creating possible configured project for /project/a/target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { - "rootNames": [ - "/project/a/target.ts" - ], - "options": { - "configFilePath": "/project/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory -Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" - - - a/target.ts - Matched by default include pattern '**/*' - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/project/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "telemetry", - "body": { - "telemetryEventName": "projectInfo", - "payload": { - "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", - "fileStats": { - "js": 0, - "jsSize": 0, - "jsx": 0, - "jsxSize": 0, - "ts": 1, - "tsSize": 38, - "tsx": 0, - "tsxSize": 0, - "dts": 0, - "dtsSize": 0, - "deferred": 0, - "deferredSize": 0 - }, - "compilerOptions": {}, - "typeAcquisition": { - "enable": false, - "include": false, - "exclude": false - }, - "extends": false, - "files": false, - "include": false, - "exclude": false, - "compileOnSave": false, - "configFileName": "tsconfig.json", - "projectType": "configured", - "languageServiceEnabled": true, - "version": "FakeVersion" - } - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/project/a/target.ts", - "configFile": "/project/tsconfig.json", - "diagnostics": [ - { - "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", - "code": 6053, - "category": "error" - }, - { - "text": "Cannot find global type 'Array'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Boolean'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Function'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'IArguments'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Number'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Object'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'RegExp'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'String'.", - "code": 2318, - "category": "error" - } - ] - } - } -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json -Info seq [hh:mm:ss:mss] response: - { - "responseRequired": false - } -After request - -PolledWatches:: -/a/lib/lib.d.ts: *new* - {"pollingInterval":500} - -FsWatches:: -/project/tsconfig.json: *new* - {} - -FsWatchesRecursive:: -/project: *new* - {} - -Projects:: -/project/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/project/a/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /project/tsconfig.json *default* - -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-1 "const a = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-2 "const a = 1;\nconst b = 2;\nconst c = 3;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- \ No newline at end of file diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 7074be0b2c88c..beb9e92367b37 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -444,7 +444,7 @@ declare namespace FourSlashInterface { toggleMultilineComment(newFileContent: string): void; commentSelection(newFileContent: string): void; uncommentSelection(newFileContent: string): void; - postPasteImportFixes(options: { + pasteEdits(options: { newFileContents: { readonly [fileName: string]: string }; copies: { text: string; copyRange?: { file: string; range: { pos: number, end: number };} }[], pastes: { pos: number, end: number }[], diff --git a/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts similarity index 92% rename from tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts rename to tests/cases/fourslash/server/pasteEdits_existingImports1.ts index 552829ebe6ae3..545c02f28b99d 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_existingImports1.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts @@ -21,7 +21,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `const m = t3 + t2 + 1;`}], pastes: [{ pos: range[0].pos, end: range[0].end }], newFileContents: { diff --git a/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts similarity index 93% rename from tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts rename to tests/cases/fourslash/server/pasteEdits_existingImports2.ts index 6b991fbdc6904..a453c1af7a089 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_existingImports2.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts @@ -27,7 +27,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `const m = t3 + t2 + n;`, copyRange: { file: "originalFile.ts", range: range[1]}}], pastes: [range[0]], newFileContents: { diff --git a/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts similarity index 92% rename from tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts rename to tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts index a7135d64e53ac..7abb513ab174f 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_knownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts @@ -20,7 +20,7 @@ const range = test.ranges(); const t = range[0]; format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `const c = a + b; const t = 9;`, diff --git a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts similarity index 92% rename from tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts rename to tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts index ff1c5bf8e5d92..c21f07aebe495 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes1.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts @@ -21,7 +21,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `const g = p + q; function e(); diff --git a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts similarity index 93% rename from tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts rename to tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts index b7838b907fc80..65f53d04c58f4 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_multiplePastes2.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -23,7 +23,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `export const t = aa + bb + r + s; const u = 1;`, diff --git a/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts similarity index 89% rename from tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts rename to tests/cases/fourslash/server/pasteEdits_pasteComments.ts index 71c80fb71acb7..16397b0c23f17 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_pasteComments.ts +++ b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts @@ -10,7 +10,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `/** * Testing comment line 1 diff --git a/tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts similarity index 92% rename from tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts rename to tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts index 3fb7b2514a1e4..dddcf842c5003 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_revertUpdatedFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts @@ -19,7 +19,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `const m = t2 + 1;`}], pastes: [{ pos: range[0].pos, end: range[0].end }], newFileContents: { diff --git a/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts similarity index 92% rename from tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts rename to tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts index 0da558ec4c045..54288bf9af78b 100644 --- a/tests/cases/fourslash/server/postPasteImportFixes_unknownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts @@ -16,7 +16,7 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.postPasteImportFixes({ +verify.pasteEdits({ copies: [{ text: `interface Testing { test1: Test1; From c67137b79ed8c0f23e16bb6a303c48a55d9e24e7 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 4 Mar 2024 13:20:19 -0800 Subject: [PATCH 20/41] Removing extra baselines --- .../postPasteImportFixes_existingImports1.js | 339 ----- .../postPasteImportFixes_existingImports2.js | 387 ----- .../postPasteImportFixes_knownSourceFile.js | 360 ----- .../postPasteImportFixes_multiplePastes1.js | 342 ----- .../postPasteImportFixes_multiplePastes2.js | 370 ----- .../postPasteImportFixes_pasteComments.js | 267 ---- .../postPasteImportFixes_revertUpdatedFile.js | 1244 ----------------- .../postPasteImportFixes_unknownSourceFile.js | 300 ---- 8 files changed, 3609 deletions(-) delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js delete mode 100644 tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js deleted file mode 100644 index 8360609c95b49..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports1.js +++ /dev/null @@ -1,339 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/other.ts] -export const t = 1; - -//// [/other2.ts] -export const t2 = 1; - -//// [/other3.ts] -export const t3 = 1; - -//// [/target.ts] -import { t } from "./other"; -import { t3 } from "./other3"; -const a = t + 1; -const b = 10; -const c = 10; - -//// [/tsconfig.json] -{ "files": ["target.ts", "other.ts", "other2.ts", "other3.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/target.ts", - "/other.ts", - "/other2.ts", - "/other3.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other3.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (7) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-0 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" - /other2.ts Text-1 "export const t2 = 1;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - other.ts - Imported via "./other" from file 'target.ts' - Part of 'files' list in tsconfig.json - other3.ts - Imported via "./other3" from file 'target.ts' - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - other2.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (7) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/other.ts: *new* - {"pollingInterval":500} -/other2.ts: *new* - {"pollingInterval":500} -/other3.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other2.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other3.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "const m = t3 + t2 + 1;" - } - ], - "pastes": [ - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 14 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (7) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10;" - /other2.ts Text-1 "export const t2 = 1;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "import { t2 } from \"./other2\";\n" - }, - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 14 - }, - "newText": "const m = t3 + t2 + 1;" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other2.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other3.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js deleted file mode 100644 index 01d324bffe176..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_existingImports2.js +++ /dev/null @@ -1,387 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/originalFile.ts] -import { t2 } from "./other2"; -import { t3 } from "./other3"; -export const n = 10; -export const m = t3 + t2 + n; - -//// [/other.ts] -export const t = 1; - -//// [/other2.ts] -export const t2 = 1; - -//// [/other3.ts] -export const t3 = 1; - -//// [/target.ts] -import { t } from "./other"; -import { t3 } from "./other3"; -const a = t + 1; -const b = 10; -const c = 10; - -//// [/tsconfig.json] -{ "files": ["target.ts", "originalFile.ts", "other.ts", "other2.ts", "other3.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/target.ts", - "/originalFile.ts", - "/other.ts", - "/other2.ts", - "/other3.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /originalFile.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other3.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (8) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-0 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst b = 10;\nconst c = 10;" - /other2.ts Text-1 "export const t2 = 1;" - /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - other.ts - Imported via "./other" from file 'target.ts' - Part of 'files' list in tsconfig.json - other3.ts - Imported via "./other3" from file 'target.ts' - Imported via "./other3" from file 'originalFile.ts' - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - other2.ts - Imported via "./other2" from file 'originalFile.ts' - Part of 'files' list in tsconfig.json - originalFile.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (8) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/originalFile.ts: *new* - {"pollingInterval":500} -/other.ts: *new* - {"pollingInterval":500} -/other2.ts: *new* - {"pollingInterval":500} -/other3.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/originalFile.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other2.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other3.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "const m = t3 + t2 + n;", - "range": { - "file": "originalFile.ts", - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 30 - } - } - } - ], - "pastes": [ - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 14 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (8) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10;" - /other2.ts Text-1 "export const t2 = 1;" - /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results -Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { n } from \"./originalFile\";\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "import { t2 } from \"./other2\";\n" - }, - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 14 - }, - "newText": "const m = t3 + t2 + n;" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/originalFile.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other2.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other3.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js deleted file mode 100644 index 2ae72b6f0467c..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_knownSourceFile.js +++ /dev/null @@ -1,360 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -export const b = 2; - -//// [/file2.ts] -import { b } from './file1'; -const a = 1; -const c = a + b; -const t = 9; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/target.ts] -export const tt = 2; -function f(); -const p = 1; - -//// [/tsconfig.json] -{ "files": ["file1.ts", "file2.ts", "target.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/file2.ts", - "/target.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export const b = 2;" - /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-1-0 "export const tt = 2;\nfunction f();\nconst p = 1;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - file1.ts - Part of 'files' list in tsconfig.json - Imported via './file1' from file 'file2.ts' - file2.ts - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file1.ts: *new* - {"pollingInterval":500} -/file2.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/file1.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/file2.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "const c = a + b;\nconst t = 9;", - "range": { - "file": "file2.ts", - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 13 - } - } - } - ], - "pastes": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 14 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export const b = 2;" - /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results -Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/file2.ts", - "textChanges": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "export " - } - ] - }, - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { a } from \"./file2\";\n\n" - }, - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { b } from './file1';\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 14 - }, - "newText": "const c = a + b;\nconst t = 9;" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/file1.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/file2.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js deleted file mode 100644 index 780462985057d..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes1.js +++ /dev/null @@ -1,342 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -export const p = 10; -export const q = 12; - -//// [/file3.ts] -export const r = 10; -export const s = 12; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/target.ts] -const a = 1; - -const b = 2; -const c = 3; - -const d = 4; - -//// [/tsconfig.json] -{ "files": ["file1.ts", "target.ts", "file3.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/target.ts", - "/file3.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file3.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" - /target.ts SVC-1-0 "const a = 1;\n\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" - /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - file1.ts - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - file3.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file1.ts: *new* - {"pollingInterval":500} -/file3.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/file1.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/file3.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "const g = p + q;\nfunction e();\nconst f = r + s;" - } - ], - "pastes": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - } - }, - { - "start": { - "line": 5, - "offset": 1 - }, - "end": { - "line": 5, - "offset": 1 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" - /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" - /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { p, q } from \"./file1\";\nimport { r, s } from \"./file3\";\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "const g = p + q;\nfunction e();\nconst f = r + s;" - }, - { - "start": { - "line": 5, - "offset": 1 - }, - "end": { - "line": 5, - "offset": 1 - }, - "newText": "const g = p + q;\nfunction e();\nconst f = r + s;" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/file1.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/file3.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js deleted file mode 100644 index fa52a13e95f3b..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_multiplePastes2.js +++ /dev/null @@ -1,370 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -import { aa, bb } from "./other"; -export const r = 10; -export const s = 12; -export const t = aa + bb + r + s; -const u = 1; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/other.ts] -export const aa = 1; -export const bb = 2; - -//// [/target.ts] -const a = 1; -const b = 2; -const c = 3; - -const d = 4; - -//// [/tsconfig.json] -{ "files": ["file1.ts", "target.ts", "other.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/target.ts", - "/other.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" - /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - other.ts - Imported via "./other" from file 'file1.ts' - Part of 'files' list in tsconfig.json - file1.ts - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file1.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/other.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/file1.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "export const t = aa + bb + r + s;\nconst u = 1;", - "range": { - "file": "file1.ts", - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 5, - "offset": 13 - } - } - } - ], - "pastes": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 13 - } - }, - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 1 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" - /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\n\nconst d = 4;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results -Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { r, s } from \"./file1\";\n\n" - }, - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { aa, bb } from \"./other\";\n\n" - }, - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 13 - }, - "newText": "export const t = aa + bb + r + s;\nconst u = 1;" - }, - { - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 1 - }, - "newText": "export const t = aa + bb + r + s;\nconst u = 1;" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/file1.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js deleted file mode 100644 index 6304a811cddbc..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_pasteComments.js +++ /dev/null @@ -1,267 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/target.ts] -const a = 10; -const b = 10; -const c = 10; - -//// [/tsconfig.json] -{ "files": ["target.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/target.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (4) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /target.ts SVC-1-0 "const a = 10;\nconst b = 10;\nconst c = 10;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - target.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (4) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" - } - ], - "pastes": [ - { - "start": { - "line": 2, - "offset": 14 - }, - "end": { - "line": 2, - "offset": 14 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (4) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 2, - "offset": 14 - }, - "end": { - "line": 2, - "offset": 14 - }, - "newText": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js deleted file mode 100644 index 057b4f3e70df0..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_revertUpdatedFile.js +++ /dev/null @@ -1,1244 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/other.ts] -export const t = 1; - -//// [/other2.ts] -export const t2 = 1; - -//// [/target.ts] -import { t } from "./other"; -const a = t + 1; -const b = 10; -type T = number; -var x; -var y = x as - -//// [/tsconfig.json] -{ "files": ["target.ts", "other.ts", "other2.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/target.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/target.ts", - "/other.ts", - "/other2.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other2.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /target.ts SVC-1-0 "import { t } from \"./other\";\nconst a = t + 1;\nconst b = 10;\ntype T = number;\nvar x;\nvar y = x as " - /other2.ts Text-1 "export const t2 = 1;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - other.ts - Imported via "./other" from file 'target.ts' - Part of 'files' list in tsconfig.json - target.ts - Part of 'files' list in tsconfig.json - other2.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/target.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/other.ts: *new* - {"pollingInterval":500} -/other2.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other2.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/target.ts", - "copies": [ - { - "text": "const m = t2 + 1;" - } - ], - "pastes": [ - { - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 14 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as " - /other2.ts Text-1 "export const t2 = 1;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/target.ts", - "textChanges": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "import { t2 } from \"./other2\";\n" - }, - { - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 14 - }, - "newText": "const m = t2 + 1;" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/other2.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* - -Info seq [hh:mm:ss:mss] request: - { - "seq": 3, - "type": "request", - "arguments": { - "preferences": {} - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 3, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 4, - "type": "request", - "arguments": { - "file": "/target.ts", - "line": 6, - "offset": 14 - }, - "command": "completionInfo" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (6) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /other.ts Text-1 "export const t = 1;" - /target.ts SVC-1-2 "import { t } from \"./other\";\nconst a = t + 1;\nconst b = 10;\ntype T = number;\nvar x;\nvar y = x as " - /other2.ts Text-1 "export const t2 = 1;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] getCompletionData: Get current token: * -Info seq [hh:mm:ss:mss] getCompletionData: Is inside comment: * -Info seq [hh:mm:ss:mss] getCompletionData: Get previous token: * -Info seq [hh:mm:ss:mss] getCompletionsAtPosition: isCompletionListBlocker: * -Info seq [hh:mm:ss:mss] getCompletionData: Semantic work: * -Info seq [hh:mm:ss:mss] getCompletionsAtPosition: getCompletionEntriesFromSymbols: * -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "completionInfo", - "request_seq": 4, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "flags": 0, - "isGlobalCompletion": true, - "isMemberCompletion": false, - "isNewIdentifierLocation": false, - "entries": [ - { - "name": "T", - "kind": "type", - "kindModifiers": "", - "sortText": "11" - }, - { - "name": "any", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayBuffer", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayBufferConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayBufferLike", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayBufferTypes", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayBufferView", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ArrayLike", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "asserts", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Awaited", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "bigint", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "boolean", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Boolean", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "BooleanConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "CallableFunction", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Capitalize", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassAccessorDecoratorContext", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassAccessorDecoratorResult", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassAccessorDecoratorTarget", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassDecorator", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassDecoratorContext", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassFieldDecoratorContext", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassGetterDecoratorContext", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassMemberDecoratorContext", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassMethodDecoratorContext", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ClassSetterDecoratorContext", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ConcatArray", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "const", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "ConstructorParameters", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "DataView", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "DataViewConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Date", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "DateConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "DecoratorContext", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "DecoratorMetadata", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "DecoratorMetadataObject", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Error", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "EvalError", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "EvalErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Exclude", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Extract", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "false", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Float32Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Float32ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Float64Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Float64ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Function", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "FunctionConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "globalThis", - "kind": "module", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "IArguments", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ImportAttributes", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ImportCallOptions", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ImportMeta", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "infer", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "InstanceType", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Int16Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Int16ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Int32Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Int32ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Int8Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Int8ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Intl", - "kind": "module", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "JSON", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "keyof", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Lowercase", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Math", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "MethodDecorator", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "never", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "NewableFunction", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "NoInfer", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "NonNullable", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "null", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "number", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Number", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "NumberConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "object", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Object", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ObjectConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Omit", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "OmitThisParameter", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ParameterDecorator", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Parameters", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Partial", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Pick", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Promise", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "PromiseConstructorLike", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "PromiseLike", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "PropertyDecorator", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "PropertyDescriptor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "PropertyDescriptorMap", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "PropertyKey", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "RangeError", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "RangeErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "readonly", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Readonly", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ReadonlyArray", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Record", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ReferenceError", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ReferenceErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "RegExp", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "RegExpConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "RegExpExecArray", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "RegExpMatchArray", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Required", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ReturnType", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "string", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "String", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "StringConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "symbol", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Symbol", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "SyntaxError", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "SyntaxErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "TemplateStringsArray", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ThisParameterType", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ThisType", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "true", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "TypedPropertyDescriptor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "TypeError", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "TypeErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "typeof", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Uint16Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint16ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint32Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint32ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint8Array", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint8ArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint8ClampedArray", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uint8ClampedArrayConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "Uncapitalize", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "undefined", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "unique", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "unknown", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "Uppercase", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "URIError", - "kind": "var", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "URIErrorConstructor", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "void", - "kind": "keyword", - "kindModifiers": "", - "sortText": "15" - }, - { - "name": "WeakKey", - "kind": "type", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "WeakKeyTypes", - "kind": "interface", - "kindModifiers": "declare", - "sortText": "15" - }, - { - "name": "ImportAssertions", - "kind": "interface", - "kindModifiers": "deprecated,declare", - "sortText": "z15" - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 - projectProgramVersion: 1 - dirty: false *changed* diff --git a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js deleted file mode 100644 index ec192f526b399..0000000000000 --- a/tests/baselines/reference/tsserver/fourslashServer/postPasteImportFixes_unknownSourceFile.js +++ /dev/null @@ -1,300 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -//// [/file1.ts] -export interface Test1 {} -export interface Test2 {} -export interface Test3 {} -export interface Test4 {} - -//// [/file2.ts] -const a = 10; -const b = 10; -const c = 10; - -//// [/lib.d.ts] -lib.d.ts-Text - -//// [/lib.decorators.d.ts] -lib.decorators.d.ts-Text - -//// [/lib.decorators.legacy.d.ts] -lib.decorators.legacy.d.ts-Text - -//// [/tsconfig.json] -{ "files": ["file1.ts", "file2.ts"] } - - -Info seq [hh:mm:ss:mss] request: - { - "seq": 0, - "type": "request", - "arguments": { - "file": "/file2.ts" - }, - "command": "open" - } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/tsconfig.json", - "reason": "Creating possible configured project for /file2.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { - "rootNames": [ - "/file1.ts", - "/file2.ts" - ], - "options": { - "configFilePath": "/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-1-0 "const a = 10;\nconst b = 10;\nconst c = 10;" - - - lib.d.ts - Default library for target 'es5' - lib.decorators.d.ts - Library referenced via 'decorators' from file 'lib.d.ts' - lib.decorators.legacy.d.ts - Library referenced via 'decorators.legacy' from file 'lib.d.ts' - file1.ts - Part of 'files' list in tsconfig.json - file2.ts - Part of 'files' list in tsconfig.json - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/file2.ts", - "configFile": "/tsconfig.json", - "diagnostics": [] - } - } -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /file2.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /tsconfig.json -After Request -watchedFiles:: -/file1.ts: *new* - {"pollingInterval":500} -/lib.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.d.ts: *new* - {"pollingInterval":500} -/lib.decorators.legacy.d.ts: *new* - {"pollingInterval":500} -/tsconfig.json: *new* - {"pollingInterval":2000} - -Projects:: -/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/file1.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/file2.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /tsconfig.json *default* -/lib.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts *new* - version: Text-1 - containingProjects: 1 - /tsconfig.json - -Info seq [hh:mm:ss:mss] request: - { - "seq": 1, - "type": "request", - "arguments": { - "formatOptions": { - "indentSize": 4, - "tabSize": 4, - "newLineCharacter": "\n", - "convertTabsToSpaces": true, - "indentStyle": 2, - "insertSpaceAfterConstructor": false, - "insertSpaceAfterCommaDelimiter": true, - "insertSpaceAfterSemicolonInForStatements": true, - "insertSpaceBeforeAndAfterBinaryOperators": true, - "insertSpaceAfterKeywordsInControlFlowStatements": true, - "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, - "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, - "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, - "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, - "insertSpaceBeforeFunctionParenthesis": false, - "placeOpenBraceOnNewLineForFunctions": false, - "placeOpenBraceOnNewLineForControlBlocks": false, - "semicolons": "ignore", - "trimTrailingWhitespace": true, - "indentSwitchCase": true - } - }, - "command": "configure" - } -Info seq [hh:mm:ss:mss] Format host information updated -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "configure", - "request_seq": 1, - "success": true - } -Info seq [hh:mm:ss:mss] request: - { - "seq": 2, - "type": "request", - "arguments": { - "file": "/file2.ts", - "copies": [ - { - "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" - } - ], - "pastes": [ - { - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 1 - } - } - ] - }, - "command": "getPostPasteImportFixes" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (5) - /lib.d.ts Text-1 lib.d.ts-Text - /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text - /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10;" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "seq": 0, - "type": "response", - "command": "getPostPasteImportFixes", - "request_seq": 2, - "success": true, - "performanceData": { - "updateGraphDurationMs": * - }, - "body": { - "edits": [ - { - "fileName": "/file2.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { Test1, Test2, Test3, Test4 } from \"./file1\";\n\n" - }, - { - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 1 - }, - "newText": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" - } - ] - } - ] - } - } -After Request -Projects:: -/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/file1.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/file2.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /tsconfig.json *default* -/lib.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json -/lib.decorators.legacy.d.ts - version: Text-1 - containingProjects: 1 - /tsconfig.json From 392dd758713f60eac15d2299a5ef423083bd4f3f Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 5 Mar 2024 15:12:26 -0800 Subject: [PATCH 21/41] adressing pr comments --- src/harness/fourslashInterfaceImpl.ts | 7 ------- src/server/project.ts | 4 ++-- src/services/types.ts | 2 +- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index 98849c8fd1055..c1a84477c25e3 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1887,13 +1887,6 @@ export interface VerifyCodeFixAllOptions { preferences?: ts.UserPreferences; } -export interface VerifyPasteEdits { - targetFile: string; - pastes: { text: string; range: ts.TextRange; }[]; - copySpan?: { file: string; range: ts.TextRange; }; - preferences: ts.UserPreferences; -} - export interface VerifyRefactorOptions { name: string; actionName: string; diff --git a/src/server/project.ts b/src/server/project.ts index d2cf55c03a288..fc459c43c62eb 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2215,12 +2215,12 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - runWithTemporaryFileUpdate(rootFile: string, pastedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedFile: SourceFile) => void) { + runWithTemporaryFileUpdate(rootFile: string, updatedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedFile: SourceFile) => void) { const originalProgram = this.program; const originalText = this.program?.getSourceFile(rootFile)?.getText(); Debug.assert(this.program && this.program.getSourceFile(rootFile) && originalText); - this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, pastedText); + this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, updatedText); this.updateGraph(); cb(this.program, originalProgram, (this.program?.getSourceFile(rootFile))!); this.getScriptInfo(rootFile)?.editContent(0, this.program.getSourceFile(rootFile)!.getText().length, originalText); diff --git a/src/services/types.ts b/src/services/types.ts index 5ebd328829ccf..091095c79449a 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -431,7 +431,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, pastedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void; + /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, updatedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void; jsDocParsingMode?: JSDocParsingMode | undefined; } From 778e2b4d135f31e1a8a7531c1828af4f42335778 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 19 Mar 2024 14:56:50 -0700 Subject: [PATCH 22/41] protocol changes and fixed tests --- src/harness/client.ts | 13 +- src/harness/fourslashImpl.ts | 4 +- src/harness/fourslashInterfaceImpl.ts | 5 +- src/server/protocol.ts | 11 +- src/server/session.ts | 23 +- src/services/codefixes/helpers.ts | 2 +- src/services/pasteEdits.ts | 61 ++- src/services/refactors/helpers.ts | 130 ++++++ src/services/services.ts | 15 +- src/services/types.ts | 14 +- src/services/utilities.ts | 105 ----- .../pasteEdits_existingImports1.js | 15 +- .../pasteEdits_existingImports2.js | 43 +- .../pasteEdits_knownSourceFile.js | 43 +- .../pasteEdits_multiplePastes1.js | 17 +- .../pasteEdits_multiplePastes2.js | 45 +- .../pasteEdits_multiplePastes3.js | 416 ++++++++++++++++++ .../pasteEdits_pasteComments.js | 15 +- .../pasteEdits_revertUpdatedFile.js | 15 +- .../pasteEdits_unknownSourceFile.js | 15 +- .../server/pasteEdits_existingImports1.ts | 9 +- .../server/pasteEdits_existingImports2.ts | 12 +- .../server/pasteEdits_knownSourceFile.ts | 17 +- .../server/pasteEdits_multiplePastes1.ts | 13 +- .../server/pasteEdits_multiplePastes2.ts | 12 +- .../server/pasteEdits_multiplePastes3.ts | 55 +++ .../server/pasteEdits_pasteComments.ts | 13 +- .../server/pasteEdits_revertUpdatedFile.ts | 9 +- .../server/pasteEdits_unknownSourceFile.ts | 13 +- 29 files changed, 852 insertions(+), 308 deletions(-) create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js create mode 100644 tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts diff --git a/src/harness/client.ts b/src/harness/client.ts index e5547e6fa851a..5a069cabc7bc2 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -50,6 +50,7 @@ import { OrganizeImportsArgs, OutliningSpan, PasteEdits, + PasteEditsArgs, PatternMatchKind, Program, QuickInfo, @@ -1011,16 +1012,14 @@ export class SessionClient implements LanguageService { } getPasteEdits( - targetFile: string, - copies: { text: string; copyRange?: { file: string; range: TextRange; }; }[], - pastes: TextRange[], - _preferences: UserPreferences, + { targetFile, pastedText, pasteLocations, copiedFrom }: PasteEditsArgs, _formatOptions: FormatCodeSettings, ): PasteEdits { const args: protocol.GetPasteEditsRequestArgs = { file: targetFile, - copies: copies.map(copy => ({ text: copy.text, range: copy.copyRange ? { file: copy.copyRange.file, start: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.pos), end: this.positionToOneBasedLineOffset(copy.copyRange.file, copy.copyRange.range.end) } : undefined })), - pastes: pastes.map(paste => ({ start: this.positionToOneBasedLineOffset(targetFile, paste.pos), end: this.positionToOneBasedLineOffset(targetFile, paste.end) })), + pastedText, + pasteLocations: pasteLocations.map(range => ({ start: this.positionToOneBasedLineOffset(targetFile, range.pos), end: this.positionToOneBasedLineOffset(targetFile, range.end) })), + copiedFrom: copiedFrom ? { file: copiedFrom.file, range: copiedFrom.range.map(range => ({ start: this.positionToOneBasedLineOffset(copiedFrom.file, range.pos), end: this.positionToOneBasedLineOffset(copiedFrom.file, range.end) })) } : undefined, }; const request = this.processRequest(protocol.CommandTypes.GetPasteEdits, args); const response = this.processResponse(request); @@ -1028,7 +1027,7 @@ export class SessionClient implements LanguageService { return { edits: [] }; } const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); - return { edits }; + return { edits, fixId: response.body.fixId }; } getProgram(): Program { diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index 7957cd30e4ccb..7bc20917bce6b 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3563,8 +3563,8 @@ export class TestState { } public verifyPasteEdits(options: FourSlashInterface.PasteEditsOptions): void { - const editInfo = this.languageService.getPasteEdits(this.activeFile.fileName, options.copies, options.pastes, options.preferences, this.formatCodeSettings); - this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); + const editInfo = this.languageService.getPasteEdits({ targetFile: this.activeFile.fileName, pastedText: options.args.pastedText, pasteLocations: options.args.pasteLocations, copiedFrom: options.args.copiedFrom, preferences: options.args.preferences }, this.formatCodeSettings); + (options.fixId === editInfo.fixId) ? this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits) : this.raiseError(`Expected to find a fix ${editInfo.fixId}, but none exists`); } public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) { diff --git a/src/harness/fourslashInterfaceImpl.ts b/src/harness/fourslashInterfaceImpl.ts index c1a84477c25e3..04ea440554291 100644 --- a/src/harness/fourslashInterfaceImpl.ts +++ b/src/harness/fourslashInterfaceImpl.ts @@ -1929,9 +1929,8 @@ export interface MoveToFileOptions { export interface PasteEditsOptions { readonly newFileContents: { readonly [fileName: string]: string; }; - readonly copies: { text: string; copyRange?: { file: string; range: ts.TextRange; }; }[]; - readonly pastes: ts.TextRange[]; - readonly preferences: ts.UserPreferences; + args: ts.PasteEditsArgs; + readonly fixId: string; } export type RenameLocationsOptions = readonly RenameLocationOptions[] | { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 075b9b12a5177..a001d0e143590 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -161,7 +161,7 @@ export const enum CommandTypes { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", - GetPasteEdits = "GetPasteEdits", + GetPasteEdits = "getPasteEdits", /** @internal */ GetEditsForRefactorFull = "getEditsForRefactor-full", @@ -636,17 +636,16 @@ export interface GetPasteEditsRequest extends Request { } export type GetPasteEditsRequestArgs = FileRequestArgs & { - copies: { - text: string; - range?: FileSpan; - }[]; - pastes: TextSpan[]; + pastedText: string[]; + pasteLocations: TextSpan[]; + copiedFrom?: { file: string; range: TextSpan[]; }; }; export interface GetPasteEditsResponse extends Response { body: PasteEditsAction; } export interface PasteEditsAction { edits: FileCodeEdits[]; + fixId?: {}; } export interface GetEditsForRefactorRequest extends Request { diff --git a/src/server/session.ts b/src/server/session.ts index b07b3d25642b0..b53e8ccd44bc8 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2798,16 +2798,17 @@ export class Session implements EventSender { private getPasteEdits(args: protocol.GetPasteEditsRequestArgs): protocol.PasteEditsAction | undefined { const { file, project } = this.getFileAndProject(args); - const copyFile = args.copies[0].range ? args.copies[0].range.file : undefined; + const copyFile = args.copiedFrom ? args.copiedFrom.file : undefined; const result = project.getLanguageService().getPasteEdits( - file, - args.copies.map(copy => ({ - text: copy.text, - copyRange: copy.range && copyFile - ? { file: copy.range.file, range: this.getRange({ file: copyFile, startLine: copy.range.start.line, startOffset: copy.range.start.offset, endLine: copy.range.end.line, endOffset: copy.range.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!) } : undefined, - })), - args.pastes.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), - this.getPreferences(file), + { + targetFile: file, + pastedText: args.pastedText, + pasteLocations: args.pasteLocations.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), + copiedFrom: args.copiedFrom && copyFile + ? { file: args.copiedFrom.file, range: args.copiedFrom.range.map(copies => this.getRange({ file: copyFile, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!)) } + : undefined, + preferences: this.getPreferences(file), + }, this.getFormatOptions(file), ); if (result === undefined) { @@ -2948,8 +2949,8 @@ export class Session implements EventSender { return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription }; } - private mapPasteEditsAction({ edits }: PasteEdits): protocol.PasteEditsAction { - return { edits: this.mapTextChangesToCodeEdits(edits) }; + private mapPasteEditsAction({ edits, fixId }: PasteEdits): protocol.PasteEditsAction { + return { edits: this.mapTextChangesToCodeEdits(edits), fixId }; } private mapTextChangesToCodeEdits(textChanges: readonly FileTextChanges[]): protocol.FileCodeEdits[] { diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 5e6dd79755636..d55a77fe2f4ca 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -925,7 +925,7 @@ function replaceFirstIdentifierOfEntityName(name: EntityName, newIdentifier: Ide /** @internal */ export function importSymbols(importAdder: ImportAdder, symbols: readonly Symbol[]) { - symbols.forEach(s => importAdder.addImportFromExportedSymbol(s, /*isValidTypeOnlyUseSite*/ true)); + symbols.forEach(s => importAdder.addImportFromSymbol(s, /*isValidTypeOnlyUseSite*/ true)); } /** @internal */ diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index bff563a5a07bd..223416868d393 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -14,15 +14,18 @@ import { } from "../compiler/utilities"; import { codefix, + Debug, fileShouldUseJavaScriptRequire, forEachChild, formatting, getQuotePreference, - getTargetFileImportsAndAddExportInOldFile, insertImports, isIdentifier, textChanges, } from "./_namespaces/ts"; +import { + getTargetFileImportsAndAddExportInOldFile, +} from "./refactors/helpers"; import { getExistingLocals, getUsageInfo, @@ -34,44 +37,59 @@ import { PasteEdits, } from "./types"; +const fixId = "providePostPasteEdits"; /** @internal */ export function pasteEditsProvider( targetFile: SourceFile, - copies: { text: string; copyRange?: { file: SourceFile; range: TextRange; }; }[], - pastes: TextRange[], + pastedText: string[], + pasteLocations: TextRange[], + copiedFrom: { file: SourceFile; range: TextRange[]; } | undefined, host: LanguageServiceHost, preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, ): PasteEdits { - const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => pasteEdits(targetFile, copies, pastes, host, preferences, formatContext, cancellationToken, changeTracker)); - return { edits: changes }; + const changes: FileTextChanges[] = textChanges.ChangeTracker.with({ host, formatContext, preferences }, changeTracker => pasteEdits(targetFile, pastedText, pasteLocations, copiedFrom, host, preferences, formatContext, cancellationToken, changeTracker)); + return { edits: changes, fixId }; } function pasteEdits( targetFile: SourceFile, - copies: { text: string; copyRange?: { file: SourceFile; range: TextRange; }; }[], - pastes: TextRange[], + pastedText: string[], + pasteLocations: TextRange[], + copiedFrom: { file: SourceFile; range: TextRange[]; } | undefined, host: LanguageServiceHost, preferences: UserPreferences, formatContext: formatting.FormatContext, cancellationToken: CancellationToken, changes: textChanges.ChangeTracker, ) { - const copy = copies[0]; const statements: Statement[] = []; - host.runWithTemporaryFileUpdate?.(targetFile.fileName, targetFile.getText().slice(0, pastes[0].pos) + copy.text + targetFile.getText().slice(pastes[0].end), (updatedProgram, originalProgram, updatedFile) => { - if (copy.copyRange) { - addRange(statements, copy.copyRange.file.statements, getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.pos), getLineOfLocalPosition(copy.copyRange.file, copy.copyRange.range.end) + 1); - const usage = getUsageInfo(copy.copyRange.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); + let start = 0; + let newText = ""; + pasteLocations.forEach((location, i) => { + if (i === pasteLocations.length - 1) { + newText += targetFile.getText().slice(start, location.pos) + pastedText[i] + targetFile.getText().slice(location.end); + } + else { + newText += targetFile.getText().slice(start, location.pos) + pastedText[i]; + start = location.end; + } + }); + host.runWithTemporaryFileUpdate?.(targetFile.fileName, newText, (updatedProgram, originalProgram, updatedFile) => { + if (copiedFrom?.range) { + Debug.assert(copiedFrom.range.length === pastedText.length); + copiedFrom.range.forEach(copy => { + addRange(statements, copiedFrom.file.statements, getLineOfLocalPosition(copiedFrom.file, copy.pos), getLineOfLocalPosition(copiedFrom.file, copy.end) + 1); + }); + const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); - - const imports = getTargetFileImportsAndAddExportInOldFile(copy.copyRange.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copy.copyRange.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); + const imports = getTargetFileImportsAndAddExportInOldFile(copiedFrom.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copiedFrom.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); if (imports.length > 0) { insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } - importAdder.writeFixes(changes, getQuotePreference(copy.copyRange.file, preferences)); + importAdder.writeFixes(changes, getQuotePreference(copiedFrom.file, preferences)); } else { const context: CodeFixContextBase = { @@ -97,7 +115,16 @@ function pasteEdits( importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); } }); - pastes.forEach(paste => { - changes.replaceRangeWithText(targetFile, { pos: paste.pos, end: paste.end }, copy.text); + + if (pastedText.length !== 1) { + Debug.assert(pastedText.length === pasteLocations.length); + } + pasteLocations.forEach((paste, i) => { + changes.replaceRangeWithText( + targetFile, + { pos: paste.pos, end: paste.end }, + pastedText.length === 1 ? + pastedText[0] : pastedText[i], + ); }); } diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index ce50f672d23b8..bccc300ad0aa7 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -1,3 +1,41 @@ +import { + getModuleSpecifier, +} from "../../compiler/moduleSpecifiers"; +import { + AnyImportOrRequireStatement, + append, + codefix, + factory, + hasSyntacticModifier, + Identifier, + ModifierFlags, + Program, + skipAlias, + SourceFile, + Symbol, + textChanges, + TypeChecker, +} from "../_namespaces/ts"; +import { + LanguageServiceHost, +} from "../types"; +import { + createModuleSpecifierResolutionHost, + makeStringLiteral, + nodeSeenTracker, + QuotePreference, +} from "../utilities"; +import { + addExportToChanges, + filterImport, + forEachImportInStatement, + getTopLevelDeclarationStatement, + isTopLevelDeclaration, + makeImportOrRequire, + moduleSpecifierFromImport, + nameOfTopLevelDeclaration, +} from "./moveToFile"; + /** * Returned by refactor functions when some error message needs to be surfaced to users. * @@ -26,3 +64,95 @@ export function refactorKindBeginsWith(known: string, requested: string | undefi if (!requested) return true; return known.substr(0, requested.length) === requested; } + +/** @internal */ +export function getTargetFileImportsAndAddExportInOldFile( + oldFile: SourceFile, + targetFile: string, + importsToCopy: Map, + targetFileImportsFromOldFile: Set, + changes: textChanges.ChangeTracker, + checker: TypeChecker, + program: Program, + host: LanguageServiceHost, + useEsModuleSyntax: boolean, + quotePreference: QuotePreference, + importAdder?: codefix.ImportAdder, +): readonly AnyImportOrRequireStatement[] { + const copiedOldImports: AnyImportOrRequireStatement[] = []; + /** + * Recomputing the imports is preferred with importAdder because it manages multiple import additions for a file and writes then to a ChangeTracker, + * but sometimes it fails because of unresolved imports from files, or when a source file is not available for the target file (in this case when creating a new file). + * So in that case, fall back to copying the import verbatim. + */ + if (importAdder) { + importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { + try { + importAdder.addImportFromSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); + } + catch { + for (const oldStatement of oldFile.statements) { + forEachImportInStatement(oldStatement, i => { + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + }); + } + } + }); + } + else { + const targetSourceFile = program.getSourceFile(targetFile); // Would be undefined for a new file + for (const oldStatement of oldFile.statements) { + forEachImportInStatement(oldStatement, i => { + // Recomputing module specifier + const moduleSpecifier = moduleSpecifierFromImport(i); + const compilerOptions = program.getCompilerOptions(); + const resolved = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier); + const fileName = resolved?.resolvedModule?.resolvedFileName; + if (fileName && targetSourceFile) { + const newModuleSpecifier = getModuleSpecifier(compilerOptions, targetSourceFile, targetSourceFile.fileName, fileName, createModuleSpecifierResolutionHost(program, host)); + append(copiedOldImports, filterImport(i, makeStringLiteral(newModuleSpecifier, quotePreference), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + } + else { + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + } + }); + } + } + + // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. + const targetFileSourceFile = program.getSourceFile(targetFile); + let oldFileDefault: Identifier | undefined; + const oldFileNamedImports: string[] = []; + const oldFileNonExportedSymbols: Symbol[] = []; + const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. + targetFileImportsFromOldFile.forEach(symbol => { + if (!symbol.declarations) { + return; + } + for (const decl of symbol.declarations) { + if (!isTopLevelDeclaration(decl)) continue; + const name = nameOfTopLevelDeclaration(decl); + if (!name) continue; + + const top = getTopLevelDeclarationStatement(decl); + if (markSeenTop(top)) { + addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); + oldFileNonExportedSymbols.push(symbol); + } + if (importAdder && !checker.isUnknownSymbol(symbol) && symbol.parent) { + oldFileNamedImports.push(name.text); + } + else { + if (hasSyntacticModifier(decl, ModifierFlags.Default)) { + oldFileDefault = name; + } + else { + oldFileNamedImports.push(name.text); + } + } + } + }); + return targetFileSourceFile + ? append(copiedOldImports, makeImportOrRequire(targetFileSourceFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference, oldFileNonExportedSymbols, importAdder)) + : append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); +} diff --git a/src/services/services.ts b/src/services/services.ts index 1db068a8e1b57..353e1f4d4932a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -240,6 +240,7 @@ import { parseJsonSourceFileConfigFileContent, PasteEdits, pasteEdits, + PasteEditsArgs, Path, positionIsSynthesized, PossibleProgramFileInfo, @@ -2094,19 +2095,17 @@ export function createLanguageService( } function getPasteEdits( - targetFile: string, - copies: { text: string; copyRange?: { file: string; range: TextRange; }; }[], - pastes: TextRange[], - preferences: UserPreferences, + args: PasteEditsArgs, formatOptions: FormatCodeSettings, ): PasteEdits { synchronizeHostData(); return pasteEdits.pasteEditsProvider( - getValidSourceFile(targetFile), - copies.map(({ text, copyRange }) => ({ text, copyRange: copyRange ? { file: getValidSourceFile(copyRange.file), range: copyRange.range } : undefined })), - pastes, + getValidSourceFile(args.targetFile), + args.pastedText, + args.pasteLocations, + args.copiedFrom ? { file: getValidSourceFile(args.copiedFrom.file), range: args.copiedFrom.range } : undefined, host, - preferences, + args.preferences, formatting.getFormatContext(formatOptions, host), cancellationToken, ); diff --git a/src/services/types.ts b/src/services/types.ts index 091095c79449a..b4d4679131c46 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -685,10 +685,7 @@ export interface LanguageService { dispose(): void; getPasteEdits( - targetFile: string, - copies: { text: string; range?: { file: string; range: TextRange; }; }[], - pastes: TextRange[], - preferences: UserPreferences, + args: PasteEditsArgs, formatOptions: FormatCodeSettings, ): PasteEdits; } @@ -715,6 +712,15 @@ export const enum OrganizeImportsMode { export interface PasteEdits { edits: readonly FileTextChanges[]; + fixId?: {}; +} + +export interface PasteEditsArgs { + targetFile: string; + pastedText: string[]; + pasteLocations: TextRange[]; + copiedFrom: { file: string; range: TextRange[]; } | undefined; + preferences: UserPreferences; } export interface OrganizeImportsArgs extends CombinedCodeFixScope { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index e476ceb506cf0..88049fca3b5d4 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1,13 +1,9 @@ -import { - getModuleSpecifier, -} from "../compiler/_namespaces/ts.moduleSpecifiers"; import { __String, addEmitFlags, addSyntheticLeadingComment, addSyntheticTrailingComment, AnyImportOrRequireStatement, - append, assertType, AssignmentDeclarationKind, BinaryExpression, @@ -382,17 +378,6 @@ import { walkUpParenthesizedExpressions, YieldExpression, } from "./_namespaces/ts"; -import { - addExportToChanges, - filterImport, - forEachImportInStatement, - getTopLevelDeclarationStatement, - isTopLevelDeclaration, - makeImportOrRequire, - moduleSpecifierFromImport, - nameOfTopLevelDeclaration, -} from "./_namespaces/ts.refactor"; - // These utilities are common to multiple language service features. // #region /** @internal */ @@ -4302,93 +4287,3 @@ export function isBlockLike(node: Node): node is BlockLike { return false; } } - -/** @internal */ -export function getTargetFileImportsAndAddExportInOldFile( - oldFile: SourceFile, - targetFile: string, - importsToCopy: Map, - targetFileImportsFromOldFile: Set, - changes: textChanges.ChangeTracker, - checker: TypeChecker, - program: Program, - host: LanguageServiceHost, - useEsModuleSyntax: boolean, - quotePreference: QuotePreference, - importAdder?: codefix.ImportAdder, -): readonly AnyImportOrRequireStatement[] { - const copiedOldImports: AnyImportOrRequireStatement[] = []; - /** - * Recomputing the imports is preferred with importAdder because it manages multiple import additions for a file and writes then to a ChangeTracker, - * but sometimes it fails because of unresolved imports from files, or when a source file is not available for the target file (in this case when creating a new file). - * So in that case, fall back to copying the import verbatim. - */ - if (importAdder) { - importsToCopy.forEach((isValidTypeOnlyUseSite, symbol) => { - try { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker), isValidTypeOnlyUseSite); - } - catch { - for (const oldStatement of oldFile.statements) { - forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - }); - } - } - }); - } - else { - const targetSourceFile = program.getSourceFile(targetFile); // Would be undefined for a new file - for (const oldStatement of oldFile.statements) { - forEachImportInStatement(oldStatement, i => { - // Recomputing module specifier - const moduleSpecifier = moduleSpecifierFromImport(i); - const compilerOptions = program.getCompilerOptions(); - const resolved = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier); - const fileName = resolved?.resolvedModule?.resolvedFileName; - if (fileName && targetSourceFile) { - const newModuleSpecifier = getModuleSpecifier(compilerOptions, targetSourceFile, targetSourceFile.fileName, fileName, createModuleSpecifierResolutionHost(program, host)); - append(copiedOldImports, filterImport(i, makeStringLiteral(newModuleSpecifier, quotePreference), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - } - else { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - } - }); - } - } - - // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. - const targetFileSourceFile = program.getSourceFile(targetFile); - let oldFileDefault: Identifier | undefined; - const oldFileNamedImports: string[] = []; - const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. - targetFileImportsFromOldFile.forEach(symbol => { - if (!symbol.declarations) { - return; - } - for (const decl of symbol.declarations) { - if (!isTopLevelDeclaration(decl)) continue; - const name = nameOfTopLevelDeclaration(decl); - if (!name) continue; - - const top = getTopLevelDeclarationStatement(decl); - if (markSeenTop(top)) { - addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); - } - if (importAdder && checker.isUnknownSymbol(symbol)) { - importAdder.addImportFromExportedSymbol(skipAlias(symbol, checker)); - } - else { - if (hasSyntacticModifier(decl, ModifierFlags.Default)) { - oldFileDefault = name; - } - else { - oldFileNamedImports.push(name.text); - } - } - } - }); - return targetFileSourceFile - ? append(copiedOldImports, makeImportOrRequire(targetFileSourceFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)) - : append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); -} diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js index 181913b06c978..12d3801164a0d 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js @@ -226,12 +226,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "const m = t3 + t2 + 1;" - } + "pastedText": [ + "const m = t3 + t2 + 1;" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 4, @@ -244,7 +242,7 @@ Info seq [hh:mm:ss:mss] request: } ] }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -263,7 +261,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -298,7 +296,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js index 749a48cb8e5fa..051b6b755c0b0 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -245,23 +245,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "const m = t3 + t2 + n;", - "range": { - "file": "originalFile.ts", - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 30 - } - } - } + "pastedText": [ + "const m = t3 + t2 + n;" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 4, @@ -272,9 +259,24 @@ Info seq [hh:mm:ss:mss] request: "offset": 14 } } - ] + ], + "copiedFrom": { + "file": "originalFile.ts", + "range": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 30 + } + } + ] + } }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -296,7 +298,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -342,7 +344,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js index 6e21e418043f0..9847220a29b83 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -212,23 +212,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "const c = a + b;\nconst t = 9;", - "range": { - "file": "file2.ts", - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 4, - "offset": 13 - } - } - } + "pastedText": [ + "const c = a + b;\nconst t = 9;" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 2, @@ -239,9 +226,24 @@ Info seq [hh:mm:ss:mss] request: "offset": 14 } } - ] + ], + "copiedFrom": { + "file": "file2.ts", + "range": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 13 + } + } + ] + } }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -261,7 +263,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -323,7 +325,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js index 98693518a9dc7..178339c47b643 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js @@ -213,12 +213,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "const g = p + q;\nfunction e();\nconst f = r + s;" - } + "pastedText": [ + "const g = p + q;\nfunction e();\nconst f = r + s;" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 2, @@ -241,7 +239,7 @@ Info seq [hh:mm:ss:mss] request: } ] }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -251,7 +249,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" - /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\nundefined\nconst d = 4;" /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" Info seq [hh:mm:ss:mss] ----------------------------------------------- @@ -259,7 +257,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -305,7 +303,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js index e5c5c48a18f0d..8e858f2b4b268 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -216,23 +216,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "export const t = aa + bb + r + s;\nconst u = 1;", - "range": { - "file": "file1.ts", - "start": { - "line": 4, - "offset": 1 - }, - "end": { - "line": 5, - "offset": 13 - } - } - } + "pastedText": [ + "export const t = aa + bb + r + s;\nconst u = 1;" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 2, @@ -253,9 +240,24 @@ Info seq [hh:mm:ss:mss] request: "offset": 1 } } - ] + ], + "copiedFrom": { + "file": "file1.ts", + "range": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 13 + } + } + ] + } }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -266,7 +268,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\n\nconst d = 4;" + /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nundefined\nconst d = 4;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results @@ -276,7 +278,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -333,7 +335,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js new file mode 100644 index 0000000000000..d93cda234b457 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js @@ -0,0 +1,416 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +import { aa, bb } from "./other"; +export const r = 10; +const s = 12; +export const m = 10; +export const t = aa + bb + r + s; +const u = 1; +export const k = r + m; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/other.ts] +export const aa = 1; +export const bb = 2; + +//// [/target.ts] +import { r } from "./file1"; +const a = r; +const b = 2; +const c = 3; + +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "other.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] Search path: / +Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/other.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /other.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nconst s = 12;\nexport const m = 10;\nexport const t = aa + bb + r + s;\nconst u = 1;\nexport const k = r + m;" + /target.ts SVC-1-0 "import { r } from \"./file1\";\nconst a = r;\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + other.ts + Imported via "./other" from file 'file1.ts' + Part of 'files' list in tsconfig.json + file1.ts + Part of 'files' list in tsconfig.json + Imported via "./file1" from file 'target.ts' + target.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/other.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastedText": [ + "export const t = aa + bb + r + s;\nconst u = 1;", + "export const k = r + m;" + ], + "pasteLocations": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 13 + } + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + } + } + ], + "copiedFrom": { + "file": "file1.ts", + "range": [ + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 6, + "offset": 13 + } + }, + { + "start": { + "line": 7, + "offset": 1 + }, + "end": { + "line": 7, + "offset": 24 + } + } + ] + } + }, + "command": "getPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" + /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nconst s = 12;\nexport const m = 10;\nexport const t = aa + bb + r + s;\nconst u = 1;\nexport const k = r + m;" + /target.ts SVC-1-1 "import { r } from \"./file1\";\nconst a = r;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nexport const k = r + m;\nconst d = 4;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/file1.ts", + "textChanges": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "export " + } + ] + }, + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 10 + }, + "end": { + "line": 1, + "offset": 10 + }, + "newText": "m, " + }, + { + "start": { + "line": 1, + "offset": 11 + }, + "end": { + "line": 1, + "offset": 11 + }, + "newText": ", s" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "import { aa, bb } from \"./other\";\n" + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 13 + }, + "newText": "export const t = aa + bb + r + s;\nconst u = 1;" + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + }, + "newText": "export const k = r + m;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/other.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js index 2b380b61b03b8..6ce33e724cefa 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js @@ -180,12 +180,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" - } + "pastedText": [ + "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 2, @@ -198,7 +196,7 @@ Info seq [hh:mm:ss:mss] request: } ] }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -214,7 +212,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -238,7 +236,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js index b988efc6cebdd..76d66bb15bd27 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -212,12 +212,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/target.ts", - "copies": [ - { - "text": "const m = t2 + 1;" - } + "pastedText": [ + "const m = t2 + 1;" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 3, @@ -230,7 +228,7 @@ Info seq [hh:mm:ss:mss] request: } ] }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -248,7 +246,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -283,7 +281,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js index 66066479e313e..9d7878227fd8c 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js @@ -197,12 +197,10 @@ Info seq [hh:mm:ss:mss] request: "type": "request", "arguments": { "file": "/file2.ts", - "copies": [ - { - "text": "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" - } + "pastedText": [ + "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" ], - "pastes": [ + "pasteLocations": [ { "start": { "line": 3, @@ -215,7 +213,7 @@ Info seq [hh:mm:ss:mss] request: } ] }, - "command": "GetPasteEdits" + "command": "getPasteEdits" } Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms @@ -232,7 +230,7 @@ Info seq [hh:mm:ss:mss] response: { "seq": 0, "type": "response", - "command": "GetPasteEdits", + "command": "getPasteEdits", "request_seq": 2, "success": true, "performanceData": { @@ -267,7 +265,8 @@ Info seq [hh:mm:ss:mss] response: } ] } - ] + ], + "fixId": "providePostPasteEdits" } } After Request diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts index 545c02f28b99d..ba27ed2df0005 100644 --- a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts @@ -22,8 +22,10 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ - copies: [{ text: `const m = t3 + t2 + 1;`}], - pastes: [{ pos: range[0].pos, end: range[0].end }], + args: { + pastedText: [ `const m = t3 + t2 + 1;`], + pasteLocations: [{ pos: range[0].pos, end: range[0].end }], + }, newFileContents: { "/target.ts": `import { t } from "./other"; @@ -32,5 +34,6 @@ import { t3 } from "./other3"; const a = t + 1; const m = t3 + t2 + 1; const c = 10;` - } + }, + fixId: "providePostPasteEdits" }); diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports2.ts b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts index a453c1af7a089..593da2488c912 100644 --- a/tests/cases/fourslash/server/pasteEdits_existingImports2.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts @@ -27,9 +27,12 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.pasteEdits({ - copies: [{ text: `const m = t3 + t2 + n;`, copyRange: { file: "originalFile.ts", range: range[1]}}], - pastes: [range[0]], +verify.pasteEdits({ + args: { + pastedText: [ `const m = t3 + t2 + n;` ], + pasteLocations: [range[0]], + copiedFrom: { file: "originalFile.ts", range: [range[1]] }, + }, newFileContents: { "/target.ts": `import { n } from "./originalFile"; @@ -39,5 +42,6 @@ import { t3 } from "./other3"; const a = t + 1; const m = t3 + t2 + n; const c = 10;` - } + }, + fixId: "providePostPasteEdits" }); diff --git a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts index 7abb513ab174f..8d51bf688fc56 100644 --- a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts @@ -20,13 +20,13 @@ const range = test.ranges(); const t = range[0]; format.setOption("insertSpaceAfterSemicolonInForStatements", true); -verify.pasteEdits({ - copies: [{ - text: `const c = a + b; -const t = 9;`, - copyRange: { file: "file2.ts", range: range[1]} - }], - pastes: [range[0]], +verify.pasteEdits({ + args: { + pastedText: [ `const c = a + b; +const t = 9;`], + pasteLocations: [range[0]], + copiedFrom: { file: "file2.ts", range: [range[1]] }, + }, newFileContents: { "/file2.ts": `import { b } from './file1'; @@ -43,5 +43,6 @@ export const tt = 2; const c = a + b; const t = 9; const p = 1;`, - } + }, + fixId: "providePostPasteEdits" }); diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts index c21f07aebe495..626e91f1d59fc 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts @@ -22,12 +22,12 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ - copies: [{ - text: `const g = p + q; + args: { + pastedText: [ `const g = p + q; function e(); -const f = r + s;`, - }], - pastes: [range[0], range[1]], +const f = r + s;`], + pasteLocations: [range[0], range[1]], + }, newFileContents: { "/target.ts": `import { p, q } from "./file1"; @@ -43,5 +43,6 @@ const g = p + q; function e(); const f = r + s; const d = 4;` - } + }, + fixId: "providePostPasteEdits" }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts index 65f53d04c58f4..3659cd20d895a 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -24,12 +24,12 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ - copies: [{ - text: `export const t = aa + bb + r + s; -const u = 1;`, - copyRange: { file: "file1.ts", range: range[2]} - }], - pastes: [range[0], range[1]], + args: { + pastedText: [ `export const t = aa + bb + r + s; +const u = 1;`,], + pasteLocations: [range[0], range[1]], + copiedFrom: { file: "file1.ts", range: [range[2]] }, + }, newFileContents: { "/target.ts": `import { r, s } from "./file1"; diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts new file mode 100644 index 0000000000000..f37736393a91e --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts @@ -0,0 +1,55 @@ +/// + +// @Filename: /target.ts +//// import { r } from "./file1"; +//// const a = r; +//// [|const b = 2;|] +//// const c = 3; +//// [||] +//// const d = 4; + +// @Filename: /file1.ts +//// import { aa, bb } from "./other"; +//// export const r = 10; +//// const s = 12; +//// export const m = 10; +//// [|export const t = aa + bb + r + s; +//// const u = 1;|] +//// [|export const k = r + m;|] + +// @Filename: /other.ts +//// export const aa = 1; +//// export const bb = 2; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "target.ts", "other.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.pasteEdits({ + args: { + pastedText: [ `export const t = aa + bb + r + s; +const u = 1;`, `export const k = r + m;`], + pasteLocations: [range[0], range[1]], + copiedFrom: { file: "file1.ts", range: [range[2], range[3]] }, + }, + newFileContents: { + "/file1.ts":`import { aa, bb } from "./other"; +export const r = 10; +export const s = 12; +export const m = 10; +export const t = aa + bb + r + s; +const u = 1; +export const k = r + m;`, + "/target.ts": +`import { m, r, s } from "./file1"; +import { aa, bb } from "./other"; +const a = r; +export const t = aa + bb + r + s; +const u = 1; +const c = 3; +export const k = r + m; +const d = 4;` + }, + fixId: "providePostPasteEdits" +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts index 16397b0c23f17..3a7ee389bcfcc 100644 --- a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts +++ b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts @@ -11,15 +11,15 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ - copies: [{ - text: `/** + args: { + pastedText: [ `/** * Testing comment line 1 * line 2 * line 3 * line 4 -*/` - }], - pastes: [range[0]], +*/`], + pasteLocations: [range[0]], + }, newFileContents: { "/target.ts": `const a = 10; @@ -30,5 +30,6 @@ const b = 10;/** * line 4 */ const c = 10;` - } + }, + fixId: "providePostPasteEdits" }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts index dddcf842c5003..4e741b76d677b 100644 --- a/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts @@ -20,8 +20,10 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ - copies: [{ text: `const m = t2 + 1;`}], - pastes: [{ pos: range[0].pos, end: range[0].end }], + args: { + pastedText: [ `const m = t2 + 1;`], + pasteLocations: [{ pos: range[0].pos, end: range[0].end }], + }, newFileContents: { "/target.ts": `import { t } from "./other"; @@ -31,7 +33,8 @@ const m = t2 + 1; type T = number; var x; var y = x as ` - } + }, + fixId: "providePostPasteEdits" }); verify.completions({ marker: "1", includes: "T" }); diff --git a/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts index 54288bf9af78b..486d945a786aa 100644 --- a/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts @@ -17,15 +17,15 @@ const range = test.ranges(); format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ - copies: [{ - text: `interface Testing { + args: { + pastedText: [ `interface Testing { test1: Test1; test2: Test2; test3: Test3; test4: Test4; - }`, - }], - pastes: [range[0]], + }`], + pasteLocations: [range[0]], + }, newFileContents: { "/file2.ts": `import { Test1, Test2, Test3, Test4 } from "./file1"; @@ -38,5 +38,6 @@ interface Testing { test3: Test3; test4: Test4; }const c = 10;` - } + }, + fixId: "providePostPasteEdits" }); \ No newline at end of file From f302b65eaae053aee2dd2daabba01264405142c8 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 19 Mar 2024 14:58:43 -0700 Subject: [PATCH 23/41] missed change for fourslash tests --- tests/cases/fourslash/fourslash.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index beb9e92367b37..253d5ee200bf5 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -446,8 +446,12 @@ declare namespace FourSlashInterface { uncommentSelection(newFileContent: string): void; pasteEdits(options: { newFileContents: { readonly [fileName: string]: string }; - copies: { text: string; copyRange?: { file: string; range: { pos: number, end: number };} }[], - pastes: { pos: number, end: number }[], + args: { + pastedText: string[]; + pasteLocations: { pos: number, end: number }[]; + copiedFrom?: { file: string, range: { pos: number, end: number }[] }; + } + fixId?: string; }): void; } class edit { From 7027ea31d1b5911fd46e8ea4f4c33fe87ed24611 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 19 Mar 2024 14:59:24 -0700 Subject: [PATCH 24/41] changes to avoid duplicated imports for symbols that are added to existing import statements --- src/services/codefixes/importFixes.ts | 86 ++++++++++++++++--- src/services/codefixes/inferFromUsage.ts | 2 +- src/services/exportInfoMap.ts | 8 ++ src/services/refactors/moveToFile.ts | 27 +++++- .../fourslash/moveToFile_existingImports1.ts | 26 ++++-- .../fourslash/moveToFile_existingImports2.ts | 8 +- 6 files changed, 128 insertions(+), 29 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index b70de03519bc8..71ed254e624f8 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -131,6 +131,7 @@ import { SymbolExportInfo, SymbolFlags, SymbolId, + SymbolInfo, SyntaxKind, textChanges, toPath, @@ -207,7 +208,7 @@ registerCodeFix({ export interface ImportAdder { hasFixes(): boolean; addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void; - addImportFromExportedSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) => void; + addImportFromSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string) => void; addImportForUnresolvedIdentifier: (context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) => void; writeFixes: (changeTracker: textChanges.ChangeTracker, oldFileQuotePreference?: QuotePreference) => void; } @@ -234,9 +235,9 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu type NewImportsKey = `${0 | 1}|${string}`; /** Use `getNewImportEntry` for access */ const newImports = new Map>(); - return { addImportFromDiagnostic, addImportFromExportedSymbol, writeFixes, hasFixes, addImportForUnresolvedIdentifier: addImportsForUnknownSymbols }; + return { addImportFromDiagnostic, addImportFromSymbol, writeFixes, hasFixes, addImportForUnresolvedIdentifier }; - function addImportsForUnknownSymbols(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) { + function addImportForUnresolvedIdentifier(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) { const info = getFixInfosWithoutDiagnostic(context, symbolToken, useAutoImportProvider); if (!info || !info.length) return; addImport(first(info)); @@ -248,16 +249,24 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu addImport(first(info)); } - function addImportFromExportedSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean) { - const moduleSymbol = Debug.checkDefined(exportedSymbol.parent); - const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions)); - const checker = program.getTypeChecker(); - const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker)); - const exportInfo = getAllExportInfoForSymbol(sourceFile, symbol, symbolName, moduleSymbol, /*preferCapitalized*/ false, program, host, preferences, cancellationToken); - const useRequire = shouldUseRequire(sourceFile, program); - const fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences); - if (fix) { - addImport({ fix, symbolName, errorIdentifierText: undefined }); + function addImportFromSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string) { + if (!exportedSymbol.parent && targetFilePath) { + const fix = getImportFixForNonEportedSymbol(sourceFile, exportedSymbol, ImportKind.Named, program, !!isValidTypeOnlyUseSite, targetFilePath); + if (fix?.kind === ImportFixKind.AddToExisting) { + addImport({ fix, symbolName: exportedSymbol.name, errorIdentifierText: undefined }); + } + } + else { + const moduleSymbol = Debug.checkDefined(exportedSymbol.parent); + const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions)); + const checker = program.getTypeChecker(); + const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker)); + const exportInfo = getAllExportInfoForSymbol(sourceFile, symbol, symbolName, moduleSymbol, /*preferCapitalized*/ false, program, host, preferences, cancellationToken); + const useRequire = shouldUseRequire(sourceFile, program); + const fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences); + if (fix) { + addImport({ fix, symbolName, errorIdentifierText: undefined }); + } } } @@ -595,6 +604,14 @@ function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly Sym return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host); } +function getImportFixForNonEportedSymbol(sourceFile: SourceFile, symbol: Symbol, importKind: ImportKind, program: Program, isValidTypeOnlyUseSite: boolean, targetFilePath: string) { + const fix = getImportFixesForNonExportedSymbols(sourceFile, symbol, importKind, program, isValidTypeOnlyUseSite, targetFilePath); + if (fix.fixes[0] === undefined) return; // Not adding an import to an existing import + if (fix.fixes[0].kind === ImportFixKind.AddToExisting) { + return fix.fixes[0]; + } +} + function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction { return { description, changes, commands }; } @@ -630,6 +647,30 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } } +export function getImportFixesForNonExportedSymbols( + sourceFile: SourceFile, + symbol: Symbol, + importKind: ImportKind, + program: Program, + isValidTypeOnlyUseSite: boolean, + targetFilePath: string, + importMap = createExistingImportMap(program.getTypeChecker(), sourceFile, program.getCompilerOptions()), +): { computedWithoutCacheCount: number; fixes: readonly ImportFixWithModuleSpecifier[]; } { + const checker = program.getTypeChecker(); + const symbolInfo = [{ + symbol, + targetFlags: SymbolFlags.Value, + importKind, + targetFilePath, + }]; + const existingImports = flatMap(symbolInfo, importMap.getImportsForNonExportedSymbols); + const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions()); + return { + computedWithoutCacheCount: 0, + fixes: [addToExisting!], + }; +} + function getImportFixes( exportInfos: readonly SymbolExportInfo[], usagePosition: number | undefined, @@ -830,6 +871,23 @@ function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile const importKind = getImportKind(importingFile, exportKind, compilerOptions); return matchingDeclarations.map(declaration => ({ declaration, importKind, symbol, targetFlags })); }, + getImportsForNonExportedSymbols: ({ symbol, importKind, targetFlags, targetFilePath }: SymbolInfo): readonly FixAddToExistingImportInfo[] => { + let fix: FixAddToExistingImportInfo[] = []; + const values = importMap?.values(); + Debug.assertIsDefined(values); + for (const value of values) { + value.forEach(v => { + if (v.kind === SyntaxKind.ImportDeclaration && cast(v.moduleSpecifier, isStringLiteral).text === targetFilePath) { + fix = [{ declaration: v, importKind, targetFlags, symbol }]; + return fix; + } + else { + return emptyArray; + } + }); + } + return fix; + }, }; } @@ -1473,7 +1531,7 @@ function promoteFromTypeOnly( } } -function doAddExistingFix( +export function doAddExistingFix( changes: textChanges.ChangeTracker, sourceFile: SourceFile, clause: ImportClause | ObjectBindingPattern, diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 95a19e1d39638..3d2513875b21d 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -439,7 +439,7 @@ function tryReplaceImportTypeNodeWithAutoImport( ): boolean { const importableReference = tryGetAutoImportableReferenceFromTypeNode(typeNode, scriptTarget); if (importableReference && changes.tryInsertTypeAnnotation(sourceFile, declaration, importableReference.typeNode)) { - forEach(importableReference.symbols, s => importAdder.addImportFromExportedSymbol(s, /*isValidTypeOnlyUseSite*/ true)); + forEach(importableReference.symbols, s => importAdder.addImportFromSymbol(s, /*isValidTypeOnlyUseSite*/ true)); return true; } return false; diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 322631ad92c31..9a17bc2ebc797 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -90,6 +90,14 @@ export interface SymbolExportInfo { isFromPackageJson: boolean; } +/** @internal */ +export interface SymbolInfo { + readonly symbol: Symbol; + importKind: ImportKind; + targetFlags: SymbolFlags; + targetFilePath: string; +} + interface CachedSymbolExportInfo { // Used to rehydrate `symbol` and `moduleSymbol` when transient id: number; diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 36c41a67312bb..1f01d9044ea72 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -58,7 +58,6 @@ import { getRelativePathFromFile, getSourceFileOfNode, getSynthesizedDeepClone, - getTargetFileImportsAndAddExportInOldFile, getTokenAtPosition, getUniqueName, hasJSFileExtension, @@ -151,6 +150,9 @@ import { import { registerRefactor, } from "../refactorProvider"; +import { + getTargetFileImportsAndAddExportInOldFile, +} from "./helpers"; const refactorNameForMoveToFile = "Move to file"; const description = getLocaleSpecificMessage(Diagnostics.Move_to_file); @@ -490,13 +492,34 @@ export function makeImportOrRequire( host: LanguageServiceHost, useEs6Imports: boolean, quotePreference: QuotePreference, + unexportedSymbols?: Symbol[], + importAdder?: codefix.ImportAdder, ): AnyImportOrRequireStatement | undefined { const pathToTargetFile = resolvePath(getDirectoryPath(sourceFile.path), targetFileNameWithExtension); const pathToTargetFileWithCorrectExtension = getModuleSpecifier(program.getCompilerOptions(), sourceFile, sourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)); if (useEs6Imports) { const specifiers = imports.map(i => factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, factory.createIdentifier(i))); - return makeImportIfNecessary(defaultImport, specifiers, pathToTargetFileWithCorrectExtension, quotePreference); + const newImports = makeImportIfNecessary(defaultImport, specifiers, pathToTargetFileWithCorrectExtension, quotePreference); + // To check if we need to add imports to an existing import statement in the target file + let addToExistingImports = false; + for (const statement of sourceFile.statements) { + forEachImportInStatement(statement, i => { + if (moduleSpecifierFromImport(i).text === pathToTargetFileWithCorrectExtension) { + addToExistingImports = true; + } + }); + } + if (addToExistingImports && importAdder && !defaultImport && unexportedSymbols) { + for (const symbol of unexportedSymbols) { + if (newImports && importAdder) { + importAdder.addImportFromSymbol(symbol, /*isValidTypeOnlyUseSite*/ false, pathToTargetFileWithCorrectExtension); + } + } + } + else { + return newImports; + } } else { Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. diff --git a/tests/cases/fourslash/moveToFile_existingImports1.ts b/tests/cases/fourslash/moveToFile_existingImports1.ts index f7f5feaf54e8c..b75549b94a2ed 100644 --- a/tests/cases/fourslash/moveToFile_existingImports1.ts +++ b/tests/cases/fourslash/moveToFile_existingImports1.ts @@ -2,22 +2,32 @@ // @filename: /common.ts ////export const x = 1; +////export const y = 2; // @filename: /a.ts -////import { x } from "./common"; -////[|export const bar = x;|] +////export const t = 1; +////export const z = 2; +////const x = 3; +////export const q = 0; +////[|export const bar = z + x + q;|] // @filename: /b.ts -////import { x } from "./common"; -////export const foo = x; +////import { t, z } from "./a"; +////import { y } from "./common"; +////export const foo = t; verify.moveToFile({ newFileContents: { - "/a.ts": "", + "/a.ts": `export const t = 1; +export const z = 2; +export const x = 3; +export const q = 0; +`, "/b.ts": -`import { x } from "./common"; -export const foo = x; -export const bar = x; +`import { q, t, x, z } from "./a"; +import { y } from "./common"; +export const foo = t; +export const bar = z + x + q; `, }, interactiveRefactorArguments: { targetFile: "/b.ts" }, diff --git a/tests/cases/fourslash/moveToFile_existingImports2.ts b/tests/cases/fourslash/moveToFile_existingImports2.ts index a93b542b59daf..fce4f8f337010 100644 --- a/tests/cases/fourslash/moveToFile_existingImports2.ts +++ b/tests/cases/fourslash/moveToFile_existingImports2.ts @@ -9,8 +9,8 @@ ////[|export const b = x;|] // @filename: /b.ts -////import { x } from "./common"; -////export const a = x; +////import { y } from "./common"; +////export const a = y; verify.moveToFile({ newFileContents: { @@ -19,8 +19,8 @@ verify.moveToFile({ export const a = x; `, "/b.ts": -`import { x } from "./common"; -export const a = x; +`import { x, y } from "./common"; +export const a = y; export const b = x; `, }, From 8e486d6dac507bcdfdf8bbc53ff2f051953b5d25 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 19 Mar 2024 22:44:27 -0700 Subject: [PATCH 25/41] fixing tests --- src/services/codefixes/importFixes.ts | 4 +- tests/baselines/reference/api/typescript.d.ts | 39 ++++++++++--------- .../moveToFile_emptyTargetFile.js | 20 +++++----- .../pasteEdits_revertUpdatedFile.js | 28 ++++++------- ...-file'-and-'move-to-new-file'-refactors.js | 20 +++++----- .../server/pasteEdits_multiplePastes2.ts | 1 + 6 files changed, 57 insertions(+), 55 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 8a17cc80ad107..001948b1b5f56 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -647,7 +647,7 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } } -export function getImportFixesForNonExportedSymbols( +function getImportFixesForNonExportedSymbols( sourceFile: SourceFile, symbol: Symbol, importKind: ImportKind, @@ -1531,7 +1531,7 @@ function promoteFromTypeOnly( } } -export function doAddExistingFix( +function doAddExistingFix( changes: textChanges.ChangeTracker, sourceFile: SourceFile, clause: ImportClause | ObjectBindingPattern, diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 74633207e4f4d..b1ee09b41a71a 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -99,7 +99,7 @@ declare namespace ts { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", - GetPasteEdits = "GetPasteEdits", + GetPasteEdits = "getPasteEdits", OrganizeImports = "organizeImports", GetEditsForFileRename = "getEditsForFileRename", ConfigurePlugin = "configurePlugin", @@ -478,17 +478,19 @@ declare namespace ts { arguments: GetPasteEditsRequestArgs; } export type GetPasteEditsRequestArgs = FileRequestArgs & { - copies: { - text: string; - range?: FileSpan; - }[]; - pastes: TextSpan[]; + pastedText: string[]; + pasteLocations: TextSpan[]; + copiedFrom?: { + file: string; + range: TextSpan[]; + }; }; export interface GetPasteEditsResponse extends Response { body: PasteEditsAction; } export interface PasteEditsAction { edits: FileCodeEdits[]; + fixId?: {}; } export interface GetEditsForRefactorRequest extends Request { command: CommandTypes.GetEditsForRefactor; @@ -10103,19 +10105,7 @@ declare namespace ts { uncommentSelection(fileName: string, textRange: TextRange): TextChange[]; getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; - getPasteEdits( - targetFile: string, - copies: { - text: string; - range?: { - file: string; - range: TextRange; - }; - }[], - pastes: TextRange[], - preferences: UserPreferences, - formatOptions: FormatCodeSettings, - ): PasteEdits; + getPasteEdits(args: PasteEditsArgs, formatOptions: FormatCodeSettings): PasteEdits; } interface JsxClosingTagInfo { readonly newText: string; @@ -10135,6 +10125,17 @@ declare namespace ts { } interface PasteEdits { edits: readonly FileTextChanges[]; + fixId?: {}; + } + interface PasteEditsArgs { + targetFile: string; + pastedText: string[]; + pasteLocations: TextRange[]; + copiedFrom: { + file: string; + range: TextRange[]; + } | undefined; + preferences: UserPreferences; } interface OrganizeImportsArgs extends CombinedCodeFixScope { /** @deprecated Use `mode` instead */ diff --git a/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js b/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js index 5414c78b40e24..73f4d8a932124 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js @@ -242,13 +242,13 @@ Info seq [hh:mm:ss:mss] response: ] }, { - "name": "Move to a new file", - "description": "Move to a new file", + "name": "Move to file", + "description": "Move to file", "actions": [ { - "name": "Move to a new file", - "description": "Move to a new file", - "kind": "refactor.move.newFile", + "name": "Move to file", + "description": "Move to file", + "kind": "refactor.move.file", "range": { "start": { "line": 1, @@ -263,13 +263,13 @@ Info seq [hh:mm:ss:mss] response: ] }, { - "name": "Move to file", - "description": "Move to file", + "name": "Move to a new file", + "description": "Move to a new file", "actions": [ { - "name": "Move to file", - "description": "Move to file", - "kind": "refactor.move.file", + "name": "Move to a new file", + "description": "Move to a new file", + "kind": "refactor.move.newFile", "range": { "start": { "line": 1, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js index 76d66bb15bd27..c29836d733319 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -729,37 +729,37 @@ Info seq [hh:mm:ss:mss] response: "sortText": "15" }, { - "name": "Int16Array", + "name": "Int8Array", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Int16ArrayConstructor", + "name": "Int8ArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Int32Array", + "name": "Int16Array", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Int32ArrayConstructor", + "name": "Int16ArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Int8Array", + "name": "Int32Array", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Int8ArrayConstructor", + "name": "Int32ArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" @@ -1119,49 +1119,49 @@ Info seq [hh:mm:ss:mss] response: "sortText": "15" }, { - "name": "Uint16Array", + "name": "Uint8Array", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint16ArrayConstructor", + "name": "Uint8ArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint32Array", + "name": "Uint8ClampedArray", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint32ArrayConstructor", + "name": "Uint8ClampedArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint8Array", + "name": "Uint16Array", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint8ArrayConstructor", + "name": "Uint16ArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint8ClampedArray", + "name": "Uint32Array", "kind": "var", "kindModifiers": "declare", "sortText": "15" }, { - "name": "Uint8ClampedArrayConstructor", + "name": "Uint32ArrayConstructor", "kind": "interface", "kindModifiers": "declare", "sortText": "15" diff --git a/tests/baselines/reference/tsserver/getApplicableRefactors/returns-the-affected-range-of-text-for-'move-to-file'-and-'move-to-new-file'-refactors.js b/tests/baselines/reference/tsserver/getApplicableRefactors/returns-the-affected-range-of-text-for-'move-to-file'-and-'move-to-new-file'-refactors.js index 963e2a025f6b4..54e72634da781 100644 --- a/tests/baselines/reference/tsserver/getApplicableRefactors/returns-the-affected-range-of-text-for-'move-to-file'-and-'move-to-new-file'-refactors.js +++ b/tests/baselines/reference/tsserver/getApplicableRefactors/returns-the-affected-range-of-text-for-'move-to-file'-and-'move-to-new-file'-refactors.js @@ -108,13 +108,13 @@ Info seq [hh:mm:ss:mss] response: { "response": [ { - "name": "Move to a new file", - "description": "Move to a new file", + "name": "Move to file", + "description": "Move to file", "actions": [ { - "name": "Move to a new file", - "description": "Move to a new file", - "kind": "refactor.move.newFile", + "name": "Move to file", + "description": "Move to file", + "kind": "refactor.move.file", "range": { "start": { "line": 1, @@ -129,13 +129,13 @@ Info seq [hh:mm:ss:mss] response: ] }, { - "name": "Move to file", - "description": "Move to file", + "name": "Move to a new file", + "description": "Move to a new file", "actions": [ { - "name": "Move to file", - "description": "Move to file", - "kind": "refactor.move.file", + "name": "Move to a new file", + "description": "Move to a new file", + "kind": "refactor.move.newFile", "range": { "start": { "line": 1, diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts index 3659cd20d895a..9a6c08f8cc0cf 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -44,4 +44,5 @@ export const t = aa + bb + r + s; const u = 1; const d = 4;` }, + fixId: "providePostPasteEdits" }); \ No newline at end of file From 835acdacd679c7b817a2bd8c36f1dfa9d2566680 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Wed, 20 Mar 2024 09:25:43 -0700 Subject: [PATCH 26/41] small fixes --- src/services/codefixes/importFixes.ts | 4 ++-- tests/cases/fourslash/moveToFile_existingImports2.ts | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 001948b1b5f56..89bca3e3ea405 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -251,7 +251,7 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu function addImportFromSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string) { if (!exportedSymbol.parent && targetFilePath) { - const fix = getImportFixForNonEportedSymbol(sourceFile, exportedSymbol, ImportKind.Named, program, !!isValidTypeOnlyUseSite, targetFilePath); + const fix = getImportFixForNonExportedSymbol(sourceFile, exportedSymbol, ImportKind.Named, program, !!isValidTypeOnlyUseSite, targetFilePath); if (fix?.kind === ImportFixKind.AddToExisting) { addImport({ fix, symbolName: exportedSymbol.name, errorIdentifierText: undefined }); } @@ -604,7 +604,7 @@ function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly Sym return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host); } -function getImportFixForNonEportedSymbol(sourceFile: SourceFile, symbol: Symbol, importKind: ImportKind, program: Program, isValidTypeOnlyUseSite: boolean, targetFilePath: string) { +function getImportFixForNonExportedSymbol(sourceFile: SourceFile, symbol: Symbol, importKind: ImportKind, program: Program, isValidTypeOnlyUseSite: boolean, targetFilePath: string) { const fix = getImportFixesForNonExportedSymbols(sourceFile, symbol, importKind, program, isValidTypeOnlyUseSite, targetFilePath); if (fix.fixes[0] === undefined) return; // Not adding an import to an existing import if (fix.fixes[0].kind === ImportFixKind.AddToExisting) { diff --git a/tests/cases/fourslash/moveToFile_existingImports2.ts b/tests/cases/fourslash/moveToFile_existingImports2.ts index fce4f8f337010..a93b542b59daf 100644 --- a/tests/cases/fourslash/moveToFile_existingImports2.ts +++ b/tests/cases/fourslash/moveToFile_existingImports2.ts @@ -9,8 +9,8 @@ ////[|export const b = x;|] // @filename: /b.ts -////import { y } from "./common"; -////export const a = y; +////import { x } from "./common"; +////export const a = x; verify.moveToFile({ newFileContents: { @@ -19,8 +19,8 @@ verify.moveToFile({ export const a = x; `, "/b.ts": -`import { x, y } from "./common"; -export const a = y; +`import { x } from "./common"; +export const a = x; export const b = x; `, }, From 3b79cb1d1c429165eb5a18b19a6a720c63cf9bcc Mon Sep 17 00:00:00 2001 From: navya9singh Date: Wed, 27 Mar 2024 17:44:05 -0700 Subject: [PATCH 27/41] new fixes for non exported symbols in import adder --- src/services/codefixes/importFixes.ts | 107 +++++++----------- src/services/exportInfoMap.ts | 8 -- src/services/pasteEdits.ts | 6 +- src/services/refactors/helpers.ts | 40 ++----- src/services/refactors/moveToFile.ts | 98 +++++++--------- src/services/refactors/moveToNewFile.ts | 87 ++------------ .../moveToFile_emptyTargetFile.js | 2 + .../pasteEdits_existingImports2.js | 1 + .../pasteEdits_knownSourceFile.js | 13 +-- .../pasteEdits_multiplePastes2.js | 15 +-- .../fourslash/moveToFile_blankExistingFile.ts | 2 - .../moveToFile_consistentQuoteStyle.ts | 1 - .../moveToFile_differentDirectories2.ts | 1 - .../moveToFile_expandSelectionRange4.ts | 17 +-- .../server/pasteEdits_knownSourceFile.ts | 5 +- .../server/pasteEdits_multiplePastes2.ts | 1 - 16 files changed, 125 insertions(+), 279 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 89bca3e3ea405..38c2f36e356ec 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -131,7 +131,6 @@ import { SymbolExportInfo, SymbolFlags, SymbolId, - SymbolInfo, SyntaxKind, textChanges, toPath, @@ -208,7 +207,7 @@ registerCodeFix({ export interface ImportAdder { hasFixes(): boolean; addImportFromDiagnostic: (diagnostic: DiagnosticWithLocation, context: CodeFixContextBase) => void; - addImportFromSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string) => void; + addImportFromSymbol: (exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string, oldFile?: SourceFile) => void; addImportForUnresolvedIdentifier: (context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean) => void; writeFixes: (changeTracker: textChanges.ChangeTracker, oldFileQuotePreference?: QuotePreference) => void; } @@ -249,21 +248,36 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu addImport(first(info)); } - function addImportFromSymbol(exportedSymbol: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string) { - if (!exportedSymbol.parent && targetFilePath) { - const fix = getImportFixForNonExportedSymbol(sourceFile, exportedSymbol, ImportKind.Named, program, !!isValidTypeOnlyUseSite, targetFilePath); - if (fix?.kind === ImportFixKind.AddToExisting) { - addImport({ fix, symbolName: exportedSymbol.name, errorIdentifierText: undefined }); + function addImportFromSymbol(symbolInfo: Symbol, isValidTypeOnlyUseSite?: boolean, targetFilePath?: string, originalFile?: SourceFile) { + if (!symbolInfo.parent && targetFilePath && originalFile) { + const moduleSymbol = originalFile.symbol; + const exportInfo: SymbolExportInfo[] = [{ + symbol: symbolInfo, + moduleSymbol, + moduleFileName: targetFilePath, + exportKind: ExportKind.Named, + targetFlags: SymbolFlags.Value, + isFromPackageJson: false, + }]; + const useRequire = shouldUseRequire(sourceFile, program); + const fix = getImportFixForSymbol(sourceFile, exportInfo, program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences, [targetFilePath]); + if (fix) { + addImport({ fix, symbolName: symbolInfo.name, errorIdentifierText: undefined }); } } else { - const moduleSymbol = Debug.checkDefined(exportedSymbol.parent); - const symbolName = getNameForExportedSymbol(exportedSymbol, getEmitScriptTarget(compilerOptions)); + const moduleSymbol = Debug.checkDefined(symbolInfo.parent); + const symbolName = getNameForExportedSymbol(symbolInfo, getEmitScriptTarget(compilerOptions)); const checker = program.getTypeChecker(); - const symbol = checker.getMergedSymbol(skipAlias(exportedSymbol, checker)); + const symbol = checker.getMergedSymbol(skipAlias(symbolInfo, checker)); const exportInfo = getAllExportInfoForSymbol(sourceFile, symbol, symbolName, moduleSymbol, /*preferCapitalized*/ false, program, host, preferences, cancellationToken); const useRequire = shouldUseRequire(sourceFile, program); - const fix = getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences); + /** + * For move to file and scenarios similar to that, there could be a case where a symbol is moved to a different file and needs to be imported by the source file. + * This is solved by 'targetFilePath' which becomes the module specifier that is used in getNewImportFixes() later. + */ + const fix = targetFilePath ? getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences, [targetFilePath]) : + getImportFixForSymbol(sourceFile, Debug.checkDefined(exportInfo), program, /*position*/ undefined, !!isValidTypeOnlyUseSite, useRequire, host, preferences); if (fix) { addImport({ fix, symbolName, errorIdentifierText: undefined }); } @@ -314,6 +328,15 @@ function createImportAdderWorker(sourceFile: SourceFile, program: Program, useAu entry.namedImports.set(symbolName, reduceAddAsTypeOnlyValues(prevValue, addAsTypeOnly)); break; case ImportKind.CommonJS: + if (compilerOptions.verbatimModuleSyntax) { + const prevValue = (entry.namedImports ||= new Map()).get(symbolName); + entry.namedImports.set(symbolName, reduceAddAsTypeOnlyValues(prevValue, addAsTypeOnly)); + } + else { + Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName"); + entry.namespaceLikeImport = { importKind, name: symbolName, addAsTypeOnly }; + } + break; case ImportKind.Namespace: Debug.assert(entry.namespaceLikeImport === undefined || entry.namespaceLikeImport.name === symbolName, "Namespacelike import shoudl be missing or match symbolName"); entry.namespaceLikeImport = { importKind, name: symbolName, addAsTypeOnly }; @@ -461,6 +484,7 @@ export function createImportSpecifierResolver(importingFile: SourceFile, program importingFile, host, preferences, + /*targetFileImportFrom*/ undefined, importMap, fromCacheOnly, ); @@ -599,17 +623,9 @@ export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbo )); } -function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], program: Program, position: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) { +function getImportFixForSymbol(sourceFile: SourceFile, exportInfos: readonly SymbolExportInfo[], program: Program, position: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences, targetFileImportFrom?: string[]) { const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host); - return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host); -} - -function getImportFixForNonExportedSymbol(sourceFile: SourceFile, symbol: Symbol, importKind: ImportKind, program: Program, isValidTypeOnlyUseSite: boolean, targetFilePath: string) { - const fix = getImportFixesForNonExportedSymbols(sourceFile, symbol, importKind, program, isValidTypeOnlyUseSite, targetFilePath); - if (fix.fixes[0] === undefined) return; // Not adding an import to an existing import - if (fix.fixes[0].kind === ImportFixKind.AddToExisting) { - return fix.fixes[0]; - } + return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences, targetFileImportFrom).fixes, sourceFile, program, packageJsonImportFilter, host); } function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction { @@ -647,30 +663,6 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } } -function getImportFixesForNonExportedSymbols( - sourceFile: SourceFile, - symbol: Symbol, - importKind: ImportKind, - program: Program, - isValidTypeOnlyUseSite: boolean, - targetFilePath: string, - importMap = createExistingImportMap(program.getTypeChecker(), sourceFile, program.getCompilerOptions()), -): { computedWithoutCacheCount: number; fixes: readonly ImportFixWithModuleSpecifier[]; } { - const checker = program.getTypeChecker(); - const symbolInfo = [{ - symbol, - targetFlags: SymbolFlags.Value, - importKind, - targetFilePath, - }]; - const existingImports = flatMap(symbolInfo, importMap.getImportsForNonExportedSymbols); - const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions()); - return { - computedWithoutCacheCount: 0, - fixes: [addToExisting!], - }; -} - function getImportFixes( exportInfos: readonly SymbolExportInfo[], usagePosition: number | undefined, @@ -680,6 +672,7 @@ function getImportFixes( sourceFile: SourceFile, host: LanguageServiceHost, preferences: UserPreferences, + targetFileImportFrom?: string[], importMap = createExistingImportMap(program.getTypeChecker(), sourceFile, program.getCompilerOptions()), fromCacheOnly?: boolean, ): { computedWithoutCacheCount: number; fixes: readonly ImportFixWithModuleSpecifier[]; } { @@ -706,6 +699,7 @@ function getImportFixes( host, preferences, fromCacheOnly, + targetFileImportFrom, ); return { computedWithoutCacheCount, @@ -871,23 +865,6 @@ function createExistingImportMap(checker: TypeChecker, importingFile: SourceFile const importKind = getImportKind(importingFile, exportKind, compilerOptions); return matchingDeclarations.map(declaration => ({ declaration, importKind, symbol, targetFlags })); }, - getImportsForNonExportedSymbols: ({ symbol, importKind, targetFlags, targetFilePath }: SymbolInfo): readonly FixAddToExistingImportInfo[] => { - let fix: FixAddToExistingImportInfo[] = []; - const values = importMap?.values(); - Debug.assertIsDefined(values); - for (const value of values) { - value.forEach(v => { - if (v.kind === SyntaxKind.ImportDeclaration && cast(v.moduleSpecifier, isStringLiteral).text === targetFilePath) { - fix = [{ declaration: v, importKind, targetFlags, symbol }]; - return fix; - } - else { - return emptyArray; - } - }); - } - return fix; - }, }; } @@ -937,6 +914,7 @@ function getNewImportFixes( host: LanguageServiceHost, preferences: UserPreferences, fromCacheOnly?: boolean, + targetFileImportFrom?: string[], ): { computedWithoutCacheCount: number; fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[]; } { const isJs = isSourceFileJS(sourceFile); const compilerOptions = program.getCompilerOptions(); @@ -951,7 +929,7 @@ function getNewImportFixes( let computedWithoutCacheCount = 0; const fixes = flatMap(exportInfo, (exportInfo, i) => { const checker = getChecker(exportInfo.isFromPackageJson); - const { computedWithoutCache, moduleSpecifiers } = getModuleSpecifiers(exportInfo.moduleSymbol, checker); + const { computedWithoutCache, moduleSpecifiers } = targetFileImportFrom ? { computedWithoutCache: true, moduleSpecifiers: targetFileImportFrom } : getModuleSpecifiers(exportInfo.moduleSymbol, checker); const importedSymbolHasValueMeaning = !!(exportInfo.targetFlags & SymbolFlags.Value); const addAsTypeOnly = getAddAsTypeOnly(isValidTypeOnlyUseSite, /*isForNewImportDeclaration*/ true, exportInfo.symbol, exportInfo.targetFlags, checker, compilerOptions); computedWithoutCacheCount += computedWithoutCache ? 1 : 0; @@ -1011,9 +989,10 @@ function getFixesForAddImport( host: LanguageServiceHost, preferences: UserPreferences, fromCacheOnly?: boolean, + targetFileImportFrom?: string[], ): { computedWithoutCacheCount?: number; fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[]; } { const existingDeclaration = firstDefined(existingImports, info => newImportInfoFromExistingSpecifier(info, isValidTypeOnlyUseSite, useRequire, program.getTypeChecker(), program.getCompilerOptions())); - return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, usagePosition, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly); + return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, usagePosition, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly, targetFileImportFrom); } function newImportInfoFromExistingSpecifier( diff --git a/src/services/exportInfoMap.ts b/src/services/exportInfoMap.ts index 9a17bc2ebc797..322631ad92c31 100644 --- a/src/services/exportInfoMap.ts +++ b/src/services/exportInfoMap.ts @@ -90,14 +90,6 @@ export interface SymbolExportInfo { isFromPackageJson: boolean; } -/** @internal */ -export interface SymbolInfo { - readonly symbol: Symbol; - importKind: ImportKind; - targetFlags: SymbolFlags; - targetFilePath: string; -} - interface CachedSymbolExportInfo { // Used to rehydrate `symbol` and `moduleSymbol` when transient id: number; diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 223416868d393..98f26d39739d7 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -19,7 +19,6 @@ import { forEachChild, formatting, getQuotePreference, - insertImports, isIdentifier, textChanges, } from "./_namespaces/ts"; @@ -85,10 +84,7 @@ function pasteEdits( }); const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); - const imports = getTargetFileImportsAndAddExportInOldFile(copiedFrom.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copiedFrom.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); - if (imports.length > 0) { - insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); - } + getTargetFileImportsAndAddExportInOldFile(copiedFrom.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copiedFrom.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); importAdder.writeFixes(changes, getQuotePreference(copiedFrom.file, preferences)); } else { diff --git a/src/services/refactors/helpers.ts b/src/services/refactors/helpers.ts index bccc300ad0aa7..12a35d65a7ad2 100644 --- a/src/services/refactors/helpers.ts +++ b/src/services/refactors/helpers.ts @@ -1,6 +1,3 @@ -import { - getModuleSpecifier, -} from "../../compiler/moduleSpecifiers"; import { AnyImportOrRequireStatement, append, @@ -20,8 +17,6 @@ import { LanguageServiceHost, } from "../types"; import { - createModuleSpecifierResolutionHost, - makeStringLiteral, nodeSeenTracker, QuotePreference, } from "../utilities"; @@ -78,7 +73,7 @@ export function getTargetFileImportsAndAddExportInOldFile( useEsModuleSyntax: boolean, quotePreference: QuotePreference, importAdder?: codefix.ImportAdder, -): readonly AnyImportOrRequireStatement[] { +) { const copiedOldImports: AnyImportOrRequireStatement[] = []; /** * Recomputing the imports is preferred with importAdder because it manages multiple import additions for a file and writes then to a ChangeTracker, @@ -93,28 +88,17 @@ export function getTargetFileImportsAndAddExportInOldFile( catch { for (const oldStatement of oldFile.statements) { forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); + append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => checker.getSymbolAtLocation(name) === symbol)); }); } } }); } else { - const targetSourceFile = program.getSourceFile(targetFile); // Would be undefined for a new file + // When target file does not exist for (const oldStatement of oldFile.statements) { forEachImportInStatement(oldStatement, i => { - // Recomputing module specifier - const moduleSpecifier = moduleSpecifierFromImport(i); - const compilerOptions = program.getCompilerOptions(); - const resolved = program.getResolvedModuleFromModuleSpecifier(moduleSpecifier); - const fileName = resolved?.resolvedModule?.resolvedFileName; - if (fileName && targetSourceFile) { - const newModuleSpecifier = getModuleSpecifier(compilerOptions, targetSourceFile, targetSourceFile.fileName, fileName, createModuleSpecifierResolutionHost(program, host)); - append(copiedOldImports, filterImport(i, makeStringLiteral(newModuleSpecifier, quotePreference), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - } - else { - append(copiedOldImports, filterImport(i, factory.createStringLiteral(moduleSpecifierFromImport(i).text), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - } + append(copiedOldImports, filterImport(i, moduleSpecifierFromImport(i), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); }); } } @@ -123,7 +107,7 @@ export function getTargetFileImportsAndAddExportInOldFile( const targetFileSourceFile = program.getSourceFile(targetFile); let oldFileDefault: Identifier | undefined; const oldFileNamedImports: string[] = []; - const oldFileNonExportedSymbols: Symbol[] = []; + const oldFileSymbols: Symbol[] = []; const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. targetFileImportsFromOldFile.forEach(symbol => { if (!symbol.declarations) { @@ -137,12 +121,9 @@ export function getTargetFileImportsAndAddExportInOldFile( const top = getTopLevelDeclarationStatement(decl); if (markSeenTop(top)) { addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); - oldFileNonExportedSymbols.push(symbol); - } - if (importAdder && !checker.isUnknownSymbol(symbol) && symbol.parent) { - oldFileNamedImports.push(name.text); + oldFileSymbols.push(symbol); } - else { + if (!importAdder) { if (hasSyntacticModifier(decl, ModifierFlags.Default)) { oldFileDefault = name; } @@ -152,7 +133,8 @@ export function getTargetFileImportsAndAddExportInOldFile( } } }); - return targetFileSourceFile - ? append(copiedOldImports, makeImportOrRequire(targetFileSourceFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference, oldFileNonExportedSymbols, importAdder)) - : append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); + + targetFileSourceFile ? makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference, oldFileSymbols, importAdder, targetFileSourceFile) : + append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, oldFile.fileName, program, host, useEsModuleSyntax, quotePreference)); + return copiedOldImports; } diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 536b03accb52a..26e2760a50895 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -2,7 +2,6 @@ import { getModuleSpecifier, } from "../../compiler/moduleSpecifiers"; import { - AnyImportOrRequireStatement, ApplicableRefactorInfo, arrayFrom, AssignmentDeclarationKind, @@ -71,7 +70,6 @@ import { importFromModuleSpecifier, insertImports, InterfaceDeclaration, - InternalSymbolName, isArrayLiteralExpression, isBinaryExpression, isBindingElement, @@ -215,15 +213,16 @@ function error(notApplicableReason: string) { 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 importAdderForOldFile = codefix.createImportAdder(oldFile, context.program, context.preferences, context.host); // For a new file if (!host.fileExists(targetFile)) { - changes.createNewFile(oldFile, targetFile, getNewStatementsAndRemoveFromOldFile(oldFile, targetFile, getUsageInfo(oldFile, toMove.all, checker), changes, toMove, program, host, preferences)); + changes.createNewFile(oldFile, targetFile, getNewStatementsAndRemoveFromOldFile(oldFile, targetFile, getUsageInfo(oldFile, toMove.all, checker), changes, toMove, program, host, preferences, /*importAdderForNewFile*/ undefined, importAdderForOldFile)); addNewFileToTsconfig(program, changes, oldFile.fileName, targetFile, hostGetCanonicalFileName(host)); } else { const targetSourceFile = Debug.checkDefined(program.getSourceFile(targetFile)); - const importAdder = codefix.createImportAdder(targetSourceFile, context.program, context.preferences, context.host); - getNewStatementsAndRemoveFromOldFile(oldFile, targetSourceFile, getUsageInfo(oldFile, toMove.all, checker, getExistingLocals(targetSourceFile, toMove.all, checker)), changes, toMove, program, host, preferences, importAdder); + const importAdderForNewFile = codefix.createImportAdder(targetSourceFile, context.program, context.preferences, context.host); + getNewStatementsAndRemoveFromOldFile(oldFile, targetSourceFile, getUsageInfo(oldFile, toMove.all, checker, getExistingLocals(targetSourceFile, toMove.all, checker)), changes, toMove, program, host, preferences, importAdderForNewFile, importAdderForOldFile); } } @@ -236,7 +235,8 @@ function getNewStatementsAndRemoveFromOldFile( program: Program, host: LanguageServiceHost, preferences: UserPreferences, - importAdder?: codefix.ImportAdder, + importAdderForNewFile?: codefix.ImportAdder, + importAdderForOldFile?: codefix.ImportAdder, ) { const checker = program.getTypeChecker(); const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective); @@ -250,16 +250,17 @@ function getNewStatementsAndRemoveFromOldFile( const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFileName, program, host, !!oldFile.commonJsModuleIndicator); const quotePreference = getQuotePreference(oldFile, preferences); - const importsFromTargetFile = createOldFileImportsFromTargetFile(oldFile, usage.oldFileImportsFromTargetFile, targetFileName, program, host, useEsModuleSyntax, quotePreference); - if (importsFromTargetFile) { - insertImports(changes, oldFile, importsFromTargetFile, /*blankLineBetween*/ true, preferences); + + makeImportOrRequire(oldFile, /*defaultImport*/ undefined, /*imports*/ [], targetFileName, program, host, useEsModuleSyntax, quotePreference, Array.from(usage.oldFileImportsFromTargetFile), importAdderForOldFile, oldFile); + if (importAdderForOldFile) { + importAdderForOldFile.writeFixes(changes, quotePreference); } deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker); deleteMovedStatements(oldFile, toMove.ranges, changes); updateImportsInOtherFiles(changes, program, host, oldFile, usage.movedSymbols, targetFileName, quotePreference); - const imports = getTargetFileImportsAndAddExportInOldFile(oldFile, targetFileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, checker, program, host, useEsModuleSyntax, quotePreference, importAdder); + const imports = getTargetFileImportsAndAddExportInOldFile(oldFile, targetFileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, checker, program, host, useEsModuleSyntax, quotePreference, importAdderForNewFile); const body = addExports(oldFile, toMove.all, usage.oldFileImportsFromTargetFile, useEsModuleSyntax); if (typeof targetFile !== "string") { if (targetFile.statements.length > 0) { @@ -272,10 +273,10 @@ function getNewStatementsAndRemoveFromOldFile( insertImports(changes, targetFile, imports, /*blankLineBetween*/ true, preferences); } } - if (importAdder) { - importAdder.writeFixes(changes, quotePreference); + if (importAdderForNewFile) { + importAdderForNewFile.writeFixes(changes, quotePreference); } - if (imports.length && body.length) { + if (body.length) { return [ ...prologueDirectives, ...imports, @@ -464,29 +465,6 @@ export type SupportedImportStatement = | ImportEqualsDeclaration | VariableStatement; -/** @internal */ -export function createOldFileImportsFromTargetFile( - sourceFile: SourceFile, - targetFileNeedExport: Set, - targetFileNameWithExtension: string, - program: Program, - host: LanguageServiceHost, - useEs6Imports: boolean, - quotePreference: QuotePreference, -): AnyImportOrRequireStatement | undefined { - let defaultImport: Identifier | undefined; - const imports: string[] = []; - targetFileNeedExport.forEach(symbol => { - if (symbol.escapedName === InternalSymbolName.Default) { - defaultImport = factory.createIdentifier(symbolNameNoDefault(symbol)!); - } - else { - imports.push(symbol.name); - } - }); - return makeImportOrRequire(sourceFile, defaultImport, imports, targetFileNameWithExtension, program, host, useEs6Imports, quotePreference); -} - /** @internal */ export function makeImportOrRequire( sourceFile: SourceFile, @@ -497,41 +475,43 @@ export function makeImportOrRequire( host: LanguageServiceHost, useEs6Imports: boolean, quotePreference: QuotePreference, - unexportedSymbols?: Symbol[], + symbols?: Symbol[], importAdder?: codefix.ImportAdder, -): AnyImportOrRequireStatement | undefined { + importingSourceFile?: SourceFile, +) { const pathToTargetFile = resolvePath(getDirectoryPath(sourceFile.path), targetFileNameWithExtension); - const pathToTargetFileWithCorrectExtension = getModuleSpecifier(program.getCompilerOptions(), sourceFile, sourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)); + const pathToTargetFileWithCorrectExtension = importingSourceFile ? getModuleSpecifier(program.getCompilerOptions(), importingSourceFile, importingSourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)) : + getModuleSpecifier(program.getCompilerOptions(), sourceFile, sourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)); if (useEs6Imports) { - const specifiers = imports.map(i => factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, factory.createIdentifier(i))); - const newImports = makeImportIfNecessary(defaultImport, specifiers, pathToTargetFileWithCorrectExtension, quotePreference); - // To check if we need to add imports to an existing import statement in the target file - let addToExistingImports = false; - for (const statement of sourceFile.statements) { - forEachImportInStatement(statement, i => { - if (moduleSpecifierFromImport(i).text === pathToTargetFileWithCorrectExtension) { - addToExistingImports = true; - } - }); - } - if (addToExistingImports && importAdder && !defaultImport && unexportedSymbols) { - for (const symbol of unexportedSymbols) { - if (newImports && importAdder) { - importAdder.addImportFromSymbol(symbol, /*isValidTypeOnlyUseSite*/ false, pathToTargetFileWithCorrectExtension); + if (importAdder && symbols && importingSourceFile) { + for (const symbol of symbols) { + if (importAdder) { + importAdder.addImportFromSymbol(symbol, /*isValidTypeOnlyUseSite*/ false, pathToTargetFileWithCorrectExtension, sourceFile); } } } else { + const specifiers = imports.map(i => factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, factory.createIdentifier(i))); + const newImports = makeImportIfNecessary(defaultImport, specifiers, pathToTargetFileWithCorrectExtension, quotePreference); return newImports; } } else { - Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. - const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); - return bindingElements.length - ? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(makeStringLiteral(pathToTargetFileWithCorrectExtension, quotePreference))) as RequireVariableStatement - : undefined; + if (importAdder && symbols && importingSourceFile) { + for (const symbol of symbols) { + if (importAdder) { + importAdder.addImportFromSymbol(symbol, /*isValidTypeOnlyUseSite*/ false, pathToTargetFileWithCorrectExtension, sourceFile); + } + } + } + else { + Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. + const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); + return bindingElements.length + ? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(makeStringLiteral(pathToTargetFileWithCorrectExtension, quotePreference))) as RequireVariableStatement + : undefined; + } } } diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 99b6612fecf85..bf162bd089eca 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -1,53 +1,37 @@ import { - append, ApplicableRefactorInfo, + codefix, Debug, Diagnostics, emptyArray, fileShouldUseJavaScriptRequire, - getBaseFileName, getLineAndCharacterOfPosition, getLocaleSpecificMessage, getQuotePreference, - hasSyntacticModifier, hostGetCanonicalFileName, - Identifier, - insertImports, isPrologueDirective, LanguageServiceHost, last, - ModifierFlags, - nodeSeenTracker, Program, - QuotePreference, + RefactorContext, RefactorEditInfo, SourceFile, - Symbol, SyntaxKind, takeWhile, textChanges, - TypeChecker, UserPreferences, } from "../_namespaces/ts"; import { addExports, - addExportToChanges, addNewFileToTsconfig, createNewFileName, - createOldFileImportsFromTargetFile, deleteMovedStatements, deleteUnusedOldImports, - filterImport, - forEachImportInStatement, getStatementsToMove, - getTopLevelDeclarationStatement, + getTargetFileImportsAndAddExportInOldFile, getUsageInfo, - isTopLevelDeclaration, makeImportOrRequire, - moduleSpecifierFromImport, - nameOfTopLevelDeclaration, registerRefactor, - SupportedImportStatement, ToMove, updateImportsInOtherFiles, UsageInfo, @@ -81,18 +65,18 @@ registerRefactor(refactorName, { getEditsForAction: function getRefactorEditsToMoveToNewFile(context, actionName): RefactorEditInfo { Debug.assert(actionName === refactorName, "Wrong refactor invoked"); const statements = Debug.checkDefined(getStatementsToMove(context)); - const edits = textChanges.ChangeTracker.with(context, t => doChange(context.file, context.program, statements, t, context.host, context.preferences)); + const edits = textChanges.ChangeTracker.with(context, t => doChange(context, context.file, context.program, statements, t, context.host, context.preferences)); return { edits, renameFilename: undefined, renameLocation: undefined }; }, }); -function doChange(oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void { +function doChange(context: RefactorContext, oldFile: SourceFile, program: Program, toMove: ToMove, changes: textChanges.ChangeTracker, host: LanguageServiceHost, preferences: UserPreferences): void { const checker = program.getTypeChecker(); const usage = getUsageInfo(oldFile, toMove.all, checker); const newFilename = createNewFileName(oldFile, program, host, toMove); - + const importAdderForOldFile = codefix.createImportAdder(oldFile, context.program, context.preferences, context.host); // If previous file was global, this is easy. - changes.createNewFile(oldFile, newFilename, getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, host, newFilename, preferences)); + changes.createNewFile(oldFile, newFilename, getNewStatementsAndRemoveFromOldFile(oldFile, usage, changes, toMove, program, host, newFilename, preferences, importAdderForOldFile)); addNewFileToTsconfig(program, changes, oldFile.fileName, newFilename, hostGetCanonicalFileName(host)); } @@ -106,6 +90,7 @@ function getNewStatementsAndRemoveFromOldFile( host: LanguageServiceHost, newFilename: string, preferences: UserPreferences, + importAdderForOldFile?: codefix.ImportAdder, ) { const checker = program.getTypeChecker(); const prologueDirectives = takeWhile(oldFile.statements, isPrologueDirective); @@ -116,16 +101,16 @@ function getNewStatementsAndRemoveFromOldFile( const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(newFilename, program, host, !!oldFile.commonJsModuleIndicator); const quotePreference = getQuotePreference(oldFile, preferences); - const importsFromNewFile = createOldFileImportsFromTargetFile(oldFile, usage.oldFileImportsFromTargetFile, newFilename, program, host, useEsModuleSyntax, quotePreference); - if (importsFromNewFile) { - insertImports(changes, oldFile, importsFromNewFile, /*blankLineBetween*/ true, preferences); + makeImportOrRequire(oldFile, /*defaultImport*/ undefined, /*imports*/ [], newFilename, program, host, useEsModuleSyntax, quotePreference, Array.from(usage.oldFileImportsFromTargetFile), importAdderForOldFile, oldFile); + if (importAdderForOldFile) { + importAdderForOldFile.writeFixes(changes, quotePreference); } deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker); deleteMovedStatements(oldFile, toMove.ranges, changes); updateImportsInOtherFiles(changes, program, host, oldFile, usage.movedSymbols, newFilename, quotePreference); - const imports = getNewFileImportsAndAddExportInOldFile(oldFile, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, checker, program, host, useEsModuleSyntax, quotePreference); + const imports = getTargetFileImportsAndAddExportInOldFile(oldFile, newFilename, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, checker, program, host, useEsModuleSyntax, quotePreference); const body = addExports(oldFile, toMove.all, usage.oldFileImportsFromTargetFile, useEsModuleSyntax); if (imports.length && body.length) { return [ @@ -142,51 +127,3 @@ function getNewStatementsAndRemoveFromOldFile( ...body, ]; } - -function getNewFileImportsAndAddExportInOldFile( - oldFile: SourceFile, - importsToCopy: Map, - newFileImportsFromOldFile: Set, - changes: textChanges.ChangeTracker, - checker: TypeChecker, - program: Program, - host: LanguageServiceHost, - useEsModuleSyntax: boolean, - quotePreference: QuotePreference, -): readonly SupportedImportStatement[] { - const copiedOldImports: SupportedImportStatement[] = []; - for (const oldStatement of oldFile.statements) { - forEachImportInStatement(oldStatement, i => { - append(copiedOldImports, filterImport(i, moduleSpecifierFromImport(i), name => importsToCopy.has(checker.getSymbolAtLocation(name)!))); - }); - } - - // Also, import things used from the old file, and insert 'export' modifiers as necessary in the old file. - let oldFileDefault: Identifier | undefined; - const oldFileNamedImports: string[] = []; - const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. - newFileImportsFromOldFile.forEach(symbol => { - if (!symbol.declarations) { - return; - } - for (const decl of symbol.declarations) { - if (!isTopLevelDeclaration(decl)) continue; - const name = nameOfTopLevelDeclaration(decl); - if (!name) continue; - - const top = getTopLevelDeclarationStatement(decl); - if (markSeenTop(top)) { - addExportToChanges(oldFile, top, name, changes, useEsModuleSyntax); - } - if (hasSyntacticModifier(decl, ModifierFlags.Default)) { - oldFileDefault = name; - } - else { - oldFileNamedImports.push(name.text); - } - } - }); - - append(copiedOldImports, makeImportOrRequire(oldFile, oldFileDefault, oldFileNamedImports, getBaseFileName(oldFile.fileName), program, host, useEsModuleSyntax, quotePreference)); - return copiedOldImports; -} diff --git a/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js b/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js index 73f4d8a932124..18cf121bee6f4 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js @@ -379,6 +379,8 @@ Info seq [hh:mm:ss:mss] request: }, "command": "getEditsForRefactor" } +Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results +Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js index 051b6b755c0b0..88a3594675a07 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -294,6 +294,7 @@ Info seq [hh:mm:ss:mss] Files (8) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js index 9847220a29b83..7fbe751de3aae 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -299,18 +299,7 @@ Info seq [hh:mm:ss:mss] response: "line": 1, "offset": 1 }, - "newText": "import { a } from \"./file2\";\n\n" - }, - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { b } from './file1';\n\n" + "newText": "import { b } from './file1';\nimport { a } from './file2';\n\n" }, { "start": { diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js index 8e858f2b4b268..4b9f8f18b623a 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -274,6 +274,8 @@ Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit +Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit Info seq [hh:mm:ss:mss] response: { "seq": 0, @@ -298,18 +300,7 @@ Info seq [hh:mm:ss:mss] response: "line": 1, "offset": 1 }, - "newText": "import { r, s } from \"./file1\";\n\n" - }, - { - "start": { - "line": 1, - "offset": 1 - }, - "end": { - "line": 1, - "offset": 1 - }, - "newText": "import { aa, bb } from \"./other\";\n\n" + "newText": "import { r, s } from \"./file1\";\nimport { aa, bb } from \"./other\";\n\n" }, { "start": { diff --git a/tests/cases/fourslash/moveToFile_blankExistingFile.ts b/tests/cases/fourslash/moveToFile_blankExistingFile.ts index 370fa30b7edab..085ff33a1f391 100644 --- a/tests/cases/fourslash/moveToFile_blankExistingFile.ts +++ b/tests/cases/fourslash/moveToFile_blankExistingFile.ts @@ -20,8 +20,6 @@ verify.moveToFile({ "/bar.ts": `// import { p } from './a'; - - import { b } from './other'; diff --git a/tests/cases/fourslash/moveToFile_consistentQuoteStyle.ts b/tests/cases/fourslash/moveToFile_consistentQuoteStyle.ts index 969060b24f2c4..1dd41d7ceeb5f 100644 --- a/tests/cases/fourslash/moveToFile_consistentQuoteStyle.ts +++ b/tests/cases/fourslash/moveToFile_consistentQuoteStyle.ts @@ -21,7 +21,6 @@ verify.moveToFile({ "/bar.ts": `import { a } from './a'; - import { b } from './other'; export const tt = 2; diff --git a/tests/cases/fourslash/moveToFile_differentDirectories2.ts b/tests/cases/fourslash/moveToFile_differentDirectories2.ts index 43aea215d6117..173b64a4cff99 100644 --- a/tests/cases/fourslash/moveToFile_differentDirectories2.ts +++ b/tests/cases/fourslash/moveToFile_differentDirectories2.ts @@ -24,7 +24,6 @@ y;`, "/src/dir2/bar.ts": `import { a } from '../dir1/a'; - import { b } from '../dir1/other'; diff --git a/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts b/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts index 7a0861405a9e0..9ab57082ab138 100644 --- a/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts +++ b/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts @@ -5,6 +5,7 @@ ////const t = b; // @Filename: /a.ts +////import { c } from './other'; //// interface T { //// a: number //// } @@ -15,20 +16,22 @@ // @Filename: /other.ts ////export const b = 2; +////export const c = 3; verify.moveToFile({ newFileContents: { "/a.ts": -`interface T { - a: number -} -export const x: T={ - a: 1 -}; +`import { c } from './other'; + interface T { + a: number + } + export const x: T={ + a: 1 + }; `, "/bar.ts": -`import { x } from "./a"; +`import { x } from './a'; import { b } from './other'; const t = b; const b = x.a; diff --git a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts index 8d51bf688fc56..2d99851ab26c3 100644 --- a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts @@ -35,9 +35,8 @@ const c = a + b; const t = 9;`, "/target.ts": -`import { a } from "./file2"; - -import { b } from './file1'; +`import { b } from './file1'; +import { a } from './file2'; export const tt = 2; const c = a + b; diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts index 9a6c08f8cc0cf..1f78205c9d55c 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -33,7 +33,6 @@ const u = 1;`,], newFileContents: { "/target.ts": `import { r, s } from "./file1"; - import { aa, bb } from "./other"; const a = 1; From 82fc3bfe9d5f104ae356c79cb61c3bf264e35a46 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Wed, 27 Mar 2024 22:21:51 -0700 Subject: [PATCH 28/41] adressing pr comments --- src/server/protocol.ts | 6 ++++-- src/server/session.ts | 8 ++++---- src/services/pasteEdits.ts | 4 ++-- tests/baselines/reference/api/typescript.d.ts | 4 ++-- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/server/protocol.ts b/src/server/protocol.ts index b757dc6bd7a44..6eba912db51c5 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -635,14 +635,16 @@ export interface GetPasteEditsRequest extends Request { arguments: GetPasteEditsRequestArgs; } -export type GetPasteEditsRequestArgs = FileRequestArgs & { +export interface GetPasteEditsRequestArgs extends FileRequestArgs { pastedText: string[]; pasteLocations: TextSpan[]; copiedFrom?: { file: string; range: TextSpan[]; }; -}; +} + export interface GetPasteEditsResponse extends Response { body: PasteEditsAction; } + export interface PasteEditsAction { edits: FileCodeEdits[]; fixId?: {}; diff --git a/src/server/session.ts b/src/server/session.ts index 0eb56079399bc..924ddb92106b0 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2798,15 +2798,15 @@ export class Session implements EventSender { private getPasteEdits(args: protocol.GetPasteEditsRequestArgs): protocol.PasteEditsAction | undefined { const { file, project } = this.getFileAndProject(args); - const copyFile = args.copiedFrom ? args.copiedFrom.file : undefined; + const copiedFrom = args.copiedFrom + ? { file: args.copiedFrom.file, range: args.copiedFrom.range.map(copies => this.getRange({ file: args.copiedFrom!.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom!.file))!)) } + : undefined; const result = project.getLanguageService().getPasteEdits( { targetFile: file, pastedText: args.pastedText, pasteLocations: args.pasteLocations.map(paste => this.getRange({ file, startLine: paste.start.line, startOffset: paste.start.offset, endLine: paste.end.line, endOffset: paste.end.offset }, project.getScriptInfoForNormalizedPath(file)!)), - copiedFrom: args.copiedFrom && copyFile - ? { file: args.copiedFrom.file, range: args.copiedFrom.range.map(copies => this.getRange({ file: copyFile, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(copyFile))!)) } - : undefined, + copiedFrom, preferences: this.getPreferences(file), }, this.getFormatOptions(file), diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 98f26d39739d7..7d3760a3d8e0b 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -69,10 +69,10 @@ function pasteEdits( let newText = ""; pasteLocations.forEach((location, i) => { if (i === pasteLocations.length - 1) { - newText += targetFile.getText().slice(start, location.pos) + pastedText[i] + targetFile.getText().slice(location.end); + newText += targetFile.text.slice(start, location.pos) + pastedText[i] + targetFile.text.slice(location.end); } else { - newText += targetFile.getText().slice(start, location.pos) + pastedText[i]; + newText += targetFile.text.slice(start, location.pos) + pastedText[i]; start = location.end; } }); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 9391ed2686456..a05b61cb329a1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -477,14 +477,14 @@ declare namespace ts { command: CommandTypes.GetPasteEdits; arguments: GetPasteEditsRequestArgs; } - export type GetPasteEditsRequestArgs = FileRequestArgs & { + export interface GetPasteEditsRequestArgs extends FileRequestArgs { pastedText: string[]; pasteLocations: TextSpan[]; copiedFrom?: { file: string; range: TextSpan[]; }; - }; + } export interface GetPasteEditsResponse extends Response { body: PasteEditsAction; } From 0ef7161521a472fc0f4d2925e32641fa24c32525 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 25 Apr 2024 15:36:34 -0700 Subject: [PATCH 29/41] fixing merge conflicts --- src/services/codefixes/importFixes.ts | 10 +----- src/services/refactors/moveToFile.ts | 44 +++++++-------------------- 2 files changed, 12 insertions(+), 42 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 308943c89e495..46e24c7bd20be 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -715,7 +715,6 @@ export function createImportSpecifierResolver(importingFile: SourceFile, program importingFile, host, preferences, - /*targetFileImportFrom*/ undefined, importMap, fromCacheOnly, ); @@ -856,7 +855,7 @@ export function getPromoteTypeOnlyCompletionAction(sourceFile: SourceFile, symbo function getImportFixForSymbol(sourceFile: SourceFile | FutureSourceFile, exportInfos: readonly SymbolExportInfo[], program: Program, position: number | undefined, isValidTypeOnlyUseSite: boolean, useRequire: boolean, host: LanguageServiceHost, preferences: UserPreferences) { const packageJsonImportFilter = createPackageJsonImportFilter(sourceFile, preferences, host); - return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences, targetFileImportFrom).fixes, sourceFile, program, packageJsonImportFilter, host); + return getBestFix(getImportFixes(exportInfos, position, isValidTypeOnlyUseSite, useRequire, program, sourceFile, host, preferences).fixes, sourceFile, program, packageJsonImportFilter, host); } function codeFixActionToCodeAction({ description, changes, commands }: CodeFixAction): CodeAction { @@ -933,7 +932,6 @@ function getImportFixes( host, preferences, fromCacheOnly, - targetFileImportFrom, ); return { computedWithoutCacheCount, @@ -1297,12 +1295,6 @@ function getFixInfosWithoutDiagnostic(context: CodeFixContextBase, symbolToken: return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); } -function getFixInfosWithoutDiagnostic(context: CodeFixContextBase, symbolToken: Identifier, useAutoImportProvider: boolean): readonly FixInfo[] | undefined { - const info = getFixesInfoForNonUMDImport(context, symbolToken, useAutoImportProvider); - const packageJsonImportFilter = createPackageJsonImportFilter(context.sourceFile, context.preferences, context.host); - return info && sortFixInfo(info, context.sourceFile, context.program, packageJsonImportFilter, context.host); -} - function getBestFix(fixes: readonly ImportFixWithModuleSpecifier[], sourceFile: SourceFile | FutureSourceFile, program: Program, packageJsonImportFilter: PackageJsonImportFilter, host: LanguageServiceHost): ImportFixWithModuleSpecifier | undefined { if (!some(fixes)) return; // These will always be placed first if available, and are better than other kinds diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 636aee8c70106..0fd2c95e8d66c 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -1,5 +1,6 @@ import { getModuleSpecifier } from "../../compiler/moduleSpecifiers"; import { + AnyImportOrRequireStatement, ApplicableRefactorInfo, arrayFrom, AssignmentDeclarationKind, @@ -479,43 +480,20 @@ export function makeImportOrRequire( host: LanguageServiceHost, useEs6Imports: boolean, quotePreference: QuotePreference, - symbols?: Symbol[], - importAdder?: codefix.ImportAdder, - importingSourceFile?: SourceFile, -) { - const pathToTargetFile = resolvePath(getDirectoryPath(sourceFile.path), targetFileNameWithExtension); - const pathToTargetFileWithCorrectExtension = importingSourceFile ? getModuleSpecifier(program.getCompilerOptions(), importingSourceFile, importingSourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)) : - getModuleSpecifier(program.getCompilerOptions(), sourceFile, sourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)); +): AnyImportOrRequireStatement | undefined { + const pathToTargetFile = resolvePath(getDirectoryPath(getNormalizedAbsolutePath(sourceFile.fileName, program.getCurrentDirectory())), targetFileNameWithExtension); + const pathToTargetFileWithCorrectExtension = getModuleSpecifier(program.getCompilerOptions(), sourceFile, sourceFile.fileName, pathToTargetFile, createModuleSpecifierResolutionHost(program, host)); if (useEs6Imports) { - if (importAdder && symbols && importingSourceFile) { - for (const symbol of symbols) { - if (importAdder) { - importAdder.addImportFromSymbol(symbol, /*isValidTypeOnlyUseSite*/ false, pathToTargetFileWithCorrectExtension, sourceFile); - } - } - } - else { - const specifiers = imports.map(i => factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, factory.createIdentifier(i))); - const newImports = makeImportIfNecessary(defaultImport, specifiers, pathToTargetFileWithCorrectExtension, quotePreference); - return newImports; - } + const specifiers = imports.map(i => factory.createImportSpecifier(/*isTypeOnly*/ false, /*propertyName*/ undefined, factory.createIdentifier(i))); + return makeImportIfNecessary(defaultImport, specifiers, pathToTargetFileWithCorrectExtension, quotePreference); } else { - if (importAdder && symbols && importingSourceFile) { - for (const symbol of symbols) { - if (importAdder) { - importAdder.addImportFromSymbol(symbol, /*isValidTypeOnlyUseSite*/ false, pathToTargetFileWithCorrectExtension, sourceFile); - } - } - } - else { - Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. - const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); - return bindingElements.length - ? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(makeStringLiteral(pathToTargetFileWithCorrectExtension, quotePreference))) as RequireVariableStatement - : undefined; - } + Debug.assert(!defaultImport, "No default import should exist"); // If there's a default export, it should have been an es6 module. + const bindingElements = imports.map(i => factory.createBindingElement(/*dotDotDotToken*/ undefined, /*propertyName*/ undefined, i)); + return bindingElements.length + ? makeVariableStatement(factory.createObjectBindingPattern(bindingElements), /*type*/ undefined, createRequireCall(makeStringLiteral(pathToTargetFileWithCorrectExtension, quotePreference))) as RequireVariableStatement + : undefined; } } From 7c6a1464d174e0e9a60ca41097d0eefd41617eb6 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 25 Apr 2024 18:18:44 -0700 Subject: [PATCH 30/41] resolving merge conflicts --- src/services/codefixes/helpers.ts | 2 +- src/services/codefixes/inferFromUsage.ts | 2 +- src/services/pasteEdits.ts | 10 ++++++---- src/services/refactors/moveToFile.ts | 3 ++- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/services/codefixes/helpers.ts b/src/services/codefixes/helpers.ts index 09dff9021007e..ee01e0f00a4b3 100644 --- a/src/services/codefixes/helpers.ts +++ b/src/services/codefixes/helpers.ts @@ -923,7 +923,7 @@ function replaceFirstIdentifierOfEntityName(name: EntityName, newIdentifier: Ide /** @internal */ export function importSymbols(importAdder: ImportAdder, symbols: readonly Symbol[]) { - symbols.forEach(s => importAdder.addImportFromSymbol(s, /*isValidTypeOnlyUseSite*/ true)); + symbols.forEach(s => importAdder.addImportFromExportedSymbol(s, /*isValidTypeOnlyUseSite*/ true)); } /** @internal */ diff --git a/src/services/codefixes/inferFromUsage.ts b/src/services/codefixes/inferFromUsage.ts index 3d2513875b21d..95a19e1d39638 100644 --- a/src/services/codefixes/inferFromUsage.ts +++ b/src/services/codefixes/inferFromUsage.ts @@ -439,7 +439,7 @@ function tryReplaceImportTypeNodeWithAutoImport( ): boolean { const importableReference = tryGetAutoImportableReferenceFromTypeNode(typeNode, scriptTarget); if (importableReference && changes.tryInsertTypeAnnotation(sourceFile, declaration, importableReference.typeNode)) { - forEach(importableReference.symbols, s => importAdder.addImportFromSymbol(s, /*isValidTypeOnlyUseSite*/ true)); + forEach(importableReference.symbols, s => importAdder.addImportFromExportedSymbol(s, /*isValidTypeOnlyUseSite*/ true)); return true; } return false; diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 7d3760a3d8e0b..47a17bbf022a5 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -22,10 +22,9 @@ import { isIdentifier, textChanges, } from "./_namespaces/ts"; +import { addTargetFileImports } from "./refactors/helpers"; import { - getTargetFileImportsAndAddExportInOldFile, -} from "./refactors/helpers"; -import { + addExportsInOldFile, getExistingLocals, getUsageInfo, } from "./refactors/moveToFile"; @@ -84,7 +83,10 @@ function pasteEdits( }); const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); - getTargetFileImportsAndAddExportInOldFile(copiedFrom.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copiedFrom.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); + //getTargetFileImportsAndAddExportInOldFile(copiedFrom.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copiedFrom.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); + const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram!, host, !!copiedFrom.file.commonJsModuleIndicator); + addExportsInOldFile(copiedFrom.file, usage.targetFileImportsFromOldFile, changes, useEsModuleSyntax); + addTargetFileImports(copiedFrom.file, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, originalProgram!.getTypeChecker(), updatedProgram!, importAdder); importAdder.writeFixes(changes, getQuotePreference(copiedFrom.file, preferences)); } else { diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 6bafe991aa42e..7b1c3b578a245 100644 --- a/src/services/refactors/moveToFile.ts +++ b/src/services/refactors/moveToFile.ts @@ -307,7 +307,8 @@ export function deleteUnusedOldImports(oldFile: SourceFile, toMove: readonly Sta } } -function addExportsInOldFile(oldFile: SourceFile, targetFileImportsFromOldFile: Map, changes: textChanges.ChangeTracker, useEsModuleSyntax: boolean) { +/** @internal */ +export function addExportsInOldFile(oldFile: SourceFile, targetFileImportsFromOldFile: Map, changes: textChanges.ChangeTracker, useEsModuleSyntax: boolean) { const markSeenTop = nodeSeenTracker(); // Needed because multiple declarations may appear in `const x = 0, y = 1;`. targetFileImportsFromOldFile.forEach((_, symbol) => { if (!symbol.declarations) { From 4ec4ccc34e0b6a99aa16e2e89264c0c72408d4ea Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 29 Apr 2024 10:59:23 -0700 Subject: [PATCH 31/41] fixing tests --- src/server/project.ts | 2 +- src/services/codefixes/importFixes.ts | 6 ++-- src/services/pasteEdits.ts | 18 +++++------- src/services/types.ts | 2 +- .../moveToFile_emptyTargetFile.js | 2 -- .../pasteEdits_existingImports1.js | 3 +- .../pasteEdits_existingImports2.js | 4 +-- .../pasteEdits_knownSourceFile.js | 3 +- .../pasteEdits_multiplePastes1.js | 3 +- .../pasteEdits_multiplePastes2.js | 5 +--- .../pasteEdits_multiplePastes3.js | 4 +-- .../pasteEdits_pasteComments.js | 3 +- .../pasteEdits_revertUpdatedFile.js | 3 +- .../pasteEdits_unknownSourceFile.js | 3 +- .../fourslash/moveToFile_existingImports1.ts | 28 ++++++------------- 15 files changed, 29 insertions(+), 60 deletions(-) diff --git a/src/server/project.ts b/src/server/project.ts index 036bba1898998..254c449303e98 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2239,7 +2239,7 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo } /** @internal */ - runWithTemporaryFileUpdate(rootFile: string, updatedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedFile: SourceFile) => void) { + runWithTemporaryFileUpdate(rootFile: string, updatedText: string, cb: (updatedProgram: Program, originalProgram: Program | undefined, updatedFile: SourceFile) => void) { const originalProgram = this.program; const originalText = this.program?.getSourceFile(rootFile)?.getText(); Debug.assert(this.program && this.program.getSourceFile(rootFile) && originalText); diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 46e24c7bd20be..37c04632808f6 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -894,7 +894,7 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } function isFutureSymbolExportInfoArray(info: readonly SymbolExportInfo[] | readonly FutureSymbolExportInfo[]): info is readonly FutureSymbolExportInfo[] { - return info[0].symbol === undefined; + return info[0].moduleSymbol === undefined; } function getImportFixes( @@ -1156,7 +1156,6 @@ function getNewImportFixes( host: LanguageServiceHost, preferences: UserPreferences, fromCacheOnly?: boolean, - targetFileImportFrom?: string[], ): { computedWithoutCacheCount: number; fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[]; } { const isJs = hasJSFileExtension(sourceFile.fileName); const compilerOptions = program.getCompilerOptions(); @@ -1231,10 +1230,9 @@ function getFixesForAddImport( host: LanguageServiceHost, preferences: UserPreferences, fromCacheOnly?: boolean, - targetFileImportFrom?: string[], ): { computedWithoutCacheCount?: number; fixes: readonly (FixAddNewImport | FixAddJsdocTypeImport)[]; } { const existingDeclaration = firstDefined(existingImports, info => newImportInfoFromExistingSpecifier(info, isValidTypeOnlyUseSite, useRequire, program.getTypeChecker(), program.getCompilerOptions())); - return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, usagePosition, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly, targetFileImportFrom); + return existingDeclaration ? { fixes: [existingDeclaration] } : getNewImportFixes(program, sourceFile, usagePosition, isValidTypeOnlyUseSite, useRequire, exportInfos, host, preferences, fromCacheOnly); } function newImportInfoFromExistingSpecifier( diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 47a17bbf022a5..1157306300a0f 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -1,6 +1,4 @@ -import { - addRange, -} from "../compiler/core"; +import { addRange } from "../compiler/core"; import { CancellationToken, SourceFile, @@ -9,9 +7,7 @@ import { TextRange, UserPreferences, } from "../compiler/types"; -import { - getLineOfLocalPosition, -} from "../compiler/utilities"; +import { getLineOfLocalPosition } from "../compiler/utilities"; import { codefix, Debug, @@ -82,11 +78,11 @@ function pasteEdits( addRange(statements, copiedFrom.file.statements, getLineOfLocalPosition(copiedFrom.file, copy.pos), getLineOfLocalPosition(copiedFrom.file, copy.end) + 1); }); const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); - const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); - //getTargetFileImportsAndAddExportInOldFile(copiedFrom.file, targetFile.fileName, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, changes, originalProgram!.getTypeChecker(), updatedProgram!, host, !fileShouldUseJavaScriptRequire(targetFile.fileName, updatedProgram!, host, !!copiedFrom.file.commonJsModuleIndicator), getQuotePreference(targetFile, preferences), importAdder); - const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram!, host, !!copiedFrom.file.commonJsModuleIndicator); + const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); + Debug.assertIsDefined(originalProgram); + const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram, host, !!copiedFrom.file.commonJsModuleIndicator); addExportsInOldFile(copiedFrom.file, usage.targetFileImportsFromOldFile, changes, useEsModuleSyntax); - addTargetFileImports(copiedFrom.file, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, originalProgram!.getTypeChecker(), updatedProgram!, importAdder); + addTargetFileImports(copiedFrom.file, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, originalProgram.getTypeChecker(), updatedProgram, importAdder); importAdder.writeFixes(changes, getQuotePreference(copiedFrom.file, preferences)); } else { @@ -98,7 +94,7 @@ function pasteEdits( preferences, formatContext, }; - const importAdder = codefix.createImportAdder(updatedFile, updatedProgram!, preferences, host); + const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); forEachChild(updatedFile, function cb(node) { if (isIdentifier(node)) { if (!originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { diff --git a/src/services/types.ts b/src/services/types.ts index 6b509221bbf06..bfa5632235845 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -431,7 +431,7 @@ export interface LanguageServiceHost extends GetEffectiveTypeRootsHost, MinimalR getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined; /** @internal */ onReleaseParsedCommandLine?(configFileName: string, oldResolvedRef: ResolvedProjectReference | undefined, optionOptions: CompilerOptions): void; /** @internal */ getIncompleteCompletionsCache?(): IncompleteCompletionsCache; - /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, updatedText: string, cb: (updatedProgram: Program | undefined, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void; + /** @internal */ runWithTemporaryFileUpdate?(rootFile: string, updatedText: string, cb: (updatedProgram: Program, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void; jsDocParsingMode?: JSDocParsingMode | undefined; } diff --git a/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js b/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js index bc608c3232147..78c59bc70c1c1 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/moveToFile_emptyTargetFile.js @@ -378,8 +378,6 @@ Info seq [hh:mm:ss:mss] request: }, "command": "getEditsForRefactor" } -Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results -Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js index 12d3801164a0d..bef391dfab032 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js @@ -38,8 +38,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js index 88a3594675a07..40a7470584611 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -44,8 +44,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: @@ -294,7 +293,6 @@ Info seq [hh:mm:ss:mss] Files (8) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms -Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js index 7fbe751de3aae..93b93e39f62b9 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -36,8 +36,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js index 178339c47b643..f23f68bdb4dd1 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js @@ -38,8 +38,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js index 4b9f8f18b623a..6cd4ff708c30e 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -40,8 +40,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: @@ -274,8 +273,6 @@ Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit -Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit -Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js index d93cda234b457..79077d9880fb2 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js @@ -43,8 +43,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: @@ -289,7 +288,6 @@ Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results Info seq [hh:mm:ss:mss] getExportInfoMap: done in * ms Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit -Info seq [hh:mm:ss:mss] getExportInfoMap: cache hit Info seq [hh:mm:ss:mss] response: { "seq": 0, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js index 6ce33e724cefa..e26bb6787148f 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js @@ -27,8 +27,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js index c29836d733319..3386cebb96943 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -36,8 +36,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /target.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js index 9d7878227fd8c..05a2c3289ac56 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js @@ -33,8 +33,7 @@ Info seq [hh:mm:ss:mss] request: }, "command": "open" } -Info seq [hh:mm:ss:mss] Search path: / -Info seq [hh:mm:ss:mss] For info: /file2.ts :: Config file name: /tsconfig.json +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /file2.ts ProjectRootPath: undefined:: Result: /tsconfig.json Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file Info seq [hh:mm:ss:mss] event: diff --git a/tests/cases/fourslash/moveToFile_existingImports1.ts b/tests/cases/fourslash/moveToFile_existingImports1.ts index b75549b94a2ed..35c5eb80a877e 100644 --- a/tests/cases/fourslash/moveToFile_existingImports1.ts +++ b/tests/cases/fourslash/moveToFile_existingImports1.ts @@ -2,33 +2,23 @@ // @filename: /common.ts ////export const x = 1; -////export const y = 2; // @filename: /a.ts -////export const t = 1; -////export const z = 2; -////const x = 3; -////export const q = 0; -////[|export const bar = z + x + q;|] +////import { x } from "./common"; +////[|export const bar = x;|] // @filename: /b.ts -////import { t, z } from "./a"; -////import { y } from "./common"; -////export const foo = t; +////import { x } from "./common"; +////export const foo = x; verify.moveToFile({ newFileContents: { - "/a.ts": `export const t = 1; -export const z = 2; -export const x = 3; -export const q = 0; -`, + "/a.ts": "", "/b.ts": -`import { q, t, x, z } from "./a"; -import { y } from "./common"; -export const foo = t; -export const bar = z + x + q; +`import { x } from "./common"; +export const foo = x; +export const bar = x; `, }, interactiveRefactorArguments: { targetFile: "/b.ts" }, -}); +}); \ No newline at end of file From 1a36951a73ac9654ca4372547ecff674de51bf12 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Mon, 29 Apr 2024 11:20:18 -0700 Subject: [PATCH 32/41] small fixes --- src/services/pasteEdits.ts | 3 +-- .../fourslash/moveToFile_expandSelectionRange4.ts | 15 ++++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 1157306300a0f..f259183db2032 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -72,13 +72,13 @@ function pasteEdits( } }); host.runWithTemporaryFileUpdate?.(targetFile.fileName, newText, (updatedProgram, originalProgram, updatedFile) => { + const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); if (copiedFrom?.range) { Debug.assert(copiedFrom.range.length === pastedText.length); copiedFrom.range.forEach(copy => { addRange(statements, copiedFrom.file.statements, getLineOfLocalPosition(copiedFrom.file, copy.pos), getLineOfLocalPosition(copiedFrom.file, copy.end) + 1); }); const usage = getUsageInfo(copiedFrom.file, statements, originalProgram!.getTypeChecker(), getExistingLocals(updatedFile, statements, originalProgram!.getTypeChecker())); - const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); Debug.assertIsDefined(originalProgram); const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram, host, !!copiedFrom.file.commonJsModuleIndicator); addExportsInOldFile(copiedFrom.file, usage.targetFileImportsFromOldFile, changes, useEsModuleSyntax); @@ -94,7 +94,6 @@ function pasteEdits( preferences, formatContext, }; - const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); forEachChild(updatedFile, function cb(node) { if (isIdentifier(node)) { if (!originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { diff --git a/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts b/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts index 9ab57082ab138..b3ccd1be8fe5d 100644 --- a/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts +++ b/tests/cases/fourslash/moveToFile_expandSelectionRange4.ts @@ -5,7 +5,6 @@ ////const t = b; // @Filename: /a.ts -////import { c } from './other'; //// interface T { //// a: number //// } @@ -16,18 +15,16 @@ // @Filename: /other.ts ////export const b = 2; -////export const c = 3; verify.moveToFile({ newFileContents: { "/a.ts": -`import { c } from './other'; - interface T { - a: number - } - export const x: T={ - a: 1 - }; +`interface T { + a: number +} +export const x: T={ + a: 1 +}; `, "/bar.ts": From 4d37a0647421e9c0440fe8029bdb7d4c9231cb6d Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 30 Apr 2024 11:34:10 -0700 Subject: [PATCH 33/41] Adressing pr comments --- src/services/pasteEdits.ts | 56 +++++++++---------- .../pasteEdits_existingImports1.js | 2 +- .../pasteEdits_existingImports2.js | 2 +- .../pasteEdits_knownSourceFile.js | 34 +++++------ .../pasteEdits_multiplePastes1.js | 2 +- .../pasteEdits_multiplePastes2.js | 2 +- .../pasteEdits_multiplePastes3.js | 34 +++++------ .../pasteEdits_pasteComments.js | 2 +- .../pasteEdits_revertUpdatedFile.js | 2 +- .../pasteEdits_unknownSourceFile.js | 2 +- 10 files changed, 66 insertions(+), 72 deletions(-) diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index f259183db2032..84f1709af109f 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -58,19 +58,30 @@ function pasteEdits( cancellationToken: CancellationToken, changes: textChanges.ChangeTracker, ) { + if (pastedText.length !== 1) { + Debug.assert(pastedText.length === pasteLocations.length); + } + pasteLocations.forEach((paste, i) => { + changes.replaceRangeWithText( + targetFile, + { pos: paste.pos, end: paste.end }, + pastedText.length === 1 ? + pastedText[0] : pastedText[i], + ); + }); + const statements: Statement[] = []; - let start = 0; + let i = pasteLocations.length - 1; + let end = targetFile.text.length - 1; let newText = ""; - pasteLocations.forEach((location, i) => { - if (i === pasteLocations.length - 1) { - newText += targetFile.text.slice(start, location.pos) + pastedText[i] + targetFile.text.slice(location.end); - } - else { - newText += targetFile.text.slice(start, location.pos) + pastedText[i]; - start = location.end; - } + pasteLocations.reverse().forEach(location => { + newText = pastedText[i] + targetFile.text.slice(location.end, end) + newText; + end = location.pos; + i--; }); + newText = targetFile.text.slice(0, end) + newText; + host.runWithTemporaryFileUpdate?.(targetFile.fileName, newText, (updatedProgram, originalProgram, updatedFile) => { const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); if (copiedFrom?.range) { @@ -83,7 +94,6 @@ function pasteEdits( const useEsModuleSyntax = !fileShouldUseJavaScriptRequire(targetFile.fileName, originalProgram, host, !!copiedFrom.file.commonJsModuleIndicator); addExportsInOldFile(copiedFrom.file, usage.targetFileImportsFromOldFile, changes, useEsModuleSyntax); addTargetFileImports(copiedFrom.file, usage.oldImportsNeededByTargetFile, usage.targetFileImportsFromOldFile, originalProgram.getTypeChecker(), updatedProgram, importAdder); - importAdder.writeFixes(changes, getQuotePreference(copiedFrom.file, preferences)); } else { const context: CodeFixContextBase = { @@ -95,29 +105,13 @@ function pasteEdits( formatContext, }; forEachChild(updatedFile, function cb(node) { - if (isIdentifier(node)) { - if (!originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { - // generate imports - importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true); - } - } - else { - node.forEachChild(cb); + if (isIdentifier(node) && !originalProgram?.getTypeChecker().resolveName(node.text, node, SymbolFlags.All, /*excludeGlobals*/ false)) { + // generate imports + importAdder.addImportForUnresolvedIdentifier(context, node, /*useAutoImportProvider*/ true); } + node.forEachChild(cb); }); - importAdder.writeFixes(changes, getQuotePreference(targetFile, preferences)); } - }); - - if (pastedText.length !== 1) { - Debug.assert(pastedText.length === pasteLocations.length); - } - pasteLocations.forEach((paste, i) => { - changes.replaceRangeWithText( - targetFile, - { pos: paste.pos, end: paste.end }, - pastedText.length === 1 ? - pastedText[0] : pastedText[i], - ); + importAdder.writeFixes(changes, getQuotePreference(copiedFrom ? copiedFrom.file : targetFile, preferences)); }); } diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js index bef391dfab032..3df2bc5e09d72 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js @@ -252,7 +252,7 @@ Info seq [hh:mm:ss:mss] Files (7) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const t = 1;" /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10" /other2.ts Text-1 "export const t2 = 1;" Info seq [hh:mm:ss:mss] ----------------------------------------------- diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js index 40a7470584611..d5eecf186002f 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -286,7 +286,7 @@ Info seq [hh:mm:ss:mss] Files (8) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const t = 1;" /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10;" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10" /other2.ts Text-1 "export const t2 = 1;" /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js index 93b93e39f62b9..7d9e3ea7bcbd3 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -253,7 +253,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export const b = 2;" /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1;" + /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results @@ -270,22 +270,6 @@ Info seq [hh:mm:ss:mss] response: }, "body": { "edits": [ - { - "fileName": "/file2.ts", - "textChanges": [ - { - "start": { - "line": 2, - "offset": 1 - }, - "end": { - "line": 2, - "offset": 1 - }, - "newText": "export " - } - ] - }, { "fileName": "/target.ts", "textChanges": [ @@ -312,6 +296,22 @@ Info seq [hh:mm:ss:mss] response: "newText": "const c = a + b;\nconst t = 9;" } ] + }, + { + "fileName": "/file2.ts", + "textChanges": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "export " + } + ] } ], "fixId": "providePostPasteEdits" diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js index f23f68bdb4dd1..b6879169240bc 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js @@ -248,7 +248,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" - /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\nundefined\nconst d = 4;" + /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\nundefined\nconst d = 4" /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" Info seq [hh:mm:ss:mss] ----------------------------------------------- diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js index 6cd4ff708c30e..3cd47d6b5e987 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -267,7 +267,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nundefined\nconst d = 4;" + /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nundefined\nconst d = 4" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js index 79077d9880fb2..4c8decf94a14b 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js @@ -282,7 +282,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nconst s = 12;\nexport const m = 10;\nexport const t = aa + bb + r + s;\nconst u = 1;\nexport const k = r + m;" - /target.ts SVC-1-1 "import { r } from \"./file1\";\nconst a = r;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nexport const k = r + m;\nconst d = 4;" + /target.ts SVC-1-1 "import { r } from \"./file1\";\nconst a = r;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nexport const k = r + m;\nconst d = 4" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results @@ -300,22 +300,6 @@ Info seq [hh:mm:ss:mss] response: }, "body": { "edits": [ - { - "fileName": "/file1.ts", - "textChanges": [ - { - "start": { - "line": 3, - "offset": 1 - }, - "end": { - "line": 3, - "offset": 1 - }, - "newText": "export " - } - ] - }, { "fileName": "/target.ts", "textChanges": [ @@ -375,6 +359,22 @@ Info seq [hh:mm:ss:mss] response: "newText": "export const k = r + m;" } ] + }, + { + "fileName": "/file1.ts", + "textChanges": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "export " + } + ] } ], "fixId": "providePostPasteEdits" diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js index e26bb6787148f..68e43f1999e77 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js @@ -204,7 +204,7 @@ Info seq [hh:mm:ss:mss] Files (4) /lib.d.ts Text-1 lib.d.ts-Text /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10;" + /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js index 3386cebb96943..c27f997d8d60e 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -237,7 +237,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const t = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as " + /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as" /other2.ts Text-1 "export const t2 = 1;" Info seq [hh:mm:ss:mss] ----------------------------------------------- diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js index 05a2c3289ac56..d398d6b70566b 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js @@ -222,7 +222,7 @@ Info seq [hh:mm:ss:mss] Files (5) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10;" + /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: From 66ca5be52001fb43de568bf9a1a29ebb077e3882 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 30 Apr 2024 15:30:05 -0700 Subject: [PATCH 34/41] adressing pr comments --- src/server/session.ts | 5 +- src/services/pasteEdits.ts | 10 +- src/testRunner/tests.ts | 1 + .../unittests/tsserver/pasteEdits.ts | 44 +++ .../tsserver/pasteEdits/adds-paste-edits.js | 270 ++++++++++++++++++ .../postPasteEdits/adds-post-paste-edits.js | 270 ++++++++++++++++++ ...g-and-reverting-changes-added-to-a-file.js | 270 ++++++++++++++++++ 7 files changed, 860 insertions(+), 10 deletions(-) create mode 100644 src/testRunner/unittests/tsserver/pasteEdits.ts create mode 100644 tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js create mode 100644 tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js create mode 100644 tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js diff --git a/src/server/session.ts b/src/server/session.ts index f5889e0c7c0a2..f9b517adb8f2c 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2812,10 +2812,7 @@ export class Session implements EventSender { }, this.getFormatOptions(file), ); - if (result === undefined) { - return undefined; - } - return this.mapPasteEditsAction(result); + return result && this.mapPasteEditsAction(result); } private organizeImports(args: protocol.OrganizeImportsRequestArgs, simplifiedResult: boolean): readonly protocol.FileCodeEdits[] | readonly FileTextChanges[] { diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 84f1709af109f..d825268202dbc 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -72,14 +72,12 @@ function pasteEdits( const statements: Statement[] = []; - let i = pasteLocations.length - 1; let end = targetFile.text.length - 1; let newText = ""; - pasteLocations.reverse().forEach(location => { - newText = pastedText[i] + targetFile.text.slice(location.end, end) + newText; - end = location.pos; - i--; - }); + for (let i = pasteLocations.length - 1; i >= 0; i--) { + newText = pastedText[i] + targetFile.text.slice(pasteLocations[i].end, end) + newText; + end = pasteLocations[i].pos; + } newText = targetFile.text.slice(0, end) + newText; host.runWithTemporaryFileUpdate?.(targetFile.fileName, newText, (updatedProgram, originalProgram, updatedFile) => { diff --git a/src/testRunner/tests.ts b/src/testRunner/tests.ts index c211d221aa4c9..7acf3ad6ed40a 100644 --- a/src/testRunner/tests.ts +++ b/src/testRunner/tests.ts @@ -217,3 +217,4 @@ import "./unittests/debugDeprecation"; import "./unittests/tsserver/inconsistentErrorInEditor"; import "./unittests/tsserver/getMoveToRefactoringFileSuggestions"; import "./unittests/skipJSDocParsing"; +import "./unittests/tsserver/pasteEdits"; diff --git a/src/testRunner/unittests/tsserver/pasteEdits.ts b/src/testRunner/unittests/tsserver/pasteEdits.ts new file mode 100644 index 0000000000000..3c7918fb30574 --- /dev/null +++ b/src/testRunner/unittests/tsserver/pasteEdits.ts @@ -0,0 +1,44 @@ +import * as ts from "../../_namespaces/ts"; +import { + baselineTsserverLogs, + openFilesForSession, + TestSession, + verifyGetErrRequest, +} from "../helpers/tsserver"; +import { + createServerHost, + File, +} from "../helpers/virtualFileSystemWithWatch"; + +describe("unittests:: tsserver:: pasteEdits", () => { + it("adds paste edits", () => { + const target: File = { + path: "/project/a/target.ts", + content: `const a = 1; +const b = 2; +const c = 3;`, + }; + const tsconfig: File = { + path: "/project/tsconfig.json", + content: "{}", + }; + const pastedText = `const q = 1; +function e(); +const f = r + s;`; + + const host = createServerHost([target, tsconfig]); + const session = new TestSession(host); + openFilesForSession([target], session); + + session.executeCommandSeq({ + command: ts.server.protocol.CommandTypes.GetPasteEdits, + arguments: { + file: target.path, + pastedText: [pastedText], + pasteLocations: [{ start: { line: 2, offset: 0 }, end: { line: 2, offset: 0 } }], + }, + }); + baselineTsserverLogs("pasteEdits", "adds paste edits", session); + verifyGetErrRequest({ session, files: [target.path] }); + }); +}); diff --git a/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js new file mode 100644 index 0000000000000..9eb2f1ac13994 --- /dev/null +++ b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js @@ -0,0 +1,270 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +Before request +//// [/project/a/target.ts] +const a = 1; +const b = 2; +const c = 3; + +//// [/project/tsconfig.json] +{} + + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/project/a/target.ts" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /project/a/target.ts ProjectRootPath: undefined:: Result: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/project/tsconfig.json", + "reason": "Creating possible configured project for /project/a/target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { + "rootNames": [ + "/project/a/target.ts" + ], + "options": { + "configFilePath": "/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" + + + a/target.ts + Matched by default include pattern '**/*' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "telemetry", + "body": { + "telemetryEventName": "projectInfo", + "payload": { + "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", + "fileStats": { + "js": 0, + "jsSize": 0, + "jsx": 0, + "jsxSize": 0, + "ts": 1, + "tsSize": 38, + "tsx": 0, + "tsxSize": 0, + "dts": 0, + "dtsSize": 0, + "deferred": 0, + "deferredSize": 0 + }, + "compilerOptions": {}, + "typeAcquisition": { + "enable": false, + "include": false, + "exclude": false + }, + "extends": false, + "files": false, + "include": false, + "exclude": false, + "compileOnSave": false, + "configFileName": "tsconfig.json", + "projectType": "configured", + "languageServiceEnabled": true, + "version": "FakeVersion" + } + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/project/a/target.ts", + "configFile": "/project/tsconfig.json", + "diagnostics": [ + { + "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +PolledWatches:: +/a/lib/lib.d.ts: *new* + {"pollingInterval":500} + +FsWatches:: +/project/tsconfig.json: *new* + {} + +FsWatchesRecursive:: +/project: *new* + {} + +Projects:: +/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/project/a/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /project/tsconfig.json *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "getPasteEdits", + "arguments": { + "file": "/project/a/target.ts", + "pastedText": [ + "const q = 1;\nfunction e();\nconst f = r + s;" + ], + "pasteLocations": [ + { + "start": { + "line": 2, + "offset": 0 + }, + "end": { + "line": 2, + "offset": 0 + } + } + ] + }, + "seq": 2, + "type": "request" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "response": { + "edits": [ + { + "fileName": "/project/a/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 13 + }, + "end": { + "line": 1, + "offset": 13 + }, + "newText": "const q = 1;\nfunction e();\nconst f = r + s;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + }, + "responseRequired": true + } +After request + +Projects:: +/project/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/project/a/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /project/tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js b/tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js new file mode 100644 index 0000000000000..9eb2f1ac13994 --- /dev/null +++ b/tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js @@ -0,0 +1,270 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +Before request +//// [/project/a/target.ts] +const a = 1; +const b = 2; +const c = 3; + +//// [/project/tsconfig.json] +{} + + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/project/a/target.ts" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /project/a/target.ts ProjectRootPath: undefined:: Result: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/project/tsconfig.json", + "reason": "Creating possible configured project for /project/a/target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { + "rootNames": [ + "/project/a/target.ts" + ], + "options": { + "configFilePath": "/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" + + + a/target.ts + Matched by default include pattern '**/*' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "telemetry", + "body": { + "telemetryEventName": "projectInfo", + "payload": { + "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", + "fileStats": { + "js": 0, + "jsSize": 0, + "jsx": 0, + "jsxSize": 0, + "ts": 1, + "tsSize": 38, + "tsx": 0, + "tsxSize": 0, + "dts": 0, + "dtsSize": 0, + "deferred": 0, + "deferredSize": 0 + }, + "compilerOptions": {}, + "typeAcquisition": { + "enable": false, + "include": false, + "exclude": false + }, + "extends": false, + "files": false, + "include": false, + "exclude": false, + "compileOnSave": false, + "configFileName": "tsconfig.json", + "projectType": "configured", + "languageServiceEnabled": true, + "version": "FakeVersion" + } + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/project/a/target.ts", + "configFile": "/project/tsconfig.json", + "diagnostics": [ + { + "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +PolledWatches:: +/a/lib/lib.d.ts: *new* + {"pollingInterval":500} + +FsWatches:: +/project/tsconfig.json: *new* + {} + +FsWatchesRecursive:: +/project: *new* + {} + +Projects:: +/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/project/a/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /project/tsconfig.json *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "getPasteEdits", + "arguments": { + "file": "/project/a/target.ts", + "pastedText": [ + "const q = 1;\nfunction e();\nconst f = r + s;" + ], + "pasteLocations": [ + { + "start": { + "line": 2, + "offset": 0 + }, + "end": { + "line": 2, + "offset": 0 + } + } + ] + }, + "seq": 2, + "type": "request" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "response": { + "edits": [ + { + "fileName": "/project/a/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 13 + }, + "end": { + "line": 1, + "offset": 13 + }, + "newText": "const q = 1;\nfunction e();\nconst f = r + s;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + }, + "responseRequired": true + } +After request + +Projects:: +/project/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/project/a/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /project/tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js b/tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js new file mode 100644 index 0000000000000..9eb2f1ac13994 --- /dev/null +++ b/tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js @@ -0,0 +1,270 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +Before request +//// [/project/a/target.ts] +const a = 1; +const b = 2; +const c = 3; + +//// [/project/tsconfig.json] +{} + + +Info seq [hh:mm:ss:mss] request: + { + "command": "open", + "arguments": { + "file": "/project/a/target.ts" + }, + "seq": 1, + "type": "request" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /project/a/target.ts ProjectRootPath: undefined:: Result: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/project/tsconfig.json", + "reason": "Creating possible configured project for /project/a/target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { + "rootNames": [ + "/project/a/target.ts" + ], + "options": { + "configFilePath": "/project/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" + + + a/target.ts + Matched by default include pattern '**/*' + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/project/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "telemetry", + "body": { + "telemetryEventName": "projectInfo", + "payload": { + "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", + "fileStats": { + "js": 0, + "jsSize": 0, + "jsx": 0, + "jsxSize": 0, + "ts": 1, + "tsSize": 38, + "tsx": 0, + "tsxSize": 0, + "dts": 0, + "dtsSize": 0, + "deferred": 0, + "deferredSize": 0 + }, + "compilerOptions": {}, + "typeAcquisition": { + "enable": false, + "include": false, + "exclude": false + }, + "extends": false, + "files": false, + "include": false, + "exclude": false, + "compileOnSave": false, + "configFileName": "tsconfig.json", + "projectType": "configured", + "languageServiceEnabled": true, + "version": "FakeVersion" + } + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/project/a/target.ts", + "configFile": "/project/tsconfig.json", + "diagnostics": [ + { + "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", + "code": 6053, + "category": "error" + }, + { + "text": "Cannot find global type 'Array'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Boolean'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Function'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'IArguments'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Number'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'Object'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'RegExp'.", + "code": 2318, + "category": "error" + }, + { + "text": "Cannot find global type 'String'.", + "code": 2318, + "category": "error" + } + ] + } + } +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +PolledWatches:: +/a/lib/lib.d.ts: *new* + {"pollingInterval":500} + +FsWatches:: +/project/tsconfig.json: *new* + {} + +FsWatchesRecursive:: +/project: *new* + {} + +Projects:: +/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/project/a/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /project/tsconfig.json *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "getPasteEdits", + "arguments": { + "file": "/project/a/target.ts", + "pastedText": [ + "const q = 1;\nfunction e();\nconst f = r + s;" + ], + "pasteLocations": [ + { + "start": { + "line": 2, + "offset": 0 + }, + "end": { + "line": 2, + "offset": 0 + } + } + ] + }, + "seq": 2, + "type": "request" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (1) + /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "response": { + "edits": [ + { + "fileName": "/project/a/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 13 + }, + "end": { + "line": 1, + "offset": 13 + }, + "newText": "const q = 1;\nfunction e();\nconst f = r + s;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + }, + "responseRequired": true + } +After request + +Projects:: +/project/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/project/a/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /project/tsconfig.json *default* From e8189c3d37cc39b171348d5d0477b04a1993c499 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 30 Apr 2024 15:42:56 -0700 Subject: [PATCH 35/41] adding `getPasteEdits` to session.ts and services.ts --- src/server/session.ts | 1 + src/services/services.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/src/server/session.ts b/src/server/session.ts index f9b517adb8f2c..aa4192191bc7e 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -911,6 +911,7 @@ const invalidPartialSemanticModeCommands: readonly protocol.CommandTypes[] = [ protocol.CommandTypes.PrepareCallHierarchy, protocol.CommandTypes.ProvideCallHierarchyIncomingCalls, protocol.CommandTypes.ProvideCallHierarchyOutgoingCalls, + protocol.CommandTypes.GetPasteEdits, ]; const invalidSyntacticModeCommands: readonly protocol.CommandTypes[] = [ diff --git a/src/services/services.ts b/src/services/services.ts index 8c948e1f8a4c4..30a0410569ea5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1576,6 +1576,7 @@ const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[] "provideCallHierarchyOutgoingCalls", "provideInlayHints", "getSupportedCodeFixes", + "getPasteEdits", ]; const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [ From 213587edc3dcca541aaf95da2d5954d645dcd465 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Wed, 1 May 2024 12:33:41 -0700 Subject: [PATCH 36/41] adding changes to handle pasted text --- src/services/pasteEdits.ts | 17 +- .../pasteEdits_existingImports1.js | 2 +- .../pasteEdits_existingImports2.js | 2 +- .../pasteEdits_knownSourceFile.js | 2 +- .../pasteEdits_multiplePastes1.js | 2 +- .../pasteEdits_multiplePastes2.js | 2 +- .../pasteEdits_multiplePastes3.js | 2 +- .../pasteEdits_multiplePastes4.js | 362 ++++++++++++++++++ .../pasteEdits_pasteComments.js | 2 +- .../pasteEdits_revertUpdatedFile.js | 2 +- .../pasteEdits_unknownSourceFile.js | 2 +- .../tsserver/pasteEdits/adds-paste-edits.js | 2 +- .../server/pasteEdits_multiplePastes4.ts | 45 +++ 13 files changed, 425 insertions(+), 19 deletions(-) create mode 100644 tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes4.js create mode 100644 tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index d825268202dbc..07806f79d3c35 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -58,27 +58,26 @@ function pasteEdits( cancellationToken: CancellationToken, changes: textChanges.ChangeTracker, ) { - if (pastedText.length !== 1) { - Debug.assert(pastedText.length === pasteLocations.length); + let actualPastedText: string[] | undefined; + if (pastedText.length !== pasteLocations.length) { + actualPastedText = pastedText.length === 1 ? pastedText : [pastedText.join("\n")]; } pasteLocations.forEach((paste, i) => { changes.replaceRangeWithText( targetFile, { pos: paste.pos, end: paste.end }, - pastedText.length === 1 ? - pastedText[0] : pastedText[i], + actualPastedText ? + actualPastedText[0] : pastedText[i], ); }); const statements: Statement[] = []; - let end = targetFile.text.length - 1; - let newText = ""; + let newText = targetFile.text; for (let i = pasteLocations.length - 1; i >= 0; i--) { - newText = pastedText[i] + targetFile.text.slice(pasteLocations[i].end, end) + newText; - end = pasteLocations[i].pos; + const { pos, end } = pasteLocations[i]; + newText = actualPastedText ? newText.slice(0, pos) + actualPastedText[0] + newText.slice(end) : newText.slice(0, pos) + pastedText[i] + newText.slice(end); } - newText = targetFile.text.slice(0, end) + newText; host.runWithTemporaryFileUpdate?.(targetFile.fileName, newText, (updatedProgram, originalProgram, updatedFile) => { const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js index 3df2bc5e09d72..bef391dfab032 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js @@ -252,7 +252,7 @@ Info seq [hh:mm:ss:mss] Files (7) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const t = 1;" /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + 1;\nconst c = 10;" /other2.ts Text-1 "export const t2 = 1;" Info seq [hh:mm:ss:mss] ----------------------------------------------- diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js index d5eecf186002f..40a7470584611 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -286,7 +286,7 @@ Info seq [hh:mm:ss:mss] Files (8) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const t = 1;" /other3.ts Text-1 "export const t3 = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10" + /target.ts SVC-1-1 "import { t } from \"./other\";\nimport { t3 } from \"./other3\";\nconst a = t + 1;\nconst m = t3 + t2 + n;\nconst c = 10;" /other2.ts Text-1 "export const t2 = 1;" /originalFile.ts Text-1 "import { t2 } from \"./other2\";\nimport { t3 } from \"./other3\";\nexport const n = 10;\nexport const m = t3 + t2 + n;" diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js index 7d9e3ea7bcbd3..89409a7a6bade 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -253,7 +253,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export const b = 2;" /file2.ts Text-1 "import { b } from './file1';\nconst a = 1;\nconst c = a + b;\nconst t = 9;" - /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1" + /target.ts SVC-1-1 "export const tt = 2;\nconst c = a + b;\nconst t = 9;\nconst p = 1;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js index b6879169240bc..c5dfc949fa58c 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js @@ -248,7 +248,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" - /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\nundefined\nconst d = 4" + /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;\nconst g = p + q;\nfunction e();\nconst f = r + s;\nconst d = 4;" /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" Info seq [hh:mm:ss:mss] ----------------------------------------------- diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js index 3cd47d6b5e987..62152ca4c2af2 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -267,7 +267,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nexport const s = 12;\nexport const t = aa + bb + r + s;\nconst u = 1;" - /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nundefined\nconst d = 4" + /target.ts SVC-1-1 "const a = 1;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst d = 4;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js index 4c8decf94a14b..f7eae4167992e 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js @@ -282,7 +282,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const aa = 1;\nexport const bb = 2;" /file1.ts Text-1 "import { aa, bb } from \"./other\";\nexport const r = 10;\nconst s = 12;\nexport const m = 10;\nexport const t = aa + bb + r + s;\nconst u = 1;\nexport const k = r + m;" - /target.ts SVC-1-1 "import { r } from \"./file1\";\nconst a = r;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nexport const k = r + m;\nconst d = 4" + /target.ts SVC-1-1 "import { r } from \"./file1\";\nconst a = r;\nexport const t = aa + bb + r + s;\nconst u = 1;\nconst c = 3;\nexport const k = r + m;\nconst d = 4;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] getExportInfoMap: cache miss or empty; calculating new results diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes4.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes4.js new file mode 100644 index 0000000000000..8f4c307eb1372 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes4.js @@ -0,0 +1,362 @@ +currentDirectory:: / useCaseSensitiveFileNames: false +Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist +//// [/file1.ts] +export const p = 10; +export const q = 12; + +//// [/file3.ts] +export const r = 10; +export const s = 12; + +//// [/lib.d.ts] +lib.d.ts-Text + +//// [/lib.decorators.d.ts] +lib.decorators.d.ts-Text + +//// [/lib.decorators.legacy.d.ts] +lib.decorators.legacy.d.ts-Text + +//// [/target.ts] +const a = 1; + +const b = 2; +const c = 3; + +const d = 4; + +//// [/tsconfig.json] +{ "files": ["file1.ts", "target.ts", "file3.ts"] } + + +Info seq [hh:mm:ss:mss] request: + { + "seq": 0, + "type": "request", + "arguments": { + "file": "/target.ts" + }, + "command": "open" + } +Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /target.ts ProjectRootPath: undefined:: Result: /tsconfig.json +Info seq [hh:mm:ss:mss] Creating configuration project /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /tsconfig.json 2000 undefined Project: /tsconfig.json WatchType: Config file +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingStart", + "body": { + "projectName": "/tsconfig.json", + "reason": "Creating possible configured project for /target.ts to open" + } + } +Info seq [hh:mm:ss:mss] Config: /tsconfig.json : { + "rootNames": [ + "/file1.ts", + "/target.ts", + "/file3.ts" + ], + "options": { + "configFilePath": "/tsconfig.json" + } +} +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file1.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /file3.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /lib.decorators.legacy.d.ts 500 undefined WatchType: Closed Script info +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-0 "const a = 1;\n\nconst b = 2;\nconst c = 3;\n\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + + + lib.d.ts + Default library for target 'es5' + lib.decorators.d.ts + Library referenced via 'decorators' from file 'lib.d.ts' + lib.decorators.legacy.d.ts + Library referenced via 'decorators.legacy' from file 'lib.d.ts' + file1.ts + Part of 'files' list in tsconfig.json + target.ts + Part of 'files' list in tsconfig.json + file3.ts + Part of 'files' list in tsconfig.json + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "projectLoadingFinish", + "body": { + "projectName": "/tsconfig.json" + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "configFileDiag", + "body": { + "triggerFile": "/target.ts", + "configFile": "/tsconfig.json", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] Open files: +Info seq [hh:mm:ss:mss] FileName: /target.ts ProjectRootPath: undefined +Info seq [hh:mm:ss:mss] Projects: /tsconfig.json +After Request +watchedFiles:: +/file1.ts: *new* + {"pollingInterval":500} +/file3.ts: *new* + {"pollingInterval":500} +/lib.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.d.ts: *new* + {"pollingInterval":500} +/lib.decorators.legacy.d.ts: *new* + {"pollingInterval":500} +/tsconfig.json: *new* + {"pollingInterval":2000} + +Projects:: +/tsconfig.json (Configured) *new* + projectStateVersion: 1 + projectProgramVersion: 1 + +ScriptInfos:: +/file1.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file3.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts *new* + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *new* + version: SVC-1-0 + containingProjects: 1 + /tsconfig.json *default* + +Info seq [hh:mm:ss:mss] request: + { + "seq": 1, + "type": "request", + "arguments": { + "formatOptions": { + "indentSize": 4, + "tabSize": 4, + "newLineCharacter": "\n", + "convertTabsToSpaces": true, + "indentStyle": 2, + "insertSpaceAfterConstructor": false, + "insertSpaceAfterCommaDelimiter": true, + "insertSpaceAfterSemicolonInForStatements": true, + "insertSpaceBeforeAndAfterBinaryOperators": true, + "insertSpaceAfterKeywordsInControlFlowStatements": true, + "insertSpaceAfterFunctionKeywordForAnonymousFunctions": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyParenthesis": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBrackets": false, + "insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": true, + "insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": false, + "insertSpaceAfterOpeningAndBeforeClosingJsxExpressionBraces": false, + "insertSpaceBeforeFunctionParenthesis": false, + "placeOpenBraceOnNewLineForFunctions": false, + "placeOpenBraceOnNewLineForControlBlocks": false, + "semicolons": "ignore", + "trimTrailingWhitespace": true, + "indentSwitchCase": true + } + }, + "command": "configure" + } +Info seq [hh:mm:ss:mss] Format host information updated +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "configure", + "request_seq": 1, + "success": true + } +Info seq [hh:mm:ss:mss] request: + { + "seq": 2, + "type": "request", + "arguments": { + "file": "/target.ts", + "pastedText": [ + "const g = p + q;", + "const f = r + s;" + ], + "pasteLocations": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + } + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 13 + } + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + } + } + ] + }, + "command": "getPasteEdits" + } +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (6) + /lib.d.ts Text-1 lib.d.ts-Text + /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text + /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text + /file1.ts Text-1 "export const p = 10;\nexport const q = 12;" + /target.ts SVC-1-1 "const a = 1;\nconst g = p + q;\nconst f = r + s;\nconst g = p + q;\nconst f = r + s;\nconst c = 3;\nconst g = p + q;\nconst f = r + s;\nconst d = 4;" + /file3.ts Text-1 "export const r = 10;\nexport const s = 12;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] response: + { + "seq": 0, + "type": "response", + "command": "getPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "fileName": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { p, q } from \"./file1\";\nimport { r, s } from \"./file3\";\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 1 + }, + "newText": "const g = p + q;\nconst f = r + s;" + }, + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 13 + }, + "newText": "const g = p + q;\nconst f = r + s;" + }, + { + "start": { + "line": 5, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 1 + }, + "newText": "const g = p + q;\nconst f = r + s;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +After Request +Projects:: +/tsconfig.json (Configured) *changed* + projectStateVersion: 3 *changed* + projectProgramVersion: 1 + dirty: true *changed* + +ScriptInfos:: +/file1.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/file3.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/lib.decorators.legacy.d.ts + version: Text-1 + containingProjects: 1 + /tsconfig.json +/target.ts (Open) *changed* + version: SVC-1-2 *changed* + containingProjects: 1 + /tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js index 68e43f1999e77..e26bb6787148f 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js @@ -204,7 +204,7 @@ Info seq [hh:mm:ss:mss] Files (4) /lib.d.ts Text-1 lib.d.ts-Text /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text - /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10" + /target.ts SVC-1-1 "const a = 10;\nconst b = 10;/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/\nconst c = 10;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js index c27f997d8d60e..3386cebb96943 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -237,7 +237,7 @@ Info seq [hh:mm:ss:mss] Files (6) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /other.ts Text-1 "export const t = 1;" - /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as" + /target.ts SVC-1-1 "import { t } from \"./other\";\nconst a = t + 1;\nconst m = t2 + 1;\ntype T = number;\nvar x;\nvar y = x as " /other2.ts Text-1 "export const t2 = 1;" Info seq [hh:mm:ss:mss] ----------------------------------------------- diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js index d398d6b70566b..05a2c3289ac56 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js @@ -222,7 +222,7 @@ Info seq [hh:mm:ss:mss] Files (5) /lib.decorators.d.ts Text-1 lib.decorators.d.ts-Text /lib.decorators.legacy.d.ts Text-1 lib.decorators.legacy.d.ts-Text /file1.ts Text-1 "export interface Test1 {}\nexport interface Test2 {}\nexport interface Test3 {}\nexport interface Test4 {}" - /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10" + /file2.ts SVC-1-1 "const a = 10;\nconst b = 10;\ninterface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }const c = 10;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: diff --git a/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js index 9eb2f1ac13994..f2b70920c6dfa 100644 --- a/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js +++ b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js @@ -227,7 +227,7 @@ Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig. Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3" + /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;" Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] response: diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts new file mode 100644 index 0000000000000..46a83b0365929 --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts @@ -0,0 +1,45 @@ +/// + +// @Filename: /target.ts +//// const a = 1; +//// [||] +//// [|const b = 2;|] +//// const c = 3; +//// [||] +//// const d = 4; + +// @Filename: /file1.ts +//// export const p = 10; +//// export const q = 12; + +// @Filename: /file3.ts +//// export const r = 10; +//// export const s = 12; + +// @Filename: /tsconfig.json +////{ "files": ["file1.ts", "target.ts", "file3.ts"] } + +const range = test.ranges(); +format.setOption("insertSpaceAfterSemicolonInForStatements", true); +verify.pasteEdits({ + args: { + pastedText: [ "const g = p + q;", "const f = r + s;"], + pasteLocations: [range[0], range[1], range[2]], + }, + newFileContents: { + "/target.ts": +`import { p, q } from "./file1"; +import { r, s } from "./file3"; + +const a = 1; +const g = p + q; +const f = r + s; +const g = p + q; +const f = r + s; +const c = 3; +const g = p + q; +const f = r + s; +const d = 4;` + }, + fixId: "providePostPasteEdits" +}); \ No newline at end of file From 68ce405fc2e7c1b71b8ba556647b66947458e4e8 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Wed, 1 May 2024 12:38:06 -0700 Subject: [PATCH 37/41] Removing baselines for deleted tests --- .../postPasteEdits/adds-post-paste-edits.js | 270 ------------------ ...g-and-reverting-changes-added-to-a-file.js | 270 ------------------ 2 files changed, 540 deletions(-) delete mode 100644 tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js delete mode 100644 tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js diff --git a/tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js b/tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js deleted file mode 100644 index 9eb2f1ac13994..0000000000000 --- a/tests/baselines/reference/tsserver/postPasteEdits/adds-post-paste-edits.js +++ /dev/null @@ -1,270 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -Before request -//// [/project/a/target.ts] -const a = 1; -const b = 2; -const c = 3; - -//// [/project/tsconfig.json] -{} - - -Info seq [hh:mm:ss:mss] request: - { - "command": "open", - "arguments": { - "file": "/project/a/target.ts" - }, - "seq": 1, - "type": "request" - } -Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /project/a/target.ts ProjectRootPath: undefined:: Result: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/project/tsconfig.json", - "reason": "Creating possible configured project for /project/a/target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { - "rootNames": [ - "/project/a/target.ts" - ], - "options": { - "configFilePath": "/project/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory -Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" - - - a/target.ts - Matched by default include pattern '**/*' - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/project/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "telemetry", - "body": { - "telemetryEventName": "projectInfo", - "payload": { - "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", - "fileStats": { - "js": 0, - "jsSize": 0, - "jsx": 0, - "jsxSize": 0, - "ts": 1, - "tsSize": 38, - "tsx": 0, - "tsxSize": 0, - "dts": 0, - "dtsSize": 0, - "deferred": 0, - "deferredSize": 0 - }, - "compilerOptions": {}, - "typeAcquisition": { - "enable": false, - "include": false, - "exclude": false - }, - "extends": false, - "files": false, - "include": false, - "exclude": false, - "compileOnSave": false, - "configFileName": "tsconfig.json", - "projectType": "configured", - "languageServiceEnabled": true, - "version": "FakeVersion" - } - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/project/a/target.ts", - "configFile": "/project/tsconfig.json", - "diagnostics": [ - { - "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", - "code": 6053, - "category": "error" - }, - { - "text": "Cannot find global type 'Array'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Boolean'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Function'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'IArguments'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Number'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Object'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'RegExp'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'String'.", - "code": 2318, - "category": "error" - } - ] - } - } -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json -Info seq [hh:mm:ss:mss] response: - { - "responseRequired": false - } -After request - -PolledWatches:: -/a/lib/lib.d.ts: *new* - {"pollingInterval":500} - -FsWatches:: -/project/tsconfig.json: *new* - {} - -FsWatchesRecursive:: -/project: *new* - {} - -Projects:: -/project/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/project/a/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /project/tsconfig.json *default* - -Before request - -Info seq [hh:mm:ss:mss] request: - { - "command": "getPasteEdits", - "arguments": { - "file": "/project/a/target.ts", - "pastedText": [ - "const q = 1;\nfunction e();\nconst f = r + s;" - ], - "pasteLocations": [ - { - "start": { - "line": 2, - "offset": 0 - }, - "end": { - "line": 2, - "offset": 0 - } - } - ] - }, - "seq": 2, - "type": "request" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "response": { - "edits": [ - { - "fileName": "/project/a/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 13 - }, - "end": { - "line": 1, - "offset": 13 - }, - "newText": "const q = 1;\nfunction e();\nconst f = r + s;" - } - ] - } - ], - "fixId": "providePostPasteEdits" - }, - "responseRequired": true - } -After request - -Projects:: -/project/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/project/a/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /project/tsconfig.json *default* diff --git a/tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js b/tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js deleted file mode 100644 index 9eb2f1ac13994..0000000000000 --- a/tests/baselines/reference/tsserver/postPasteEdits/returns-the-same-file-unchanged,-after-updating-and-reverting-changes-added-to-a-file.js +++ /dev/null @@ -1,270 +0,0 @@ -currentDirectory:: / useCaseSensitiveFileNames: false -Info seq [hh:mm:ss:mss] Provided types map file "/typesMap.json" doesn't exist -Before request -//// [/project/a/target.ts] -const a = 1; -const b = 2; -const c = 3; - -//// [/project/tsconfig.json] -{} - - -Info seq [hh:mm:ss:mss] request: - { - "command": "open", - "arguments": { - "file": "/project/a/target.ts" - }, - "seq": 1, - "type": "request" - } -Info seq [hh:mm:ss:mss] getConfigFileNameForFile:: File: /project/a/target.ts ProjectRootPath: undefined:: Result: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Creating configuration project /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /project/tsconfig.json 2000 undefined Project: /project/tsconfig.json WatchType: Config file -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingStart", - "body": { - "projectName": "/project/tsconfig.json", - "reason": "Creating possible configured project for /project/a/target.ts to open" - } - } -Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { - "rootNames": [ - "/project/a/target.ts" - ], - "options": { - "configFilePath": "/project/tsconfig.json" - } -} -Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory -Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" - - - a/target.ts - Matched by default include pattern '**/*' - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "projectLoadingFinish", - "body": { - "projectName": "/project/tsconfig.json" - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "telemetry", - "body": { - "telemetryEventName": "projectInfo", - "payload": { - "projectId": "4877b582a3e7d5836ee46b4a0db488dc715db827bacc8ef1fbcd0dbb78ae23d1", - "fileStats": { - "js": 0, - "jsSize": 0, - "jsx": 0, - "jsxSize": 0, - "ts": 1, - "tsSize": 38, - "tsx": 0, - "tsxSize": 0, - "dts": 0, - "dtsSize": 0, - "deferred": 0, - "deferredSize": 0 - }, - "compilerOptions": {}, - "typeAcquisition": { - "enable": false, - "include": false, - "exclude": false - }, - "extends": false, - "files": false, - "include": false, - "exclude": false, - "compileOnSave": false, - "configFileName": "tsconfig.json", - "projectType": "configured", - "languageServiceEnabled": true, - "version": "FakeVersion" - } - } - } -Info seq [hh:mm:ss:mss] event: - { - "seq": 0, - "type": "event", - "event": "configFileDiag", - "body": { - "triggerFile": "/project/a/target.ts", - "configFile": "/project/tsconfig.json", - "diagnostics": [ - { - "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", - "code": 6053, - "category": "error" - }, - { - "text": "Cannot find global type 'Array'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Boolean'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Function'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'IArguments'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Number'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Object'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'RegExp'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'String'.", - "code": 2318, - "category": "error" - } - ] - } - } -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] Open files: -Info seq [hh:mm:ss:mss] FileName: /project/a/target.ts ProjectRootPath: undefined -Info seq [hh:mm:ss:mss] Projects: /project/tsconfig.json -Info seq [hh:mm:ss:mss] response: - { - "responseRequired": false - } -After request - -PolledWatches:: -/a/lib/lib.d.ts: *new* - {"pollingInterval":500} - -FsWatches:: -/project/tsconfig.json: *new* - {} - -FsWatchesRecursive:: -/project: *new* - {} - -Projects:: -/project/tsconfig.json (Configured) *new* - projectStateVersion: 1 - projectProgramVersion: 1 - -ScriptInfos:: -/project/a/target.ts (Open) *new* - version: SVC-1-0 - containingProjects: 1 - /project/tsconfig.json *default* - -Before request - -Info seq [hh:mm:ss:mss] request: - { - "command": "getPasteEdits", - "arguments": { - "file": "/project/a/target.ts", - "pastedText": [ - "const q = 1;\nfunction e();\nconst f = r + s;" - ], - "pasteLocations": [ - { - "start": { - "line": 2, - "offset": 0 - }, - "end": { - "line": 2, - "offset": 0 - } - } - ] - }, - "seq": 2, - "type": "request" - } -Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms -Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) - /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3" - -Info seq [hh:mm:ss:mss] ----------------------------------------------- -Info seq [hh:mm:ss:mss] response: - { - "response": { - "edits": [ - { - "fileName": "/project/a/target.ts", - "textChanges": [ - { - "start": { - "line": 1, - "offset": 13 - }, - "end": { - "line": 1, - "offset": 13 - }, - "newText": "const q = 1;\nfunction e();\nconst f = r + s;" - } - ] - } - ], - "fixId": "providePostPasteEdits" - }, - "responseRequired": true - } -After request - -Projects:: -/project/tsconfig.json (Configured) *changed* - projectStateVersion: 3 *changed* - projectProgramVersion: 1 - dirty: true *changed* - -ScriptInfos:: -/project/a/target.ts (Open) *changed* - version: SVC-1-2 *changed* - containingProjects: 1 - /project/tsconfig.json *default* From 5e1ff78c9ef97261f47dd037bf3af0bae23fafbf Mon Sep 17 00:00:00 2001 From: navya9singh Date: Wed, 1 May 2024 19:51:07 -0700 Subject: [PATCH 38/41] adressing pr comments --- src/services/codefixes/importFixes.ts | 8 ++------ src/services/pasteEdits.ts | 3 ++- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 37c04632808f6..b3aab8454c638 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -893,10 +893,6 @@ function getSingleExportInfoForSymbol(symbol: Symbol, symbolName: string, module } } -function isFutureSymbolExportInfoArray(info: readonly SymbolExportInfo[] | readonly FutureSymbolExportInfo[]): info is readonly FutureSymbolExportInfo[] { - return info[0].moduleSymbol === undefined; -} - function getImportFixes( exportInfos: readonly SymbolExportInfo[] | readonly FutureSymbolExportInfo[], usagePosition: number | undefined, @@ -910,7 +906,7 @@ function getImportFixes( fromCacheOnly?: boolean, ): { computedWithoutCacheCount: number; fixes: readonly ImportFixWithModuleSpecifier[]; } { const checker = program.getTypeChecker(); - const existingImports = importMap && !isFutureSymbolExportInfoArray(exportInfos) ? flatMap(exportInfos, importMap.getImportsForExportInfo) : emptyArray; + const existingImports = importMap ? flatMap(exportInfos, importMap.getImportsForExportInfo) : emptyArray; const useNamespace = usagePosition !== undefined && tryUseExistingNamespaceImport(existingImports, usagePosition); const addToExisting = tryAddToExistingImport(existingImports, isValidTypeOnlyUseSite, checker, program.getCompilerOptions()); if (addToExisting) { @@ -1092,7 +1088,7 @@ function createExistingImportMap(importingFile: SourceFile, program: Program) { } return { - getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo): readonly FixAddToExistingImportInfo[] => { + getImportsForExportInfo: ({ moduleSymbol, exportKind, targetFlags, symbol }: SymbolExportInfo | FutureSymbolExportInfo): readonly FixAddToExistingImportInfo[] => { const matchingDeclarations = importMap?.get(getSymbolId(moduleSymbol)); if (!matchingDeclarations) return emptyArray; diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index 07806f79d3c35..c79e3e035d4bc 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -1,6 +1,7 @@ import { addRange } from "../compiler/core"; import { CancellationToken, + Program, SourceFile, Statement, SymbolFlags, @@ -79,7 +80,7 @@ function pasteEdits( newText = actualPastedText ? newText.slice(0, pos) + actualPastedText[0] + newText.slice(end) : newText.slice(0, pos) + pastedText[i] + newText.slice(end); } - host.runWithTemporaryFileUpdate?.(targetFile.fileName, newText, (updatedProgram, originalProgram, updatedFile) => { + Debug.checkDefined(host.runWithTemporaryFileUpdate).call(host, targetFile.fileName, newText, (updatedProgram: Program, originalProgram: Program | undefined, updatedFile: SourceFile) => { const importAdder = codefix.createImportAdder(updatedFile, updatedProgram, preferences, host); if (copiedFrom?.range) { Debug.assert(copiedFrom.range.length === pastedText.length); From a3fbd6960327a46335bb8959f6c74b5fcab5f5a9 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Thu, 2 May 2024 12:11:28 -0700 Subject: [PATCH 39/41] adding changes tests and protocol --- src/harness/client.ts | 2 +- src/harness/fourslashImpl.ts | 2 +- src/server/protocol.ts | 7 +- src/server/session.ts | 2 +- .../unittests/tsserver/pasteEdits.ts | 5 +- tests/baselines/reference/api/typescript.d.ts | 7 +- .../pasteEdits_existingImports2.js | 2 +- .../pasteEdits_knownSourceFile.js | 2 +- .../pasteEdits_multiplePastes2.js | 2 +- .../pasteEdits_multiplePastes3.js | 2 +- .../tsserver/pasteEdits/adds-paste-edits.js | 188 ++++++++++++------ tests/cases/fourslash/fourslash.ts | 1 - .../server/pasteEdits_existingImports1.ts | 3 +- .../server/pasteEdits_existingImports2.ts | 3 +- .../server/pasteEdits_knownSourceFile.ts | 3 +- .../server/pasteEdits_multiplePastes1.ts | 3 +- .../server/pasteEdits_multiplePastes2.ts | 3 +- .../server/pasteEdits_multiplePastes3.ts | 3 +- .../server/pasteEdits_multiplePastes4.ts | 3 +- .../server/pasteEdits_pasteComments.ts | 3 +- .../server/pasteEdits_revertUpdatedFile.ts | 3 +- 21 files changed, 162 insertions(+), 87 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 21aa5291b3947..24863ba11404f 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1016,7 +1016,7 @@ export class SessionClient implements LanguageService { file: targetFile, pastedText, pasteLocations: pasteLocations.map(range => ({ start: this.positionToOneBasedLineOffset(targetFile, range.pos), end: this.positionToOneBasedLineOffset(targetFile, range.end) })), - copiedFrom: copiedFrom ? { file: copiedFrom.file, range: copiedFrom.range.map(range => ({ start: this.positionToOneBasedLineOffset(copiedFrom.file, range.pos), end: this.positionToOneBasedLineOffset(copiedFrom.file, range.end) })) } : undefined, + copiedFrom: copiedFrom ? { file: copiedFrom.file, spans: copiedFrom.range.map(range => ({ start: this.positionToOneBasedLineOffset(copiedFrom.file, range.pos), end: this.positionToOneBasedLineOffset(copiedFrom.file, range.end) })) } : undefined, }; const request = this.processRequest(protocol.CommandTypes.GetPasteEdits, args); const response = this.processResponse(request); diff --git a/src/harness/fourslashImpl.ts b/src/harness/fourslashImpl.ts index a4a578b545463..1cf3e7e5e3672 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3562,7 +3562,7 @@ export class TestState { public verifyPasteEdits(options: FourSlashInterface.PasteEditsOptions): void { const editInfo = this.languageService.getPasteEdits({ targetFile: this.activeFile.fileName, pastedText: options.args.pastedText, pasteLocations: options.args.pasteLocations, copiedFrom: options.args.copiedFrom, preferences: options.args.preferences }, this.formatCodeSettings); - (options.fixId === editInfo.fixId) ? this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits) : this.raiseError(`Expected to find a fix ${editInfo.fixId}, but none exists`); + this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); } public verifyDocCommentTemplate(expected: ts.TextInsertion | undefined, options?: ts.DocCommentTemplateOptions) { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index d2dd361707f80..df26b8d2321b4 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -636,9 +636,14 @@ export interface GetPasteEditsRequest extends Request { } export interface GetPasteEditsRequestArgs extends FileRequestArgs { + /** The text that gets pasted in a file. */ pastedText: string[]; + /** Locations of where the `pastedText` gets added in a file. If the length of the `pastedText` and `pastedLocations` are not the same, + * then the `pastedText` is combined into one and added at all the `pastedLocations`. + */ pasteLocations: TextSpan[]; - copiedFrom?: { file: string; range: TextSpan[]; }; + /** The source location of each `pastedText`. If present, the length of `spans` must be equal to the length of `pastedText`. */ + copiedFrom?: { file: string; spans: TextSpan[]; }; } export interface GetPasteEditsResponse extends Response { diff --git a/src/server/session.ts b/src/server/session.ts index aa4192191bc7e..821db821b667f 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -2801,7 +2801,7 @@ export class Session implements EventSender { private getPasteEdits(args: protocol.GetPasteEditsRequestArgs): protocol.PasteEditsAction | undefined { const { file, project } = this.getFileAndProject(args); const copiedFrom = args.copiedFrom - ? { file: args.copiedFrom.file, range: args.copiedFrom.range.map(copies => this.getRange({ file: args.copiedFrom!.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom!.file))!)) } + ? { file: args.copiedFrom.file, range: args.copiedFrom.spans.map(copies => this.getRange({ file: args.copiedFrom!.file, startLine: copies.start.line, startOffset: copies.start.offset, endLine: copies.end.line, endOffset: copies.end.offset }, project.getScriptInfoForNormalizedPath(toNormalizedPath(args.copiedFrom!.file))!)) } : undefined; const result = project.getLanguageService().getPasteEdits( { diff --git a/src/testRunner/unittests/tsserver/pasteEdits.ts b/src/testRunner/unittests/tsserver/pasteEdits.ts index 3c7918fb30574..b3dd4f75acb04 100644 --- a/src/testRunner/unittests/tsserver/pasteEdits.ts +++ b/src/testRunner/unittests/tsserver/pasteEdits.ts @@ -8,6 +8,7 @@ import { import { createServerHost, File, + libFile, } from "../helpers/virtualFileSystemWithWatch"; describe("unittests:: tsserver:: pasteEdits", () => { @@ -26,7 +27,7 @@ const c = 3;`, function e(); const f = r + s;`; - const host = createServerHost([target, tsconfig]); + const host = createServerHost([target, tsconfig, libFile]); const session = new TestSession(host); openFilesForSession([target], session); @@ -38,7 +39,7 @@ const f = r + s;`; pasteLocations: [{ start: { line: 2, offset: 0 }, end: { line: 2, offset: 0 } }], }, }); - baselineTsserverLogs("pasteEdits", "adds paste edits", session); verifyGetErrRequest({ session, files: [target.path] }); + baselineTsserverLogs("pasteEdits", "adds paste edits", session); }); }); diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c63bb198e4cb4..b1ac4827d4fd1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -478,11 +478,16 @@ declare namespace ts { arguments: GetPasteEditsRequestArgs; } export interface GetPasteEditsRequestArgs extends FileRequestArgs { + /** The text that gets pasted in a file. */ pastedText: string[]; + /** Locations of where the `pastedText` gets added in a file. If the length of the `pastedText` and `pastedLocations` are not the same, + * then the `pastedText` is combined into one and added at all the `pastedLocations`. + */ pasteLocations: TextSpan[]; + /** The source location of each `pastedText`. If present, the length of `spans` must be equal to the length of `pastedText`. */ copiedFrom?: { file: string; - range: TextSpan[]; + spans: TextSpan[]; }; } export interface GetPasteEditsResponse extends Response { diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js index 40a7470584611..7c84068e8d401 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -261,7 +261,7 @@ Info seq [hh:mm:ss:mss] request: ], "copiedFrom": { "file": "originalFile.ts", - "range": [ + "spans": [ { "start": { "line": 4, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js index 89409a7a6bade..6f24330921c6c 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -228,7 +228,7 @@ Info seq [hh:mm:ss:mss] request: ], "copiedFrom": { "file": "file2.ts", - "range": [ + "spans": [ { "start": { "line": 3, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js index 62152ca4c2af2..4220fcf05728e 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -242,7 +242,7 @@ Info seq [hh:mm:ss:mss] request: ], "copiedFrom": { "file": "file1.ts", - "range": [ + "spans": [ { "start": { "line": 4, diff --git a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js index f7eae4167992e..68e20b148b131 100644 --- a/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js @@ -247,7 +247,7 @@ Info seq [hh:mm:ss:mss] request: ], "copiedFrom": { "file": "file1.ts", - "range": [ + "spans": [ { "start": { "line": 5, diff --git a/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js index f2b70920c6dfa..5f0a2b2a5a1be 100644 --- a/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js +++ b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js @@ -9,6 +9,19 @@ const c = 3; //// [/project/tsconfig.json] {} +//// [/a/lib/lib.d.ts] +/// +interface Boolean {} +interface Function {} +interface CallableFunction {} +interface NewableFunction {} +interface IArguments {} +interface Number { toExponential: any; } +interface Object {} +interface RegExp {} +interface String { charAt: any; } +interface Array { length: number; [n: number]: T; } + Info seq [hh:mm:ss:mss] request: { @@ -43,13 +56,16 @@ Info seq [hh:mm:ss:mss] Config: /project/tsconfig.json : { Info seq [hh:mm:ss:mss] DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Elapsed:: *ms DirectoryWatcher:: Added:: WatchInfo: /project 1 undefined Config: /project/tsconfig.json WatchType: Wild card directory Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json -Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined Project: /project/tsconfig.json WatchType: Missing file +Info seq [hh:mm:ss:mss] FileWatcher:: Added:: WatchInfo: /a/lib/lib.d.ts 500 undefined WatchType: Closed Script info Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 1 projectProgramVersion: 0 structureChanged: true structureIsReused:: Not Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) +Info seq [hh:mm:ss:mss] Files (2) + /a/lib/lib.d.ts Text-1 "/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }" /project/a/target.ts SVC-1-0 "const a = 1;\nconst b = 2;\nconst c = 3;" + ../a/lib/lib.d.ts + Default library for target 'es5' a/target.ts Matched by default include pattern '**/*' @@ -81,8 +97,8 @@ Info seq [hh:mm:ss:mss] event: "tsSize": 38, "tsx": 0, "tsxSize": 0, - "dts": 0, - "dtsSize": 0, + "dts": 1, + "dtsSize": 334, "deferred": 0, "deferredSize": 0 }, @@ -112,57 +128,11 @@ Info seq [hh:mm:ss:mss] event: "body": { "triggerFile": "/project/a/target.ts", "configFile": "/project/tsconfig.json", - "diagnostics": [ - { - "text": "File '/a/lib/lib.d.ts' not found.\n The file is in the program because:\n Default library for target 'es5'", - "code": 6053, - "category": "error" - }, - { - "text": "Cannot find global type 'Array'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Boolean'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Function'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'IArguments'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Number'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'Object'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'RegExp'.", - "code": 2318, - "category": "error" - }, - { - "text": "Cannot find global type 'String'.", - "code": 2318, - "category": "error" - } - ] + "diagnostics": [] } } Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) +Info seq [hh:mm:ss:mss] Files (2) Info seq [hh:mm:ss:mss] ----------------------------------------------- Info seq [hh:mm:ss:mss] Open files: @@ -174,11 +144,9 @@ Info seq [hh:mm:ss:mss] response: } After request -PolledWatches:: -/a/lib/lib.d.ts: *new* - {"pollingInterval":500} - FsWatches:: +/a/lib/lib.d.ts: *new* + {} /project/tsconfig.json: *new* {} @@ -192,6 +160,10 @@ Projects:: projectProgramVersion: 1 ScriptInfos:: +/a/lib/lib.d.ts *new* + version: Text-1 + containingProjects: 1 + /project/tsconfig.json /project/a/target.ts (Open) *new* version: SVC-1-0 containingProjects: 1 @@ -226,7 +198,8 @@ Info seq [hh:mm:ss:mss] request: Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 2 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) -Info seq [hh:mm:ss:mss] Files (1) +Info seq [hh:mm:ss:mss] Files (2) + /a/lib/lib.d.ts Text-1 "/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }" /project/a/target.ts SVC-1-1 "const a = 1;const q = 1;\nfunction e();\nconst f = r + s;\nconst b = 2;\nconst c = 3;" Info seq [hh:mm:ss:mss] ----------------------------------------------- @@ -264,7 +237,108 @@ Projects:: dirty: true *changed* ScriptInfos:: +/a/lib/lib.d.ts + version: Text-1 + containingProjects: 1 + /project/tsconfig.json /project/a/target.ts (Open) *changed* version: SVC-1-2 *changed* containingProjects: 1 /project/tsconfig.json *default* + +Before request + +Info seq [hh:mm:ss:mss] request: + { + "command": "geterr", + "arguments": { + "delay": 0, + "files": [ + "/project/a/target.ts" + ] + }, + "seq": 3, + "type": "request" + } +Info seq [hh:mm:ss:mss] response: + { + "responseRequired": false + } +After request + +Timeout callback:: count: 1 +1: checkOne *new* + +Before running Timeout callback:: count: 1 +1: checkOne + +Info seq [hh:mm:ss:mss] Starting updateGraphWorker: Project: /project/tsconfig.json +Info seq [hh:mm:ss:mss] Finishing updateGraphWorker: Project: /project/tsconfig.json projectStateVersion: 3 projectProgramVersion: 1 structureChanged: false structureIsReused:: Completely Elapsed:: *ms +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + /a/lib/lib.d.ts Text-1 "/// \ninterface Boolean {}\ninterface Function {}\ninterface CallableFunction {}\ninterface NewableFunction {}\ninterface IArguments {}\ninterface Number { toExponential: any; }\ninterface Object {}\ninterface RegExp {}\ninterface String { charAt: any; }\ninterface Array { length: number; [n: number]: T; }" + /project/a/target.ts SVC-1-2 "const a = 1;\nconst b = 2;\nconst c = 3;" + +Info seq [hh:mm:ss:mss] ----------------------------------------------- +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "syntaxDiag", + "body": { + "file": "/project/a/target.ts", + "diagnostics": [] + } + } +After running Timeout callback:: count: 0 + +Immedidate callback:: count: 1 +1: semanticCheck *new* + +Projects:: +/project/tsconfig.json (Configured) *changed* + projectStateVersion: 3 + projectProgramVersion: 1 + dirty: false *changed* + +Before running Immedidate callback:: count: 1 +1: semanticCheck + +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "semanticDiag", + "body": { + "file": "/project/a/target.ts", + "diagnostics": [] + } + } +After running Immedidate callback:: count: 1 + +Immedidate callback:: count: 1 +2: suggestionCheck *new* + +Before running Immedidate callback:: count: 1 +2: suggestionCheck + +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "suggestionDiag", + "body": { + "file": "/project/a/target.ts", + "diagnostics": [] + } + } +Info seq [hh:mm:ss:mss] event: + { + "seq": 0, + "type": "event", + "event": "requestCompleted", + "body": { + "request_seq": 3 + } + } +After running Immedidate callback:: count: 0 diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index 253d5ee200bf5..e892d9d98725c 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -451,7 +451,6 @@ declare namespace FourSlashInterface { pasteLocations: { pos: number, end: number }[]; copiedFrom?: { file: string, range: { pos: number, end: number }[] }; } - fixId?: string; }): void; } class edit { diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts index ba27ed2df0005..616db9c6ab52a 100644 --- a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts @@ -34,6 +34,5 @@ import { t3 } from "./other3"; const a = t + 1; const m = t3 + t2 + 1; const c = 10;` - }, - fixId: "providePostPasteEdits" + } }); diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports2.ts b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts index 593da2488c912..65d44e516b4d6 100644 --- a/tests/cases/fourslash/server/pasteEdits_existingImports2.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts @@ -42,6 +42,5 @@ import { t3 } from "./other3"; const a = t + 1; const m = t3 + t2 + n; const c = 10;` - }, - fixId: "providePostPasteEdits" + } }); diff --git a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts index 2d99851ab26c3..93cafd2b623d3 100644 --- a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts @@ -42,6 +42,5 @@ export const tt = 2; const c = a + b; const t = 9; const p = 1;`, - }, - fixId: "providePostPasteEdits" + } }); diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts index 626e91f1d59fc..946239c13d2c7 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts @@ -43,6 +43,5 @@ const g = p + q; function e(); const f = r + s; const d = 4;` - }, - fixId: "providePostPasteEdits" + } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts index 1f78205c9d55c..960438f0157a8 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -42,6 +42,5 @@ const c = 3; export const t = aa + bb + r + s; const u = 1; const d = 4;` - }, - fixId: "providePostPasteEdits" + } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts index f37736393a91e..3acf8a6bc1c94 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts @@ -50,6 +50,5 @@ const u = 1; const c = 3; export const k = r + m; const d = 4;` - }, - fixId: "providePostPasteEdits" + } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts index 46a83b0365929..8e9fefd5b82cc 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts @@ -40,6 +40,5 @@ const c = 3; const g = p + q; const f = r + s; const d = 4;` - }, - fixId: "providePostPasteEdits" + } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts index 3a7ee389bcfcc..a6c6009eb9b26 100644 --- a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts +++ b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts @@ -30,6 +30,5 @@ const b = 10;/** * line 4 */ const c = 10;` - }, - fixId: "providePostPasteEdits" + } }); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts index 4e741b76d677b..7340b9ce67bfb 100644 --- a/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts @@ -33,8 +33,7 @@ const m = t2 + 1; type T = number; var x; var y = x as ` - }, - fixId: "providePostPasteEdits" + } }); verify.completions({ marker: "1", includes: "T" }); From 8c23899ba9038e1ec69243a7a0050d1ee99ade40 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 7 May 2024 10:49:50 -0700 Subject: [PATCH 40/41] fixing test formatting --- src/harness/client.ts | 3 ++- tests/cases/fourslash/server/pasteEdits_existingImports1.ts | 3 +-- tests/cases/fourslash/server/pasteEdits_existingImports2.ts | 1 - tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts | 1 - tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts | 1 - tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts | 1 - tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts | 1 - tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts | 1 - tests/cases/fourslash/server/pasteEdits_pasteComments.ts | 1 - tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts | 3 +-- tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts | 1 - 11 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/harness/client.ts b/src/harness/client.ts index 24863ba11404f..3203c956c7e9e 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -1010,8 +1010,9 @@ export class SessionClient implements LanguageService { getPasteEdits( { targetFile, pastedText, pasteLocations, copiedFrom }: PasteEditsArgs, - _formatOptions: FormatCodeSettings, + formatOptions: FormatCodeSettings, ): PasteEdits { + this.setFormattingOptions(formatOptions); const args: protocol.GetPasteEditsRequestArgs = { file: targetFile, pastedText, diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts index 616db9c6ab52a..204d6bb0c8186 100644 --- a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts @@ -20,11 +20,10 @@ ////{ "files": ["target.ts", "other.ts", "other2.ts", "other3.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `const m = t3 + t2 + 1;`], - pasteLocations: [{ pos: range[0].pos, end: range[0].end }], + pasteLocations: [range[0]], }, newFileContents: { "/target.ts": diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports2.ts b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts index 65d44e516b4d6..e12fe6350dbc0 100644 --- a/tests/cases/fourslash/server/pasteEdits_existingImports2.ts +++ b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts @@ -26,7 +26,6 @@ ////{ "files": ["target.ts", "originalFile.ts", "other.ts", "other2.ts", "other3.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `const m = t3 + t2 + n;` ], diff --git a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts index 93cafd2b623d3..fe9023647fb0a 100644 --- a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts @@ -19,7 +19,6 @@ const range = test.ranges(); const t = range[0]; -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `const c = a + b; diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts index 946239c13d2c7..5b0e9f5bfbfdb 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts @@ -20,7 +20,6 @@ ////{ "files": ["file1.ts", "target.ts", "file3.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `const g = p + q; diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts index 960438f0157a8..71de5ac278f4e 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -22,7 +22,6 @@ ////{ "files": ["file1.ts", "target.ts", "other.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `export const t = aa + bb + r + s; diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts index 3acf8a6bc1c94..99b5451eb319f 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts @@ -25,7 +25,6 @@ ////{ "files": ["file1.ts", "target.ts", "other.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `export const t = aa + bb + r + s; diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts index 8e9fefd5b82cc..61d25803abd3d 100644 --- a/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts @@ -20,7 +20,6 @@ ////{ "files": ["file1.ts", "target.ts", "file3.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ "const g = p + q;", "const f = r + s;"], diff --git a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts index a6c6009eb9b26..49d621d21387f 100644 --- a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts +++ b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts @@ -9,7 +9,6 @@ ////{ "files": ["target.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `/** diff --git a/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts index 7340b9ce67bfb..fbe0e77ef2f99 100644 --- a/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts @@ -18,11 +18,10 @@ ////{ "files": ["target.ts", "other.ts", "other2.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `const m = t2 + 1;`], - pasteLocations: [{ pos: range[0].pos, end: range[0].end }], + pasteLocations: [range[0]], }, newFileContents: { "/target.ts": diff --git a/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts index 486d945a786aa..f8175850ff17e 100644 --- a/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts +++ b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts @@ -15,7 +15,6 @@ ////{ "files": ["file1.ts", "file2.ts"] } const range = test.ranges(); -format.setOption("insertSpaceAfterSemicolonInForStatements", true); verify.pasteEdits({ args: { pastedText: [ `interface Testing { From 3fe8f4890d370b37fc1238ccd0d3391d37eaf8b3 Mon Sep 17 00:00:00 2001 From: navya9singh Date: Tue, 7 May 2024 11:10:41 -0700 Subject: [PATCH 41/41] fixing error in pasteEdit.ts --- src/services/_namespaces/ts.PasteEdits.ts | 2 +- src/services/_namespaces/ts.ts | 2 +- src/services/pasteEdits.ts | 14 +++++++------- src/testRunner/tests.ts | 1 + src/testRunner/unittests/tsserver/pasteEdits.ts | 6 +++--- 5 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/services/_namespaces/ts.PasteEdits.ts b/src/services/_namespaces/ts.PasteEdits.ts index 6765b467d802f..b9a30dec6f501 100644 --- a/src/services/_namespaces/ts.PasteEdits.ts +++ b/src/services/_namespaces/ts.PasteEdits.ts @@ -1 +1 @@ -export * from "../pasteEdits"; +export * from "../pasteEdits.js"; diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts index 28c93b045e924..0c09ffca05e94 100644 --- a/src/services/_namespaces/ts.ts +++ b/src/services/_namespaces/ts.ts @@ -56,5 +56,5 @@ import * as textChanges from "./ts.textChanges.js"; export { textChanges }; import * as formatting from "./ts.formatting.js"; export { formatting }; -import * as pasteEdits from "./ts.PasteEdits"; +import * as pasteEdits from "./ts.PasteEdits.js"; export { pasteEdits }; diff --git a/src/services/pasteEdits.ts b/src/services/pasteEdits.ts index c79e3e035d4bc..c146733a4a4bf 100644 --- a/src/services/pasteEdits.ts +++ b/src/services/pasteEdits.ts @@ -1,4 +1,4 @@ -import { addRange } from "../compiler/core"; +import { addRange } from "../compiler/core.js"; import { CancellationToken, Program, @@ -7,8 +7,8 @@ import { SymbolFlags, TextRange, UserPreferences, -} from "../compiler/types"; -import { getLineOfLocalPosition } from "../compiler/utilities"; +} from "../compiler/types.js"; +import { getLineOfLocalPosition } from "../compiler/utilities.js"; import { codefix, Debug, @@ -18,19 +18,19 @@ import { getQuotePreference, isIdentifier, textChanges, -} from "./_namespaces/ts"; -import { addTargetFileImports } from "./refactors/helpers"; +} from "./_namespaces/ts.js"; +import { addTargetFileImports } from "./refactors/helpers.js"; import { addExportsInOldFile, getExistingLocals, getUsageInfo, -} from "./refactors/moveToFile"; +} from "./refactors/moveToFile.js"; import { CodeFixContextBase, FileTextChanges, LanguageServiceHost, PasteEdits, -} from "./types"; +} from "./types.js"; const fixId = "providePostPasteEdits"; /** @internal */ diff --git a/src/testRunner/tests.ts b/src/testRunner/tests.ts index f01233dc12f67..fe6a891ba89f3 100644 --- a/src/testRunner/tests.ts +++ b/src/testRunner/tests.ts @@ -189,6 +189,7 @@ export * from "./unittests/tsserver/occurences.js"; export * from "./unittests/tsserver/openFile.js"; export * from "./unittests/tsserver/packageJsonInfo.js"; export * from "./unittests/tsserver/partialSemanticServer.js"; +export * from "./unittests/tsserver/pasteEdits.js"; export * from "./unittests/tsserver/plugins.js"; export * from "./unittests/tsserver/pluginsAsync.js"; export * from "./unittests/tsserver/projectErrors.js"; diff --git a/src/testRunner/unittests/tsserver/pasteEdits.ts b/src/testRunner/unittests/tsserver/pasteEdits.ts index b3dd4f75acb04..2af5d74804098 100644 --- a/src/testRunner/unittests/tsserver/pasteEdits.ts +++ b/src/testRunner/unittests/tsserver/pasteEdits.ts @@ -1,15 +1,15 @@ -import * as ts from "../../_namespaces/ts"; +import * as ts from "../../_namespaces/ts.js"; import { baselineTsserverLogs, openFilesForSession, TestSession, verifyGetErrRequest, -} from "../helpers/tsserver"; +} from "../helpers/tsserver.js"; import { createServerHost, File, libFile, -} from "../helpers/virtualFileSystemWithWatch"; +} from "../helpers/virtualFileSystemWithWatch.js"; describe("unittests:: tsserver:: pasteEdits", () => { it("adds paste edits", () => {