Skip to content

Commit

Permalink
feat: Ability to add/insert statement structures.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Apr 14, 2019
1 parent cfca440 commit faaa2cd
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 23 deletions.
8 changes: 4 additions & 4 deletions lib/ts-morph.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8057,17 +8057,17 @@ export interface StatementedNode {
getStatementByKindOrThrow<TKind extends SyntaxKind>(kind: TKind): KindToNodeMappingsWithCommentStatements[TKind];
/**
* Add statements.
* @param textOrWriterFunction - Text or writer function to add the statement or statements with.
* @param statements - statements to add.
* @returns The statements that were added.
*/
addStatements(textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction>): Statement[];
addStatements(statements: string | WriterFunction | ReadonlyArray<string | WriterFunction | StatementStructures>): Statement[];
/**
* Inserts statements at the specified index.
* @param index - Child index to insert at.
* @param textOrWriterFunction - Text or writer function to write the statement or statements with.
* @param statements - Statements to insert.
* @returns The statements that were inserted.
*/
insertStatements(index: number, textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction>): Statement[];
insertStatements(index: number, statements: string | WriterFunction | ReadonlyArray<string | WriterFunction | StatementStructures>): Statement[];
/**
* Removes the statement at the specified index.
* @param index - Child index to remove the statement at.
Expand Down
32 changes: 16 additions & 16 deletions src/compiler/ast/statement/StatementedNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import * as errors from "../../../errors";
import { InsertIntoBracesOrSourceFileOptionsWriteInfo, insertIntoBracesOrSourceFileWithGetChildren, removeStatementedNodeChildren,
verifyAndGetIndex } from "../../../manipulation";
import { ClassDeclarationStructure, EnumDeclarationStructure, FunctionDeclarationStructure, InterfaceDeclarationStructure, NamespaceDeclarationStructure,
StatementedNodeStructure, TypeAliasDeclarationStructure, VariableStatementStructure, OptionalKind, Structure } from "../../../structures";
StatementedNodeStructure, TypeAliasDeclarationStructure, VariableStatementStructure, StatementStructures, OptionalKind, Structure } from "../../../structures";
import { Constructor, WriterFunction } from "../../../types";
import { SyntaxKind, ts } from "../../../typescript";
import { ArrayUtils, getNodeByNameOrFindFunction, nodeHasName, getNotFoundErrorMessageForNameOrFindFunction, getSyntaxKindName, isNodeAmbientOrInAmbientContext,
import { getNodeByNameOrFindFunction, nodeHasName, getNotFoundErrorMessageForNameOrFindFunction, getSyntaxKindName, isNodeAmbientOrInAmbientContext,
TypeGuards } from "../../../utils";
import { callBaseSet } from "../callBaseSet";
import { callBaseGetStructure } from "../callBaseGetStructure";
Expand Down Expand Up @@ -62,17 +62,17 @@ export interface StatementedNode {
getStatementByKindOrThrow<TKind extends SyntaxKind>(kind: TKind): KindToNodeMappingsWithCommentStatements[TKind];
/**
* Add statements.
* @param textOrWriterFunction - Text or writer function to add the statement or statements with.
* @param statements - statements to add.
* @returns The statements that were added.
*/
addStatements(textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction>): Statement[];
addStatements(statements: string | WriterFunction | ReadonlyArray<string | WriterFunction | StatementStructures>): Statement[];
/**
* Inserts statements at the specified index.
* @param index - Child index to insert at.
* @param textOrWriterFunction - Text or writer function to write the statement or statements with.
* @param statements - Statements to insert.
* @returns The statements that were inserted.
*/
insertStatements(index: number, textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction>): Statement[];
insertStatements(index: number, statements: string | WriterFunction | ReadonlyArray<string | WriterFunction | StatementStructures>): Statement[];
/**
* Removes the statement at the specified index.
* @param index - Child index to remove the statement at.
Expand Down Expand Up @@ -485,14 +485,18 @@ export function StatementedNode<T extends Constructor<StatementedNodeExtensionTy
return errors.throwIfNullOrUndefined(this.getStatementByKind(kind), `Expected to find a statement with syntax kind ${getSyntaxKindName(kind)}.`);
}

addStatements(textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction>) {
addStatements(textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction | StatementStructures>) {
return this.insertStatements(this._getCompilerStatementsWithComments().length, textOrWriterFunction);
}

insertStatements(index: number, textOrWriterFunction: string | WriterFunction | ReadonlyArray<string | WriterFunction>) {
insertStatements(index: number, statements: string | WriterFunction | ReadonlyArray<string | WriterFunction | StatementStructures>) {
addBodyIfNotExists(this);
const writerFunction = (writer: CodeBlockWriter) => {
const statementsPrinter = this._context.structurePrinterFactory.forStatements({ isAmbient: isNodeAmbientOrInAmbientContext(this) });
statementsPrinter.printTexts(writer, statements);
};

return getChildSyntaxList.call(this).insertChildText(index, textOrWriterFunction) as Statement[];
return getChildSyntaxList.call(this).insertChildText(index, writerFunction) as Statement[];

function getChildSyntaxList(this: Node) {
const childSyntaxList = this.getChildSyntaxListOrThrow();
Expand Down Expand Up @@ -899,13 +903,9 @@ export function StatementedNode<T extends Constructor<StatementedNodeExtensionTy

callBaseSet(Base.prototype, this, structure);

// add the text after if necessary (do this in a single print so it's fast)
if (structure.statements != null) {
this.addStatements(writer => {
const statementsPrinter = this._context.structurePrinterFactory.forStatementedNode({ isAmbient: isNodeAmbientOrInAmbientContext(this) });
statementsPrinter.printText(writer, structure);
});
}
// add the text after if necessary
if (structure.statements != null)
this.addStatements(structure.statements);

return this;
}
Expand Down
4 changes: 2 additions & 2 deletions src/structurePrinters/statement/StatementsStructurePrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ export class StatementsStructurePrinter extends Printer<StatementStructuresArray
super();
}

printTexts(writer: CodeBlockWriter, statements: StatementStructuresArrayItem[] | string | WriterFunction | undefined) {
printTexts(writer: CodeBlockWriter, statements: ReadonlyArray<StatementStructuresArrayItem> | string | WriterFunction | undefined) {
if (statements == null)
return;

if (typeof statements === "string" || statements instanceof Function)
this.printText(writer, statements)
this.printText(writer, statements);
else {
for (const statement of statements) {
if (isLastNonWhitespaceCharCloseBrace.test(writer.toString()))
Expand Down
8 changes: 7 additions & 1 deletion src/tests/compiler/ast/statement/statementedNodeTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { StatementedNodeStructure, StatementStructures, StructureKind } from "..
import { SyntaxKind } from "../../../../typescript";
import { TypeGuards } from "../../../../utils";
import { getInfoFromText, fillStructures } from "../../testHelpers";
import { WriterFunction } from "../../../../types";

function getInfoFromTextWithSyntax<T extends Node>(text: string, kind?: SyntaxKind) {
const obj = getInfoFromText(text);
Expand Down Expand Up @@ -132,7 +133,7 @@ describe(nameof(StatementedNode), () => {
});

describe(nameof<StatementedNode>(s => s.insertStatements), () => {
function doSourceFileTest(code: string, index: number, statements: string, expectedLength: number, expectedCode: string) {
function doSourceFileTest(code: string, index: number, statements: string | WriterFunction | StatementStructures[], expectedLength: number, expectedCode: string) {
const { sourceFile } = getInfoFromText(code);
const nodes = sourceFile.insertStatements(index, statements);
expect(nodes.length).to.equal(expectedLength);
Expand Down Expand Up @@ -194,6 +195,11 @@ describe(nameof(StatementedNode), () => {
"function a() {}\nfunction b() {}\nnewText;\nsecondText;");
});

it("should insert structures", () => {
doSourceFileTest("", 0, [{ kind: StructureKind.Function, name: "f" }], 1,
"function f() {\n}\n");
});

function doFirstChildTest<T extends Node>(code: string, index: number, statements: string, expectedLength: number, expectedCode: string, kind?: SyntaxKind) {
const { sourceFile, firstChild } = getInfoFromTextWithSyntax<T>(code, kind);
const nodes = (firstChild as any as StatementedNode).insertStatements(index, statements);
Expand Down

0 comments on commit faaa2cd

Please sign in to comment.