Skip to content

Commit

Permalink
feat: #370 - Add RenameableNode.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Jul 18, 2018
1 parent 5e61d27 commit 1d18158
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 93 deletions.
1 change: 1 addition & 0 deletions src/codeBlockWriter/code-block-writer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ declare class CodeBlockWriter {
toString(): string;
private _writeIndentingNewLines(text);
private _baseWriteNewline();
private dequeueQueuedIndentation();
private _updateInternalState(str);
private _writeIndentation();
private _newLineIfNewLineOnNextWrite();
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/CompilerNodeToWrappedType.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// DO NOT EDIT - Automatically maintained by createCompilerNodeToWrappedType.ts
import { ts } from "../typescript";
import * as compiler from "./index";
import { ts } from "../typescript";

export type CompilerNodeToWrappedType<T extends ts.Node> = T extends ts.ClassDeclaration ? compiler.ClassDeclaration :
T extends ts.ConstructorDeclaration ? compiler.ConstructorDeclaration :
Expand Down
16 changes: 3 additions & 13 deletions src/compiler/base/name/BindingNamedNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import { Constructor } from "../../../types";
import { SyntaxKind, ts } from "../../../typescript";
import { Identifier, Node } from "../../common";
import { ReferenceFindableNode } from "./ReferenceFindableNode";
import { RenameableNode } from "./RenameableNode";

// todo: consolidate these named classes somehow

export type BindingNamedNodeExtensionType = Node<ts.Declaration & { name: ts.BindingName; }>;

export interface BindingNamedNode extends BindingNamedNodeSpecific, ReferenceFindableNode {
export interface BindingNamedNode extends BindingNamedNodeSpecific, ReferenceFindableNode, RenameableNode {
}

export interface BindingNamedNodeSpecific {
Expand All @@ -20,15 +21,10 @@ export interface BindingNamedNodeSpecific {
* Gets the declaration's name as a string.
*/
getName(): string;
/**
* Renames the name.
* @param text - New name.
*/
rename(text: string): this;
}

export function BindingNamedNode<T extends Constructor<BindingNamedNodeExtensionType>>(Base: T): Constructor<BindingNamedNode> & T {
return BindingNamedNodeInternal(ReferenceFindableNode(Base));
return BindingNamedNodeInternal(ReferenceFindableNode(RenameableNode(Base)));
}

function BindingNamedNodeInternal<T extends Constructor<BindingNamedNodeExtensionType>>(Base: T): Constructor<BindingNamedNodeSpecific> & T {
Expand All @@ -48,11 +44,5 @@ function BindingNamedNodeInternal<T extends Constructor<BindingNamedNodeExtensio
getName() {
return this.getNameNode().getText();
}

rename(text: string) {
errors.throwIfNotStringOrWhitespace(text, nameof(text));
this.getNameNode().rename(text);
return this;
}
};
}
21 changes: 3 additions & 18 deletions src/compiler/base/name/DeclarationNamedNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ import { Constructor } from "../../../types";
import { SyntaxKind, ts } from "../../../typescript";
import { Identifier, Node } from "../../common";
import { ReferenceFindableNode } from "./ReferenceFindableNode";
import { RenameableNode } from "./RenameableNode";

// todo: support other types other than identifier
// todo: consolidate these named classes somehow

export type DeclarationNamedNodeExtensionType = Node<ts.NamedDeclaration>;

export interface DeclarationNamedNode extends DeclarationNamedNodeSpecific, ReferenceFindableNode {
export interface DeclarationNamedNode extends DeclarationNamedNodeSpecific, ReferenceFindableNode, RenameableNode {
}

export interface DeclarationNamedNodeSpecific {
Expand All @@ -29,15 +30,10 @@ export interface DeclarationNamedNodeSpecific {
* Gets the name or throws if it doens't exist.
*/
getNameOrThrow(): string;
/**
* Renames the name.
* @param text - Text to set as the name.
*/
rename(text: string): this;
}

export function DeclarationNamedNode<T extends Constructor<DeclarationNamedNodeExtensionType>>(Base: T): Constructor<DeclarationNamedNode> & T {
return DeclarationNamedNodeInternal(ReferenceFindableNode(Base));
return DeclarationNamedNodeInternal(ReferenceFindableNode(RenameableNode(Base)));
}

function DeclarationNamedNodeInternal<T extends Constructor<DeclarationNamedNodeExtensionType>>(Base: T): Constructor<DeclarationNamedNodeSpecific> & T {
Expand Down Expand Up @@ -72,16 +68,5 @@ function DeclarationNamedNodeInternal<T extends Constructor<DeclarationNamedNode
const nameNode = this.getNameNode();
return nameNode == null ? undefined : nameNode.getText();
}

rename(text: string) {
errors.throwIfNotStringOrWhitespace(text, nameof(text));
const nameNode = this.getNameNode();

if (nameNode == null)
throw errors.getNotImplementedForSyntaxKindError(this.getKind());

nameNode.rename(text);
return this;
}
};
}
15 changes: 6 additions & 9 deletions src/compiler/base/name/NameableNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { StringUtils } from "../../../utils";
import { callBaseFill } from "../../callBaseFill";
import { Identifier, Node } from "../../common";
import { ReferenceFindableNode } from "./ReferenceFindableNode";
import { RenameableNode } from "./RenameableNode";

export type NameableNodeExtensionType = Node<ts.Node & { name?: ts.Identifier; }>;

export interface NameableNode extends NameableNodeSpecific, ReferenceFindableNode {
export interface NameableNode extends NameableNodeSpecific, ReferenceFindableNode, RenameableNode {
}

export interface NameableNodeSpecific {
Expand All @@ -30,15 +31,10 @@ export interface NameableNodeSpecific {
* Gets the name if it exists, or throws.
*/
getNameOrThrow(): string;
/**
* Renames the name or sets the name if it doesn't exist.
* @param newName - New name.
*/
rename(newName: string): this;
}

export function NameableNode<T extends Constructor<NameableNodeExtensionType>>(Base: T): Constructor<NameableNode> & T {
return NameableNodeInternal(ReferenceFindableNode(Base));
return NameableNodeInternal(ReferenceFindableNode(RenameableNode(Base)));
}

function NameableNodeInternal<T extends Constructor<NameableNodeExtensionType>>(Base: T): Constructor<NameableNodeSpecific> & T {
Expand Down Expand Up @@ -82,8 +78,9 @@ function NameableNodeInternal<T extends Constructor<NameableNodeExtensionType>>(
parent: this
});
}
else
nameNode.rename(newName);
else {
Base.prototype.rename.call(this, newName);
}

return this;
}
Expand Down
22 changes: 4 additions & 18 deletions src/compiler/base/name/NamedNode.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import * as errors from "../../../errors";
import { NamedNodeStructure } from "../../../structures";
import { Constructor } from "../../../types";
import { ts } from "../../../typescript";
import { callBaseFill } from "../../callBaseFill";
import { Identifier, Node } from "../../common";
import { ReferenceFindableNode } from "./ReferenceFindableNode";
import { RenameableNode } from "./RenameableNode";

// todo: make name optional, but in a different class because TypeParameterDeclaration expects a name
// (maybe NameableNode and rename some of the other "-ed" classes)
export type NamedNodeExtensionType = Node<ts.Node & { name: ts.Identifier; }>;

export interface NamedNode extends NamedNodeSpecific, ReferenceFindableNode {
export interface NamedNode extends NamedNodeSpecific, ReferenceFindableNode, RenameableNode {
}

export interface NamedNodeSpecific {
Expand All @@ -22,15 +22,10 @@ export interface NamedNodeSpecific {
* Gets the name.
*/
getName(): string;
/**
* Renames the name.
* @param newName - New name.
*/
rename(newName: string): this;
}

export function NamedNode<T extends Constructor<NamedNodeExtensionType>>(Base: T): Constructor<NamedNode> & T {
return NamedNodeInternal(ReferenceFindableNode(Base));
return NamedNodeInternal(RenameableNode(ReferenceFindableNode(Base)));
}

export function NamedNodeInternal<T extends Constructor<NamedNodeExtensionType>>(Base: T): Constructor<NamedNodeSpecific> & T {
Expand All @@ -43,20 +38,11 @@ export function NamedNodeInternal<T extends Constructor<NamedNodeExtensionType>>
return this.getNameNode().getText();
}

rename(newName: string) {
if (newName === this.getName())
return this;

errors.throwIfNotStringOrWhitespace(newName, nameof(newName));
this.getNameNode().rename(newName);
return this;
}

fill(structure: Partial<NamedNodeStructure>) {
callBaseFill(Base.prototype, this, structure);

if (structure.name != null)
this.rename(structure.name);
(this as any as RenameableNode).rename(structure.name);

return this;
}
Expand Down
21 changes: 10 additions & 11 deletions src/compiler/base/name/PropertyNamedNode.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,30 @@
import * as errors from "../../../errors";
import { PropertyNamedNodeStructure } from "../../../structures";
import { Constructor } from "../../../types";
import { ts } from "../../../typescript";
import { PropertyName } from "../../aliases";
import { callBaseFill } from "../../callBaseFill";
import { Node } from "../../common";
import { ReferenceFindableNode } from "./ReferenceFindableNode";
import { RenameableNode } from "./RenameableNode";

export type PropertyNamedNodeExtensionType = Node<ts.Node & { name: ts.PropertyName; }>;

export interface PropertyNamedNode extends PropertyNamedNodeSpecific, ReferenceFindableNode {
export interface PropertyNamedNode extends PropertyNamedNodeSpecific, ReferenceFindableNode, RenameableNode {
}

export interface PropertyNamedNodeSpecific {
/**
* Gets the name node.
*/
getNameNode(): PropertyName;
/**
* Gets the text of the name of the node.
*/
getName(): string;
rename(text: string): this;
}

export function PropertyNamedNode<T extends Constructor<PropertyNamedNodeExtensionType>>(Base: T): Constructor<PropertyNamedNode> & T {
return PropertyNamedNodeInternal(ReferenceFindableNode(Base));
return PropertyNamedNodeInternal(ReferenceFindableNode(RenameableNode(Base)));
}

function PropertyNamedNodeInternal<T extends Constructor<PropertyNamedNodeExtensionType>>(Base: T): Constructor<PropertyNamedNodeSpecific> & T {
Expand All @@ -32,17 +37,11 @@ function PropertyNamedNodeInternal<T extends Constructor<PropertyNamedNodeExtens
return this.getNameNode().getText();
}

rename(text: string) {
errors.throwIfNotStringOrWhitespace(text, nameof(text));
this.global.languageService.renameNode(this.getNameNode(), text);
return this;
}

fill(structure: Partial<PropertyNamedNodeStructure>) {
callBaseFill(Base.prototype, this, structure);

if (structure.name != null)
this.rename(structure.name);
(this as any as RenameableNode).rename(structure.name);

return this;
}
Expand Down
33 changes: 33 additions & 0 deletions src/compiler/base/name/RenameableNode.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import * as errors from "../../../errors";
import { Constructor } from "../../../types";
import { ts } from "../../../typescript";
import { TypeGuards } from "../../../utils";
import { Node } from "../../common";

export type RenameableNodeExtensionType = Node<ts.Node>;

export interface RenameableNode {
/**
* Renames the name of the node.
* @param newName - New name.
*/
rename(newName: string): this;
}

export function RenameableNode<T extends Constructor<RenameableNodeExtensionType>>(Base: T): Constructor<RenameableNode> & T {
return class extends Base implements RenameableNode {
rename(newName: string) {
this.global.languageService.renameNode(getNodeToRename.call(this), newName);
return this;

function getNodeToRename(this: Node) {
if (TypeGuards.isIdentifier(this))
return this;
else if ((this as any).getNameNode != null)
return (this as any).getNameNode() as Node;
else
throw new errors.NotImplementedError(`Not implemented renameable scenario for ${this.getKindName()}`);
}
}
};
}
1 change: 1 addition & 0 deletions src/compiler/base/name/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export * from "./NameableNode";
export * from "./NamedNode";
export * from "./PropertyNamedNode";
export * from "./ReferenceFindableNode";
export * from "./RenameableNode";
12 changes: 2 additions & 10 deletions src/compiler/common/Identifier.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { ts } from "../../typescript";
import { ReferenceFindableNode } from "../base";
import { ReferenceFindableNode, RenameableNode } from "../base";
import { PrimaryExpression } from "../expression/PrimaryExpression";
import { DefinitionInfo, ImplementationLocation } from "../tools";
import { Node } from "./Node";

export const IdentifierBase = ReferenceFindableNode(PrimaryExpression);
export const IdentifierBase = ReferenceFindableNode(RenameableNode(PrimaryExpression));
export class Identifier extends IdentifierBase<ts.Identifier> {
/**
* Gets the text for the identifier.
Expand All @@ -13,14 +13,6 @@ export class Identifier extends IdentifierBase<ts.Identifier> {
return this.compilerNode.text;
}

/**
* Renames the identifier.
* @param newName - New name of the identifier.
*/
rename(newName: string) {
this.global.languageService.renameNode(this, newName);
}

/**
* Gets the definition nodes of the identifier.
* @remarks This is similar to "go to definition" and `.getDefinitions()`, but only returns the nodes.
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/kindToNodeMappings.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// DO NOT EDIT - Automatically maintained by createKindToNodeMappings.ts until conditional types have been released for a while.
import { SyntaxKind } from "../typescript";
import * as compiler from "./index";
import { SyntaxKind } from "../typescript";

export interface KindToNodeMappings {
[kind: number]: compiler.Node;
Expand Down
22 changes: 11 additions & 11 deletions src/factories/StructurePrinterFactory.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// DO NOT EDIT - Automatically maintained by createStructurePrinterFactory.ts
import { SupportedFormatCodeSettings } from "../options";
import * as structurePrinters from "../structurePrinters";
import { SupportedFormatCodeSettings } from "../options";
import { Memoize } from "../utils";

/**
Expand Down Expand Up @@ -34,16 +34,6 @@ export class StructurePrinterFactory {
return new structurePrinters.TypedNodeStructurePrinter(this, separator, alwaysWrite);
}

@Memoize
forJSDoc(): structurePrinters.JSDocStructurePrinter {
return new structurePrinters.JSDocStructurePrinter(this);
}

@Memoize
forDecorator(): structurePrinters.DecoratorStructurePrinter {
return new structurePrinters.DecoratorStructurePrinter(this);
}

@Memoize
forClassDeclaration(options: { isAmbient: boolean; }): structurePrinters.ClassDeclarationStructurePrinter {
return new structurePrinters.ClassDeclarationStructurePrinter(this, options);
Expand Down Expand Up @@ -89,6 +79,16 @@ export class StructurePrinterFactory {
return new structurePrinters.SpreadAssignmentStructurePrinter(this);
}

@Memoize
forDecorator(): structurePrinters.DecoratorStructurePrinter {
return new structurePrinters.DecoratorStructurePrinter(this);
}

@Memoize
forJSDoc(): structurePrinters.JSDocStructurePrinter {
return new structurePrinters.JSDocStructurePrinter(this);
}

@Memoize
forEnumDeclaration(): structurePrinters.EnumDeclarationStructurePrinter {
return new structurePrinters.EnumDeclarationStructurePrinter(this);
Expand Down

0 comments on commit 1d18158

Please sign in to comment.