Skip to content

Commit

Permalink
feat: #625 - Add writer.withHangingIndent(() => {}). Also better ha…
Browse files Browse the repository at this point in the history
…nging indent printing

Fixes #616.
  • Loading branch information
dsherret committed May 18, 2019
1 parent 17eefea commit a544e55
Show file tree
Hide file tree
Showing 33 changed files with 246 additions and 128 deletions.
20 changes: 20 additions & 0 deletions lib/code-block-writer.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,11 @@ declare class CodeBlockWriter {
* @param whitespaceText - Gets the indentation level from the indentation text.
*/
queueIndentationLevel(whitespaceText: string): this;
/**
* Writes the text within the provided action with hanging indentation.
* @param action - Action to perform with hanging indentation.
*/
withHangingIndentation(action: () => void): this;
/**
* Sets the current indentation level.
* @param indentationLevel - Indentation level to be at.
Expand All @@ -56,6 +61,21 @@ declare class CodeBlockWriter {
* @param whitespaceText - Gets the indentation level from the indentation text.
*/
setIndentationLevel(whitespaceText: string): this;
/**
* Sets the indentation level within the provided action and restores the writer's indentation
* state afterwards.
* @remarks Restores the writer's state after the action.
* @param indentationLevel - Indentation level to queue.
* @param action - Action to perform with the indentation.
*/
withIndentationLevel(indentationLevel: number, action: () => void): this;
/**
* Sets the identation level with the provided indentation text within the provided action
* and restores the writer's indentation state afterwards.
* @param whitespaceText - Gets the indentation level from the indentation text.
* @param action - Action to perform with the indentation.
*/
withIndentationLevel(whitespaceText: string, action: () => void): this;
/**
* Gets the current indentation level.
*/
Expand Down
20 changes: 10 additions & 10 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,27 @@
"main": "dist/main.js",
"typings": "dist-declarations/ts-morph.d.ts",
"scripts": {
"dopublish": "yarn run type-check-docs && yarn run package && yarn run publish-code-verification && echo \"Run: npm publish --otp\"",
"lint": "yarn run lint-src && yarn run lint-scripts",
"dopublish": "yarn type-check-docs && yarn package && yarn publish-code-verification && echo \"Run: npm publish --otp\"",
"lint": "yarn lint-src && yarn lint-scripts",
"lint-src": "tslint \"src/**/*.ts\"",
"lint-scripts": "tslint \"scripts/**/*.ts\"",
"lint-src-and-fix": "tslint \"src/**/*.ts\" --fix",
"build": "rimraf dist && npx ttsc && ts-node --transpileOnly scripts/build/removeEmptyFiles",
"build-declarations": "rimraf dist-declarations && ts-node --max-old-space-size=8192 --transpileOnly scripts/generation/main create-code-block-writer-file create-declaration-file",
"test": "cross-env TS_NODE_COMPILER=\"ttypescript\" TS_NODE_TRANSPILE_ONLY=\"true\" mocha --opts mocha.opts",
"test-debug": "cross-env TS_NODE_COMPILER=\"ttypescript\" TS_NODE_TRANSPILE_ONLY=\"true\" mocha --opts mocha.opts --inspect-brk",
"test-watch": "yarn run test --watch-extensions ts --watch",
"test-watch": "yarn test --watch-extensions ts --watch",
"test-ts-versions": "ts-node --transpileOnly scripts/test/testTypeScriptVersions",
"test-coverage": "cross-env TS_NODE_COMPILER=\"ttypescript\" TS_NODE_TRANSPILE_ONLY=\"true\" nyc --reporter=lcov mocha --opts mocha.opts",
"test-performance": "yarn run build && node ./dist/tests/performance/run.js",
"test-performance-save": "yarn run test-performance --save",
"test-performance": "yarn build && node ./dist/tests/performance/run.js",
"test-performance-save": "yarn test-performance --save",
"type-check-library": "ts-node --transpileOnly scripts/typeCheckLibrary",
"type-check-scripts": "tsc --noEmit --project tsconfig.scripts.json",
"code-generate": "ts-node --transpileOnly --compiler ttypescript scripts/generation/main",
"refactor": "ts-node --transpileOnly scripts/refactor",
"output-wrapped-nodes": "ts-node --transpileOnly scripts/generation/outputWrappedNodesInfo",
"package": "yarn run build && yarn run build-declarations",
"publish-code-verification": "yarn run code-verification && yarn run ensure-no-declaration-file-errors && yarn run ensure-declaration-files-not-changed",
"package": "yarn build && yarn build-declarations",
"publish-code-verification": "yarn code-verification && yarn ensure-no-declaration-file-errors && yarn ensure-declaration-files-not-changed",
"code-verification": "ts-node --transpileOnly scripts/verification/main ensure-structures-match-classes ensure-overload-structures-match ensure-array-inputs-readonly ensure-classes-implement-structure-methods ensure-mixin-not-applied-multiple-times validate-public-api-class-member-names validate-compiler-node-to-wrapped-type validate-code-fences",
"ensure-structures-match-classes": "ts-node --transpileOnly scripts/verification/main ensure-structures-match-classes",
"ensure-overload-structures-match": "ts-node --transpileOnly scripts/verification/main ensure-overload-structures-match",
Expand All @@ -34,7 +34,7 @@
"ensure-declaration-files-not-changed": "ts-node --transpileOnly scripts/verification/ensureDeclarationFilesNotChanged",
"ensure-array-inputs-readonly": "ts-node --transpileOnly scripts/verification/main ensure-array-inputs-readonly",
"ensure-or-throw-exists": "ts-node --transpileOnly scripts/verification/main ensure-or-throw-exists",
"overwrite-declaration-files": "yarn run build-declarations && shx cp -rf dist-declarations/ts-morph.d.ts lib/ts-morph.d.ts && shx cp -rf dist-declarations/code-block-writer.d.ts lib/code-block-writer.d.ts",
"overwrite-declaration-files": "yarn build-declarations && shx cp -rf dist-declarations/ts-morph.d.ts lib/ts-morph.d.ts && shx cp -rf dist-declarations/code-block-writer.d.ts lib/code-block-writer.d.ts",
"type-check-docs": "ts-node --transpileOnly scripts/typeCheckDocumentation.ts",
"maintain-barrels": "barrel-maintainer src"
},
Expand Down Expand Up @@ -74,7 +74,7 @@
},
"dependencies": {
"@dsherret/to-absolute-glob": "^2.0.2",
"code-block-writer": "8.1.2",
"code-block-writer": "9.1.2",
"fs-extra": "^7.0.0",
"glob-parent": "^3.1.0",
"globby": "^8.0.1",
Expand Down Expand Up @@ -111,7 +111,7 @@
"ts-node": "7.0.0",
"tslint": "^5.11.0",
"ttypescript": "1.5.5",
"typescript": "3.4.4",
"typescript": "3.4.5",
"typescript-3.0.1": "npm:typescript@3.0.1",
"typescript-3.0.3": "npm:typescript@3.0.3",
"typescript-3.1.6": "npm:typescript@3.1.6",
Expand Down
20 changes: 20 additions & 0 deletions src/codeBlockWriter/code-block-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,11 @@ declare class CodeBlockWriter {
* @param whitespaceText - Gets the indentation level from the indentation text.
*/
queueIndentationLevel(whitespaceText: string): this;
/**
* Writes the text within the provided action with hanging indentation.
* @param action - Action to perform with hanging indentation.
*/
withHangingIndentation(action: () => void): this;
/**
* Sets the current indentation level.
* @param indentationLevel - Indentation level to be at.
Expand All @@ -59,6 +64,21 @@ declare class CodeBlockWriter {
* @param whitespaceText - Gets the indentation level from the indentation text.
*/
setIndentationLevel(whitespaceText: string): this;
/**
* Sets the indentation level within the provided action and restores the writer's indentation
* state afterwards.
* @remarks Restores the writer's state after the action.
* @param indentationLevel - Indentation level to queue.
* @param action - Action to perform with the indentation.
*/
withIndentationLevel(indentationLevel: number, action: () => void): this;
/**
* Sets the identation level with the provided indentation text within the provided action
* and restores the writer's indentation state afterwards.
* @param whitespaceText - Gets the indentation level from the indentation text.
* @param action - Action to perform with the indentation.
*/
withIndentationLevel(whitespaceText: string, action: () => void): this;
/**
* Gets the current indentation level.
*/
Expand Down
1 change: 0 additions & 1 deletion src/compiler/ast/base/BodyableNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export function BodyableNode<T extends Constructor<BodyableNodeExtensionType>>(B
return this;

const semiColon = this.getLastChildByKind(SyntaxKind.SemicolonToken);

insertIntoParentTextRange({
parent: this,
insertPos: semiColon == null ? this.getEnd() : semiColon.getStart(),
Expand Down
11 changes: 7 additions & 4 deletions src/structurePrinters/Printer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,15 @@ export abstract class Printer<TStructure> {
return newWriter;
}

protected getText(writer: CodeBlockWriter, textOrWriterFunc: string | WriterFunction) {
const newWriter = this.getNewWriter(writer);
this.printTextOrWriterFunc(newWriter, textOrWriterFunc);
return newWriter.toString();
}

protected getTextWithQueuedChildIndentation(writer: CodeBlockWriter, textOrWriterFunc: string | WriterFunction) {
const queuedChildIndentationWriter = this.getNewWriterWithQueuedChildIndentation(writer);
if (typeof textOrWriterFunc === "string")
queuedChildIndentationWriter.write(textOrWriterFunc);
else
textOrWriterFunc(queuedChildIndentationWriter);
this.printTextOrWriterFunc(queuedChildIndentationWriter, textOrWriterFunc);
return queuedChildIndentationWriter.toString();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,12 @@ export class InitializerExpressionableNodeStructurePrinter extends Printer<Initi
if (initializer == null)
return;

const initializerText = this.getTextWithQueuedChildIndentation(writer, initializer);
if (!StringUtils.isNullOrWhitespace(initializerText))
writer.write(` = ${initializerText}`);
const initializerText = this.getText(writer, initializer);
if (!StringUtils.isNullOrWhitespace(initializerText)) {
writer.withHangingIndentation(() => {
writer.spaceIfLastNot();
writer.write(`= ${initializerText}`);
});
}
}
}
9 changes: 6 additions & 3 deletions src/structurePrinters/base/ReturnTypedNodeStructurePrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ export class ReturnTypedNodeStructurePrinter extends Printer<ReturnTypedNodeStru

returnType = returnType || "void";

const returnTypeText = this.getTextWithQueuedChildIndentation(writer, returnType);
if (!StringUtils.isNullOrWhitespace(returnTypeText))
writer.write(`: ${returnTypeText}`);
const returnTypeText = this.getText(writer, returnType);
if (!StringUtils.isNullOrWhitespace(returnTypeText)) {
writer.withHangingIndentation(() => {
writer.write(`: ${returnTypeText}`);
});
}
}
}
9 changes: 6 additions & 3 deletions src/structurePrinters/base/TypedNodeStructurePrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ export class TypedNodeStructurePrinter extends Printer<TypedNodeStructure> {

type = type || "any";

const typeText = this.getTextWithQueuedChildIndentation(writer, type);
if (!StringUtils.isNullOrWhitespace(typeText))
writer.write(`${this.separator} ${typeText}`);
const typeText = this.getText(writer, type);
if (!StringUtils.isNullOrWhitespace(typeText)) {
writer.withHangingIndentation(() => {
writer.write(`${this.separator} ${typeText}`);
});
}
}
}
48 changes: 27 additions & 21 deletions src/structurePrinters/class/ClassDeclarationStructurePrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,21 @@ export class ClassDeclarationStructurePrinter extends NodePrinter<OptionalKind<C
const isAmbient = structure.hasDeclareKeyword || this.options.isAmbient;
this.factory.forJSDoc().printDocs(writer, structure.docs);
this.factory.forDecorator().printTexts(writer, structure.decorators);
this.printHeader(writer, structure);

writer.inlineBlock(() => {
this.factory.forPropertyDeclaration().printTexts(writer, structure.properties);
this.printCtors(writer, structure, isAmbient);
this.printGetAndSet(writer, structure, isAmbient);

if (!ArrayUtils.isNullOrEmpty(structure.methods)) {
this.conditionalSeparator(writer, isAmbient);
this.factory.forMethodDeclaration({ isAmbient }).printTexts(writer, structure.methods);
}
});
}

