Skip to content

Commit

Permalink
feat: SourceFile#applyTextChanges now accepts objects of type `ts.T…
Browse files Browse the repository at this point in the history
…extChange`.
  • Loading branch information
dsherret committed Nov 30, 2019
1 parent e6cb995 commit e72c3f0
Show file tree
Hide file tree
Showing 6 changed files with 39 additions and 11 deletions.
2 changes: 1 addition & 1 deletion packages/ts-morph/lib/ts-morph.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8573,7 +8573,7 @@ export declare class SourceFile extends SourceFileBase<ts.SourceFile> {
* WARNING! This will forget all the nodes in the file! It's best to do this after you're all done with the file.
* @param textChanges - Text changes.
*/
applyTextChanges(textChanges: ReadonlyArray<TextChange>): this;
applyTextChanges(textChanges: ReadonlyArray<ts.TextChange | TextChange>): this;
/**
* Sets the node from a structure.
* @param structure - Structure to set the node with.
Expand Down
4 changes: 2 additions & 2 deletions packages/ts-morph/src/compiler/ast/common/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { CodeBlockWriter } from "../../../codeBlockWriter";
import { errors, ArrayUtils, StoredComparer, getSyntaxKindName, StringUtils, ts, SyntaxKind, SymbolFlags } from "@ts-morph/common";
import { ProjectContext } from "../../../ProjectContext";
import * as compiler from "../../../compiler";
import { getNextMatchingPos, getNextNonWhitespacePos, getPreviousNonWhitespacePos, getPreviousMatchingPos, getTextFromFormattingEdits,
import { getNextMatchingPos, getNextNonWhitespacePos, getPreviousNonWhitespacePos, getPreviousMatchingPos, getTextFromTextChanges,
insertIntoParentTextRange, replaceSourceFileTextForFormatting, replaceSourceFileTextStraight, hasNewLineInRange } from "../../../manipulation";
import { WriterFunction } from "../../../types";
import { getParentSyntaxList, getTextFromStringOrWriter, isStringKind, printNode, PrintNodeOptions } from "../../../utils";
Expand Down Expand Up @@ -1402,7 +1402,7 @@ export class Node<NodeType extends ts.Node = ts.Node> {

replaceSourceFileTextForFormatting({
sourceFile: this._sourceFile,
newText: getTextFromFormattingEdits(this._sourceFile, formattingEdits)
newText: getTextFromTextChanges(this._sourceFile, formattingEdits)
});
}

Expand Down
6 changes: 3 additions & 3 deletions packages/ts-morph/src/compiler/ast/module/SourceFile.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { errors, ArrayUtils, StringUtils, Memoize, EventContainer, FileUtils, LanguageVariant, ScriptTarget, ts, ScriptKind,
StandardizedFilePath } from "@ts-morph/common";
import { Directory } from "../../../fileSystem";
import { getTextFromFormattingEdits, insertIntoTextRange, replaceNodeText, replaceSourceFileForFilePathMove,
import { getTextFromTextChanges, insertIntoTextRange, replaceNodeText, replaceSourceFileForFilePathMove,
replaceSourceFileTextForFormatting } from "../../../manipulation";
import { getNextMatchingPos, getPreviousMatchingPos } from "../../../manipulation/textSeek";
import { ProjectContext } from "../../../ProjectContext";
Expand Down Expand Up @@ -919,7 +919,7 @@ export class SourceFile extends SourceFileBase<ts.SourceFile> {
* WARNING! This will forget all the nodes in the file! It's best to do this after you're all done with the file.
* @param textChanges - Text changes.
*/
applyTextChanges(textChanges: ReadonlyArray<TextChange>) {
applyTextChanges(textChanges: ReadonlyArray<ts.TextChange | TextChange>) {
// do nothing if no changes
if (textChanges.length === 0)
return this;
Expand All @@ -929,7 +929,7 @@ export class SourceFile extends SourceFileBase<ts.SourceFile> {
sourceFile: this._sourceFile,
start: 0,
replacingLength: this.getFullWidth(),
newText: getTextFromFormattingEdits(this, textChanges)
newText: getTextFromTextChanges(this, textChanges)
});
return this;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/ts-morph/src/compiler/tools/LanguageService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { errors, ObjectUtils, FileUtils, RealFileSystemHost, ResolutionHost, CompilerOptions, EditorSettings, ScriptTarget, ts, TsSourceFileContainer,
createHosts } from "@ts-morph/common";
import { ProjectContext } from "../../ProjectContext";
import { getTextFromFormattingEdits } from "../../manipulation";
import { getTextFromTextChanges } from "../../manipulation";
import { fillDefaultEditorSettings, fillDefaultFormatCodeSettings } from "../../utils";
import { Node } from "../ast/common";
import { SourceFile } from "../ast/module";
Expand Down Expand Up @@ -213,7 +213,7 @@ export class LanguageService {

formatSettings = this._getFilledSettings(formatSettings);
const formattingEdits = this.getFormattingEditsForDocument(standardizedFilePath, formatSettings);
let newText = getTextFromFormattingEdits(sourceFile, formattingEdits);
let newText = getTextFromTextChanges(sourceFile, formattingEdits);
const newLineChar = formatSettings.newLineCharacter!;

if (formatSettings.ensureNewLineAtEndOfFile && !newText.endsWith(newLineChar))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { ts } from "@ts-morph/common";
import { SourceFile, TextChange } from "../../compiler";

export function getTextFromFormattingEdits(sourceFile: SourceFile, formattingEdits: ReadonlyArray<TextChange>) {
export function getTextFromTextChanges(sourceFile: SourceFile, textChanges: ReadonlyArray<TextChange | ts.TextChange>) {
// reverse the order
const reversedFormattingEdits = formattingEdits.map((edit, index) => ({ edit, index })).sort((a, b) => {
const reversedFormattingEdits = textChanges.map((edit, index) => ({ edit: toWrappedTextChange(edit), index })).sort((a, b) => {
const aStart = a.edit.getSpan().getStart();
const bStart = b.edit.getSpan().getStart();
const difference = bStart - aStart;
Expand All @@ -17,4 +18,11 @@ export function getTextFromFormattingEdits(sourceFile: SourceFile, formattingEdi
text = text.slice(0, span.getStart()) + edit.getNewText() + text.slice(span.getEnd());
}
return text;

function toWrappedTextChange(change: TextChange | ts.TextChange) {
if (change instanceof TextChange)
return change;
else
return new TextChange(change);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from "chai";
import { EmitResult, FileSystemRefreshResult, FormatCodeSettings, SourceFile, VariableDeclarationKind } from "../../../../compiler";
import { EmitResult, FileSystemRefreshResult, FormatCodeSettings, SourceFile, VariableDeclarationKind, TextChange } from "../../../../compiler";
import { errors, CompilerOptions, LanguageVariant, ModuleResolutionKind, NewLineKind, ScriptTarget, SyntaxKind } from "@ts-morph/common";
import { IndentationText, ManipulationSettings } from "../../../../options";
import { Project } from "../../../../Project";
Expand Down Expand Up @@ -1493,6 +1493,26 @@ function myFunction(param: MyClass) {
});
});

describe(nameof<SourceFile>(s => s.applyTextChanges), () => {
// there are more tests for this functionality elsewhere... this is just testing the applyTextChanges api

it("should apply the file text change when using a wrapped object", () => {
const { sourceFile } = getInfoFromText("test;");
const change = new TextChange({ newText: "console;", span: { start: 0, length: 0 } });
sourceFile.applyTextChanges([change]);
expect(sourceFile.getText()).to.equal("console;test;");
});

it("should apply the file text change when using a compiler object", () => {
const { sourceFile } = getInfoFromText("test;");
sourceFile.applyTextChanges([
{ newText: "console;", span: { start: 0, length: 0 } },
{ newText: "asdf;", span: { start: 0, length: 5 } }
]);
expect(sourceFile.getText()).to.equal("console;asdf;");
});
});

describe(nameof<SourceFile>(s => s.getLibReferenceDirectives), () => {
it("should get when they exist", () => {
const { sourceFile } = getInfoFromText("/// <reference lib='es2017.string' />");
Expand Down

0 comments on commit e72c3f0

Please sign in to comment.