diff --git a/src/harness/client.ts b/src/harness/client.ts index 286b712af11b6..a2fa6c4e1d37c 100644 --- a/src/harness/client.ts +++ b/src/harness/client.ts @@ -48,6 +48,8 @@ import { notImplemented, OrganizeImportsArgs, OutliningSpan, + PasteEdits, + PasteEditsArgs, PatternMatchKind, Program, QuickInfo, @@ -1006,6 +1008,26 @@ export class SessionClient implements LanguageService { return getSupportedCodeFixes(); } + getPasteEdits( + { targetFile, pastedText, pasteLocations, copiedFrom }: PasteEditsArgs, + formatOptions: FormatCodeSettings, + ): PasteEdits { + this.setFormattingOptions(formatOptions); + const args: protocol.GetPasteEditsRequestArgs = { + file: targetFile, + pastedText, + pasteLocations: pasteLocations.map(range => ({ start: this.positionToOneBasedLineOffset(targetFile, range.pos), end: this.positionToOneBasedLineOffset(targetFile, range.end) })), + 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); + if (!response.body) { + return { edits: [] }; + } + const edits: FileTextChanges[] = this.convertCodeEditsToTextChanges(response.body.edits); + return { edits, fixId: response.body.fixId }; + } + 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 d11daf7b45a8b..6c7a14535d2c5 100644 --- a/src/harness/fourslashImpl.ts +++ b/src/harness/fourslashImpl.ts @@ -3560,6 +3560,11 @@ export class TestState { assert.deepEqual(actualModuleSpecifiers, moduleSpecifiers); } + 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); + this.verifyNewContent({ newFileContent: options.newFileContents }, editInfo.edits); + } + 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 b904a94cc2653..28cfa8c201d7d 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 pasteEdits(options: PasteEditsOptions): void { + this.state.verifyPasteEdits(options); + } } export class Edit { @@ -1923,6 +1927,12 @@ export interface MoveToFileOptions { readonly preferences?: ts.UserPreferences; } +export interface PasteEditsOptions { + readonly newFileContents: { readonly [fileName: string]: string; }; + args: ts.PasteEditsArgs; + readonly fixId: string; +} + export type RenameLocationsOptions = readonly RenameLocationOptions[] | { readonly findInStrings?: boolean; readonly findInComments?: boolean; diff --git a/src/server/project.ts b/src/server/project.ts index 6786d35f1fe18..1f3d44e68b751 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2238,6 +2238,18 @@ export abstract class Project implements LanguageServiceHost, ModuleResolutionHo return this.noDtsResolutionProject; } + /** @internal */ + 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); + + 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); + } + /** @internal */ private getCompilerOptionsForNoDtsResolutionProject() { return { diff --git a/src/server/protocol.ts b/src/server/protocol.ts index 39bc194385376..1f21dde2669ba 100644 --- a/src/server/protocol.ts +++ b/src/server/protocol.ts @@ -161,6 +161,7 @@ export const enum CommandTypes { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", + GetPasteEdits = "getPasteEdits", /** @internal */ GetEditsForRefactorFull = "getEditsForRefactor-full", @@ -625,6 +626,35 @@ export interface GetMoveToRefactoringFileSuggestions extends Response { }; } +/** + * Request refactorings at a given position post pasting text from some other location. + */ + +export interface GetPasteEditsRequest extends Request { + command: CommandTypes.GetPasteEdits; + 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; spans: TextSpan[]; }; +} + +export interface GetPasteEditsResponse extends Response { + body: PasteEditsAction; +} + +export interface PasteEditsAction { + edits: FileCodeEdits[]; + fixId?: {}; +} + export interface GetEditsForRefactorRequest extends Request { command: CommandTypes.GetEditsForRefactor; arguments: GetEditsForRefactorRequestArgs; diff --git a/src/server/session.ts b/src/server/session.ts index 9fe3a45479b3a..372d987634368 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -100,6 +100,7 @@ import { OperationCanceledException, OrganizeImportsMode, OutliningSpan, + PasteEdits, Path, perfLogger, PerformanceEvent, @@ -910,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[] = [ @@ -2796,6 +2798,24 @@ export class Session implements EventSender { return project.getLanguageService().getMoveToRefactoringFileSuggestions(file, this.extractPositionOrRange(args, scriptInfo), this.getPreferences(file)); } + 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.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( + { + 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, + preferences: this.getPreferences(file), + }, + this.getFormatOptions(file), + ); + return result && this.mapPasteEditsAction(result); + } + 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); @@ -2928,6 +2948,10 @@ export class Session implements EventSender { return { fixName, description, changes: this.mapTextChangesToCodeEdits(changes), commands, fixId, fixAllDescription }; } + private mapPasteEditsAction({ edits, fixId }: PasteEdits): protocol.PasteEditsAction { + return { edits: this.mapTextChangesToCodeEdits(edits), fixId }; + } + private mapTextChangesToCodeEdits(textChanges: readonly FileTextChanges[]): protocol.FileCodeEdits[] { return textChanges.map(change => this.mapTextChangeToCodeEdit(change)); } @@ -3521,6 +3545,9 @@ export class Session implements EventSender { [protocol.CommandTypes.GetMoveToRefactoringFileSuggestions]: (request: protocol.GetMoveToRefactoringFileSuggestionsRequest) => { return this.requiredResponse(this.getMoveToRefactoringFileSuggestions(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..b9a30dec6f501 --- /dev/null +++ b/src/services/_namespaces/ts.PasteEdits.ts @@ -0,0 +1 @@ +export * from "../pasteEdits.js"; diff --git a/src/services/_namespaces/ts.ts b/src/services/_namespaces/ts.ts index 78e24eda966f0..0c09ffca05e94 100644 --- a/src/services/_namespaces/ts.ts +++ b/src/services/_namespaces/ts.ts @@ -56,3 +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.js"; +export { pasteEdits }; diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index e528701942ce9..463f9e85ca625 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].symbol === 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 new file mode 100644 index 0000000000000..c146733a4a4bf --- /dev/null +++ b/src/services/pasteEdits.ts @@ -0,0 +1,115 @@ +import { addRange } from "../compiler/core.js"; +import { + CancellationToken, + Program, + SourceFile, + Statement, + SymbolFlags, + TextRange, + UserPreferences, +} from "../compiler/types.js"; +import { getLineOfLocalPosition } from "../compiler/utilities.js"; +import { + codefix, + Debug, + fileShouldUseJavaScriptRequire, + forEachChild, + formatting, + getQuotePreference, + isIdentifier, + textChanges, +} from "./_namespaces/ts.js"; +import { addTargetFileImports } from "./refactors/helpers.js"; +import { + addExportsInOldFile, + getExistingLocals, + getUsageInfo, +} from "./refactors/moveToFile.js"; +import { + CodeFixContextBase, + FileTextChanges, + LanguageServiceHost, + PasteEdits, +} from "./types.js"; + +const fixId = "providePostPasteEdits"; +/** @internal */ +export function pasteEditsProvider( + targetFile: SourceFile, + 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, pastedText, pasteLocations, copiedFrom, host, preferences, formatContext, cancellationToken, changeTracker)); + return { edits: changes, fixId }; +} + +function pasteEdits( + targetFile: SourceFile, + pastedText: string[], + pasteLocations: TextRange[], + copiedFrom: { file: SourceFile; range: TextRange[]; } | undefined, + host: LanguageServiceHost, + preferences: UserPreferences, + formatContext: formatting.FormatContext, + cancellationToken: CancellationToken, + changes: textChanges.ChangeTracker, +) { + 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 }, + actualPastedText ? + actualPastedText[0] : pastedText[i], + ); + }); + + const statements: Statement[] = []; + + let newText = targetFile.text; + for (let i = pasteLocations.length - 1; i >= 0; i--) { + 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); + } + + 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); + 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())); + 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); + } + else { + const context: CodeFixContextBase = { + sourceFile: updatedFile, + program: originalProgram!, + cancellationToken, + host, + preferences, + formatContext, + }; + forEachChild(updatedFile, function cb(node) { + 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(copiedFrom ? copiedFrom.file : targetFile, preferences)); + }); +} diff --git a/src/services/refactors/moveToFile.ts b/src/services/refactors/moveToFile.ts index 38e6b137bad1f..3d061d7f34900 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) { @@ -1118,7 +1119,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 7e508b1f38d63..b46a5956dd4e8 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -241,6 +241,9 @@ import { ParseConfigFileHost, ParsedCommandLine, parseJsonSourceFileConfigFileContent, + PasteEdits, + pasteEdits, + PasteEditsArgs, Path, positionIsSynthesized, PossibleProgramFileInfo, @@ -1573,6 +1576,7 @@ const invalidOperationsInPartialSemanticMode: readonly (keyof LanguageService)[] "provideCallHierarchyOutgoingCalls", "provideInlayHints", "getSupportedCodeFixes", + "getPasteEdits", ]; const invalidOperationsInSyntacticMode: readonly (keyof LanguageService)[] = [ @@ -2128,6 +2132,23 @@ export function createLanguageService( }; } + function getPasteEdits( + args: PasteEditsArgs, + formatOptions: FormatCodeSettings, + ): PasteEdits { + synchronizeHostData(); + return pasteEdits.pasteEditsProvider( + getValidSourceFile(args.targetFile), + args.pastedText, + args.pasteLocations, + args.copiedFrom ? { file: getValidSourceFile(args.copiedFrom.file), range: args.copiedFrom.range } : undefined, + host, + args.preferences, + formatting.getFormatContext(formatOptions, host), + cancellationToken, + ); + } + function getNodeForQuickInfo(node: Node): Node { if (isNewExpression(node.parent) && node.pos === node.parent.pos) { return node.parent.expression; @@ -3214,6 +3235,7 @@ export function createLanguageService( uncommentSelection, provideInlayHints, getSupportedCodeFixes, + getPasteEdits, }; switch (languageServiceMode) { diff --git a/src/services/types.ts b/src/services/types.ts index 5a4b80afb6cdd..7d1b10311f85e 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, originalProgram: Program | undefined, updatedPastedText: SourceFile) => void): void; jsDocParsingMode?: JSDocParsingMode | undefined; } @@ -684,6 +684,10 @@ export interface LanguageService { getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; + getPasteEdits( + args: PasteEditsArgs, + formatOptions: FormatCodeSettings, + ): PasteEdits; } export interface JsxClosingTagInfo { @@ -706,6 +710,19 @@ export const enum OrganizeImportsMode { RemoveUnused = "RemoveUnused", } +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 { /** @deprecated Use `mode` instead */ skipDestructiveCodeActions?: boolean; 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 new file mode 100644 index 0000000000000..2af5d74804098 --- /dev/null +++ b/src/testRunner/unittests/tsserver/pasteEdits.ts @@ -0,0 +1,45 @@ +import * as ts from "../../_namespaces/ts.js"; +import { + baselineTsserverLogs, + openFilesForSession, + TestSession, + verifyGetErrRequest, +} from "../helpers/tsserver.js"; +import { + createServerHost, + File, + libFile, +} from "../helpers/virtualFileSystemWithWatch.js"; + +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, libFile]); + 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 } }], + }, + }); + 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 825eaeeb3e381..b1ac4827d4fd1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -99,6 +99,7 @@ declare namespace ts { GetApplicableRefactors = "getApplicableRefactors", GetEditsForRefactor = "getEditsForRefactor", GetMoveToRefactoringFileSuggestions = "getMoveToRefactoringFileSuggestions", + GetPasteEdits = "getPasteEdits", OrganizeImports = "organizeImports", GetEditsForFileRename = "getEditsForFileRename", ConfigurePlugin = "configurePlugin", @@ -469,6 +470,33 @@ declare namespace ts { files: string[]; }; } + /** + * Request refactorings at a given position post pasting text from some other location. + */ + export interface GetPasteEditsRequest extends Request { + command: CommandTypes.GetPasteEdits; + 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; + spans: TextSpan[]; + }; + } + export interface GetPasteEditsResponse extends Response { + body: PasteEditsAction; + } + export interface PasteEditsAction { + edits: FileCodeEdits[]; + fixId?: {}; + } export interface GetEditsForRefactorRequest extends Request { command: CommandTypes.GetEditsForRefactor; arguments: GetEditsForRefactorRequestArgs; @@ -3499,6 +3527,7 @@ declare namespace ts { private getApplicableRefactors; private getEditsForRefactor; private getMoveToRefactoringFileSuggestions; + private getPasteEdits; private organizeImports; private getEditsForFileRename; private getCodeFixes; @@ -3507,6 +3536,7 @@ declare namespace ts { private getStartAndEndPosition; private mapCodeAction; private mapCodeFixAction; + private mapPasteEditsAction; private mapTextChangesToCodeEdits; private mapTextChangeToCodeEdit; private convertTextChangeToCodeEdit; @@ -10103,6 +10133,7 @@ declare namespace ts { uncommentSelection(fileName: string, textRange: TextRange): TextChange[]; getSupportedCodeFixes(fileName?: string): readonly string[]; dispose(): void; + getPasteEdits(args: PasteEditsArgs, formatOptions: FormatCodeSettings): PasteEdits; } interface JsxClosingTagInfo { readonly newText: string; @@ -10120,6 +10151,20 @@ declare namespace ts { SortAndCombine = "SortAndCombine", RemoveUnused = "RemoveUnused", } + 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 */ skipDestructiveCodeActions?: boolean; 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..bef391dfab032 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports1.js @@ -0,0 +1,337 @@ +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] 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": [ + "/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", + "pastedText": [ + "const m = t3 + t2 + 1;" + ], + "pasteLocations": [ + { + "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;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +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..7c84068e8d401 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_existingImports2.js @@ -0,0 +1,389 @@ +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] 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": [ + "/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", + "pastedText": [ + "const m = t3 + t2 + n;" + ], + "pasteLocations": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 14 + } + } + ], + "copiedFrom": { + "file": "originalFile.ts", + "spans": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 30 + } + } + ] + } + }, + "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;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +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..6f24330921c6c --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_knownSourceFile.js @@ -0,0 +1,351 @@ +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] 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", + "/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", + "pastedText": [ + "const c = a + b;\nconst t = 9;" + ], + "pasteLocations": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + } + } + ], + "copiedFrom": { + "file": "file2.ts", + "spans": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 13 + } + } + ] + } + }, + "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": "/target.ts", + "textChanges": [ + { + "start": { + "line": 1, + "offset": 1 + }, + "end": { + "line": 1, + "offset": 1 + }, + "newText": "import { b } from './file1';\nimport { a } from './file2';\n\n" + }, + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 14 + }, + "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" + } + } +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..c5dfc949fa58c --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes1.js @@ -0,0 +1,340 @@ +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;\nfunction e();\nconst f = r + s;" + ], + "pasteLocations": [ + { + "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;\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] ----------------------------------------------- +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;" + } + ] + } + ], + "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_multiplePastes2.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js new file mode 100644 index 0000000000000..4220fcf05728e --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes2.js @@ -0,0 +1,361 @@ +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] 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", + "/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", + "pastedText": [ + "export const t = aa + bb + r + s;\nconst u = 1;" + ], + "pasteLocations": [ + { + "start": { + "line": 2, + "offset": 1 + }, + "end": { + "line": 2, + "offset": 13 + } + }, + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 4, + "offset": 1 + } + } + ], + "copiedFrom": { + "file": "file1.ts", + "spans": [ + { + "start": { + "line": 4, + "offset": 1 + }, + "end": { + "line": 5, + "offset": 13 + } + } + ] + } + }, + "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;\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 +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\";\nimport { 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;" + } + ] + } + ], + "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_multiplePastes3.js b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js new file mode 100644 index 0000000000000..68e20b148b131 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_multiplePastes3.js @@ -0,0 +1,414 @@ +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] 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", + "/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", + "spans": [ + { + "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] response: + { + "seq": 0, + "type": "response", + "command": "getPasteEdits", + "request_seq": 2, + "success": true, + "performanceData": { + "updateGraphDurationMs": * + }, + "body": { + "edits": [ + { + "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;" + } + ] + }, + { + "fileName": "/file1.ts", + "textChanges": [ + { + "start": { + "line": 3, + "offset": 1 + }, + "end": { + "line": 3, + "offset": 1 + }, + "newText": "export " + } + ] + } + ], + "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_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 new file mode 100644 index 0000000000000..e26bb6787148f --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_pasteComments.js @@ -0,0 +1,265 @@ +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] 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": [ + "/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", + "pastedText": [ + "/**\n* Testing comment line 1\n* line 2\n* line 3\n* line 4\n*/" + ], + "pasteLocations": [ + { + "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*/" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +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..3386cebb96943 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_revertUpdatedFile.js @@ -0,0 +1,1242 @@ +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] 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": [ + "/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", + "pastedText": [ + "const m = t2 + 1;" + ], + "pasteLocations": [ + { + "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;" + } + ] + } + ], + "fixId": "providePostPasteEdits" + } + } +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": "Int8Array", + "kind": "var", + "kindModifiers": "declare", + "sortText": "15" + }, + { + "name": "Int8ArrayConstructor", + "kind": "interface", + "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": "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": "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": "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": "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..05a2c3289ac56 --- /dev/null +++ b/tests/baselines/reference/tsserver/fourslashServer/pasteEdits_unknownSourceFile.js @@ -0,0 +1,298 @@ +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] 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: + { + "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", + "pastedText": [ + "interface Testing {\n test1: Test1;\n test2: Test2;\n test3: Test3;\n test4: Test4;\n }" + ], + "pasteLocations": [ + { + "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 }" + } + ] + } + ], + "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 +/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/pasteEdits/adds-paste-edits.js b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js new file mode 100644 index 0000000000000..5f0a2b2a5a1be --- /dev/null +++ b/tests/baselines/reference/tsserver/pasteEdits/adds-paste-edits.js @@ -0,0 +1,344 @@ +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] +{} + +//// [/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: + { + "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 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 (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 '**/*' + +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": 1, + "dtsSize": 334, + "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": [] + } + } +Info seq [hh:mm:ss:mss] Project '/project/tsconfig.json' (Configured) +Info seq [hh:mm:ss:mss] Files (2) + +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 + +FsWatches:: +/a/lib/lib.d.ts: *new* + {} +/project/tsconfig.json: *new* + {} + +FsWatchesRecursive:: +/project: *new* + {} + +Projects:: +/project/tsconfig.json (Configured) *new* + projectStateVersion: 1 + 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 + /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 (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] ----------------------------------------------- +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:: +/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 ff8fad9abff01..e892d9d98725c 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -444,6 +444,14 @@ declare namespace FourSlashInterface { toggleMultilineComment(newFileContent: string): void; commentSelection(newFileContent: string): void; uncommentSelection(newFileContent: string): void; + pasteEdits(options: { + newFileContents: { readonly [fileName: string]: string }; + args: { + pastedText: string[]; + pasteLocations: { pos: number, end: number }[]; + copiedFrom?: { file: string, range: { pos: number, end: number }[] }; + } + }): void; } class edit { caretPosition(): Marker; diff --git a/tests/cases/fourslash/moveToFile_existingImports1.ts b/tests/cases/fourslash/moveToFile_existingImports1.ts index f7f5feaf54e8c..35c5eb80a877e 100644 --- a/tests/cases/fourslash/moveToFile_existingImports1.ts +++ b/tests/cases/fourslash/moveToFile_existingImports1.ts @@ -21,4 +21,4 @@ export const bar = x; `, }, interactiveRefactorArguments: { targetFile: "/b.ts" }, -}); +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_existingImports1.ts b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts new file mode 100644 index 0000000000000..204d6bb0c8186 --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_existingImports1.ts @@ -0,0 +1,37 @@ +/// + +// @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(); +verify.pasteEdits({ + args: { + pastedText: [ `const m = t3 + t2 + 1;`], + pasteLocations: [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/pasteEdits_existingImports2.ts b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts new file mode 100644 index 0000000000000..e12fe6350dbc0 --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_existingImports2.ts @@ -0,0 +1,45 @@ +/// + +// @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(); +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"; +import { t } from "./other"; +import { t2 } from "./other2"; +import { t3 } from "./other3"; +const a = t + 1; +const m = t3 + t2 + n; +const c = 10;` + } +}); diff --git a/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts new file mode 100644 index 0000000000000..fe9023647fb0a --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_knownSourceFile.ts @@ -0,0 +1,45 @@ +/// + +// @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(); +const t = 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'; +export const a = 1; +const c = a + b; +const t = 9;`, + + "/target.ts": +`import { b } from './file1'; +import { a } from './file2'; + +export const tt = 2; +const c = a + b; +const t = 9; +const p = 1;`, + } +}); diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts new file mode 100644 index 0000000000000..5b0e9f5bfbfdb --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes1.ts @@ -0,0 +1,46 @@ +/// + +// @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(); +verify.pasteEdits({ + args: { + pastedText: [ `const g = p + q; +function e(); +const f = r + s;`], + pasteLocations: [range[0], 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/pasteEdits_multiplePastes2.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts new file mode 100644 index 0000000000000..71de5ac278f4e --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes2.ts @@ -0,0 +1,45 @@ +/// + +// @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(); +verify.pasteEdits({ + 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"; +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;` + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts new file mode 100644 index 0000000000000..99b5451eb319f --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes3.ts @@ -0,0 +1,53 @@ +/// + +// @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(); +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;` + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts new file mode 100644 index 0000000000000..61d25803abd3d --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_multiplePastes4.ts @@ -0,0 +1,43 @@ +/// + +// @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(); +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;` + } +}); \ No newline at end of file diff --git a/tests/cases/fourslash/server/pasteEdits_pasteComments.ts b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts new file mode 100644 index 0000000000000..49d621d21387f --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_pasteComments.ts @@ -0,0 +1,33 @@ +/// + +// @Filename: /target.ts +//// const a = 10; +//// const b = 10;[||] +//// const c = 10; + +// @Filename: /tsconfig.json +////{ "files": ["target.ts"] } + +const range = test.ranges(); +verify.pasteEdits({ + args: { + pastedText: [ `/** +* Testing comment line 1 +* line 2 +* line 3 +* line 4 +*/`], + pasteLocations: [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/pasteEdits_revertUpdatedFile.ts b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts new file mode 100644 index 0000000000000..fbe0e77ef2f99 --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_revertUpdatedFile.ts @@ -0,0 +1,38 @@ +/// + +// @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(); +verify.pasteEdits({ + args: { + pastedText: [ `const m = t2 + 1;`], + pasteLocations: [range[0]], + }, + 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" }); + diff --git a/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts b/tests/cases/fourslash/server/pasteEdits_unknownSourceFile.ts new file mode 100644 index 0000000000000..f8175850ff17e --- /dev/null +++ b/tests/cases/fourslash/server/pasteEdits_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(); +verify.pasteEdits({ + args: { + pastedText: [ `interface Testing { + test1: Test1; + test2: Test2; + test3: Test3; + test4: Test4; + }`], + pasteLocations: [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;` + }, + fixId: "providePostPasteEdits" +}); \ No newline at end of file