private printHeader(writer: CodeBlockWriter, structure: OptionalKind<ClassDeclarationStructure>) {
this.factory.forModifierableNode().printText(writer, structure);
writer.write(`class`);
// can be null, ex. `export default class { ... }`
Expand All @@ -28,29 +43,20 @@ export class ClassDeclarationStructurePrinter extends NodePrinter<OptionalKind<C
this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters);
writer.space();

if (structure.extends != null) {
const extendsText = this.getTextWithQueuedChildIndentation(writer, structure.extends);
if (!StringUtils.isNullOrWhitespace(extendsText))
writer.write(`extends ${extendsText} `);
}

if (structure.implements != null) {
const implementsText = structure.implements instanceof Array
? structure.implements.map(i => this.getTextWithQueuedChildIndentation(writer, i)).join(", ")
: this.getTextWithQueuedChildIndentation(writer, structure.implements);

if (!StringUtils.isNullOrWhitespace(implementsText))
writer.write(`implements ${implementsText} `);
}
writer.withHangingIndentation(() => {
if (structure.extends != null) {
const extendsText = this.getText(writer, structure.extends);
if (!StringUtils.isNullOrWhitespace(extendsText))
writer.write(`extends ${extendsText} `);
}

writer.inlineBlock(() => {
this.factory.forPropertyDeclaration().printTexts(writer, structure.properties);
this.printCtors(writer, structure, isAmbient);
this.printGetAndSet(writer, structure, isAmbient);
if (structure.implements != null) {
const implementsText = structure.implements instanceof Array
? structure.implements.map(i => this.getText(writer, i)).join(", ")
: this.getText(writer, structure.implements);

if (!ArrayUtils.isNullOrEmpty(structure.methods)) {
this.conditionalSeparator(writer, isAmbient);
this.factory.forMethodDeclaration({ isAmbient }).printTexts(writer, structure.methods);
if (!StringUtils.isNullOrWhitespace(implementsText))
writer.write(`implements ${implementsText} `);
}
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class ConstructorDeclarationStructurePrinter extends NodePrinter<Optional

protected printTextInternal(writer: CodeBlockWriter, structure: OptionalKind<ConstructorDeclarationStructure>) {
this.printOverloads(writer, getOverloadStructures());
this.printBase(writer, structure);
this.printHeader(writer, structure);
if (this.options.isAmbient)
writer.write(";");
else
Expand Down Expand Up @@ -59,17 +59,15 @@ export class ConstructorDeclarationStructurePrinter extends NodePrinter<Optional
}

printOverload(writer: CodeBlockWriter, structure: OptionalKind<ConstructorDeclarationOverloadStructure>) {
this.printBase(writer, structure);
this.printHeader(writer, structure);
writer.write(";");
}

private printBase(writer: CodeBlockWriter, structure: OptionalKind<ConstructorDeclarationStructure | ConstructorDeclarationOverloadStructure>) {
private printHeader(writer: CodeBlockWriter, structure: OptionalKind<ConstructorDeclarationStructure | ConstructorDeclarationOverloadStructure>) {
this.factory.forJSDoc().printDocs(writer, structure.docs);
this.factory.forModifierableNode().printText(writer, structure);
writer.write("constructor");
this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters);
writer.write("(");
this.factory.forParameterDeclaration().printTexts(writer, structure.parameters);
writer.write(")");
this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ export class GetAccessorDeclarationStructurePrinter extends NodePrinter<Optional
this.factory.forModifierableNode().printText(writer, structure);
writer.write(`get ${structure.name}`);
this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters);
writer.write("(");
this.factory.forParameterDeclaration().printTexts(writer, structure.parameters);
writer.write(")");
this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters);
this.factory.forReturnTypedNode().printText(writer, structure);

if (this.options.isAmbient || structure.isAbstract)
Expand Down
11 changes: 5 additions & 6 deletions src/structurePrinters/class/MethodDeclarationStructurePrinter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export class MethodDeclarationStructurePrinter extends NodePrinter<OptionalKind<

protected printTextInternal(writer: CodeBlockWriter, structure: OptionalKind<MethodDeclarationStructure>) {
this.printOverloads(writer, structure.name, getOverloadStructures());
this.printBase(writer, structure.name, structure);
this.printHeader(writer, structure.name, structure);

if (this.options.isAmbient || structure.isAbstract)
writer.write(";");
Expand Down Expand Up @@ -63,21 +63,20 @@ export class MethodDeclarationStructurePrinter extends NodePrinter<OptionalKind<
}

printOverload(writer: CodeBlockWriter, name: string, structure: OptionalKind<MethodDeclarationOverloadStructure>) {
this.printBase(writer, name, structure);
this.printHeader(writer, name, structure);
writer.write(";");
}

private printBase(writer: CodeBlockWriter, name: string, structure: OptionalKind<MethodDeclarationOverloadStructure> | OptionalKind<MethodDeclarationStructure>) {
private printHeader(writer: CodeBlockWriter, name: string, structure: OptionalKind<MethodDeclarationOverloadStructure> | OptionalKind<MethodDeclarationStructure>) {
this.factory.forJSDoc().printDocs(writer, structure.docs);
if ((structure as MethodDeclarationStructure).decorators != null)
this.factory.forDecorator().printTexts(writer, (structure as MethodDeclarationStructure).decorators);

this.factory.forModifierableNode().printText(writer, structure);
writer.write(name);
writer.conditionalWrite(structure.hasQuestionToken, "?");
this.factory.forTypeParameterDeclaration().printTextsWithBrackets(writer, structure.typeParameters);
writer.write("(");
this.factory.forParameterDeclaration().printTexts(writer, structure.parameters);
writer.write(`)`);
this.factory.forParameterDeclaration().printTextsWithParenthesis(writer, structure.parameters);
this.factory.forReturnTypedNode().printText(writer, structure);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class PropertyDeclarationStructurePrinter extends NodePrinter<OptionalKin
protected printTextInternal(writer: CodeBlockWriter, structure: OptionalKind<PropertyDeclarationStructure>) {
this.factory.forJSDoc().printDocs(writer, structure.docs);
this.factory.forDecorator().printTexts(writer, structure.decorators);

this.factory.forModifierableNode().printText(writer, structure);
writer.write(structure.name);
writer.conditionalWrite(structure.hasQuestionToken, "?");
Expand Down

0 comments on commit a544e55

Please sign in to comment.