Skip to content

Commit

Permalink
fix: Changing from namespace to module keyword and vice versa will no…
Browse files Browse the repository at this point in the history
…w change the node kind.
  • Loading branch information
dsherret committed Jan 1, 2018
1 parent 2b83b9a commit 38dc73b
Showing 1 changed file with 11 additions and 36 deletions.
47 changes: 11 additions & 36 deletions src/manipulation/replaction/replaceNodeText.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,23 @@
import * as ts from "typescript";
import {Node, SourceFile} from "./../../compiler";
import {Logger, TypeGuards} from "./../../utils";
import {doManipulation} from "./../doManipulation";
import {NodeHandlerFactory} from "./../nodeHandlers";
import {InsertionTextManipulator} from "./../textManipulators";

/**
* Replaces text in a source file. Good for renaming identifiers. Not good for creating new nodes!
* Replaces text in a source file. Will forget any changed nodes.
* @param sourceFile - Source file to replace in.
* @param replaceStart - Start of where to replace.
* @param replaceEnd - End of where to replace.
* @param newText - The new text to go in place.
*/
export function replaceNodeText(sourceFile: SourceFile, replaceStart: number, replaceEnd: number, newText: string) {
const difference = newText.length - (replaceEnd - replaceStart);

replaceForNode(sourceFile);
sourceFile.global.resetProgram();
sourceFile.setIsSaved(false);

function replaceForNode(node: Node) {
const currentStart = TypeGuards.isSourceFile(node) ? 0 : node.getStart();
const compilerNode = node.compilerNode;

// do the children first so that the underlying _children array is filled in based on the source file
for (const child of node.getChildren()) {
replaceForNode(child);
}

if (node.containsRange(replaceStart, replaceEnd)) {
const text = (compilerNode as any).text as string | undefined;
if (text != null) {
const relativeStart = replaceStart - currentStart;
const relativeEnd = replaceEnd - currentStart;
const newNodeText = text.substring(0, relativeStart) + newText + text.substring(relativeEnd);
if (compilerNode.kind === ts.SyntaxKind.SourceFile)
(compilerNode as any).text = newNodeText;
else if ((compilerNode as any).escapedText != null)
(compilerNode as any).escapedText = newNodeText;
else
Logger.warn("Unhandled scenario when replacing node text: Node did not have an escapedText property.");
}
compilerNode.end += difference;
}
else if (currentStart > replaceStart) {
compilerNode.pos += difference;
compilerNode.end += difference;
}
}
doManipulation(sourceFile,
new InsertionTextManipulator({
insertPos: replaceStart,
newText,
replacingLength: replaceEnd - replaceStart
}),
new NodeHandlerFactory().getForForgetChanged(sourceFile.global.compilerFactory));
}

0 comments on commit 38dc73b

Please sign in to comment.