Skip to content

Commit

Permalink
feat: #242 - Wrap IndexSignatureDeclaration.
Browse files Browse the repository at this point in the history
  • Loading branch information
dsherret committed Feb 9, 2018
1 parent afb18cc commit 3dab39f
Show file tree
Hide file tree
Showing 15 changed files with 558 additions and 17 deletions.
29 changes: 29 additions & 0 deletions docs/details/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,35 @@ Remove a call signature:
callSignature.remove();
```

### Index signatures

Use:

```ts
const indexSignatures = interfaceDeclaration.getIndexSignatures();
const indexSignature = interfaceDeclaration.getIndexSignature(s => s.getKeyName() === "keyName");
```

#### Add/Insert

To add or insert use `addIndexSignature()`, `addIndexSignatures()`, `insertIndexSignature`, or `insertIndexSignatures()`:

```ts
const indexSignature = interfaceDeclaration.addIndexSignature({
keyName: "someKey", // defaults to key
keyType: "string", // defaults to string
returnType: "SomeClass"
});
```

#### Remove

Remove an index signature:

```ts
indexSignature.remove();
```

### Method signatures

Use:
Expand Down
1 change: 1 addition & 0 deletions src/compiler/common/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -813,6 +813,7 @@ export class Node<NodeType extends ts.Node = ts.Node> {
const childIndex = this.getChildIndex();

try {
// todo: this should only forget the existing node if the kind changes
const nodes = getNodes(this);
const start = nodes[0].getStart();
insertIntoParent({
Expand Down
112 changes: 112 additions & 0 deletions src/compiler/interface/IndexSignatureDeclaration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import * as ts from "typescript";
import {IndexSignatureDeclarationStructure} from "./../../structures";
import {removeInterfaceMember} from "./../../manipulation";
import {callBaseFill} from "./../callBaseFill";
import {Node, Identifier} from "./../common";
import {TypeNode, Type} from "./../type";
import {JSDocableNode, ChildOrderableNode} from "./../base";

export const IndexSignatureDeclarationBase = ChildOrderableNode(JSDocableNode(Node));
export class IndexSignatureDeclaration extends IndexSignatureDeclarationBase<ts.IndexSignatureDeclaration> {
/**
* Fills the node from a structure.
* @param structure - Structure to fill.
*/
fill(structure: Partial<IndexSignatureDeclarationStructure>) {
callBaseFill(IndexSignatureDeclarationBase.prototype, this, structure);

if (structure.keyName != null)
this.setKeyName(structure.keyName);
if (structure.keyType != null)
this.setKeyType(structure.keyType);
if (structure.returnType != null)
this.setReturnType(structure.returnType);

return this;
}

/**
* Gets the key name.
*/
getKeyName() {
return this.getKeyNameNode().getText();
}

/**
* Sets the key name.
* @param name - New name.
*/
setKeyName(name: string) {
if (this.getKeyName() === name)
return;

this.getKeyNameNode().replaceWithText(name);
}

/**
* Gets the key name node.
*/
getKeyNameNode() {
const param = this.compilerNode.parameters[0];
return this.getNodeFromCompilerNode<Identifier>(param.name);
}

/**
* Gets the key type.
*/
getKeyType(): Type {
return this.getKeyTypeNode().getType();
}

/**
* Sets the key type.
* @param type - Type.
*/
setKeyType(type: string) {
if (this.getKeyTypeNode().getText() === type)
return;
this.getKeyTypeNode().replaceWithText(type);
}

/**
* Gets the key type node.
*/
getKeyTypeNode() {
const param = this.compilerNode.parameters[0];
return this.getNodeFromCompilerNode<TypeNode>(param.type!);
}

/**
* Gets the return type.
*/
getReturnType() {
return this.getReturnTypeNode().getType();
}

/**
* Gets the return type node.
*/
getReturnTypeNode() {
return this.getNodeFromCompilerNode<TypeNode>(this.compilerNode.type!);
}

/**
* Sets the return type.
* @param text
*/
setReturnType(text: string) {
const returnTypeNode = this.getReturnTypeNode();
if (returnTypeNode.getText() === text)
return this;

returnTypeNode.replaceWithText(text);
return this;
}

/**
* Removes this index signature.
*/
remove() {
removeInterfaceMember(this);
}
}
87 changes: 85 additions & 2 deletions src/compiler/interface/InterfaceDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import {getEndIndexFromArray, insertIntoBracesOrSourceFileWithFillAndGetChildren} from "./../../manipulation";
import * as errors from "./../../errors";
import {ConstructSignatureDeclarationStructure, MethodSignatureStructure, PropertySignatureStructure, InterfaceDeclarationStructure,
CallSignatureDeclarationStructure} from "./../../structures";
CallSignatureDeclarationStructure, IndexSignatureDeclarationStructure} from "./../../structures";
import {getNamedNodeByNameOrFindFunction, getNotFoundErrorMessageForNameOrFindFunction, ArrayUtils} from "./../../utils";
import * as structureToTexts from "./../../structureToTexts";
import {callBaseFill} from "./../callBaseFill";
Expand All @@ -15,10 +15,11 @@ import {Type, TypeAliasDeclaration} from "./../type";
import {ImplementationLocation} from "./../tools";
import {ConstructSignatureDeclaration} from "./ConstructSignatureDeclaration";
import {CallSignatureDeclaration} from "./CallSignatureDeclaration";
import {IndexSignatureDeclaration} from "./IndexSignatureDeclaration";
import {MethodSignature} from "./MethodSignature";
import {PropertySignature} from "./PropertySignature";

export type InterfaceMemberTypes = PropertySignature | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration;
export type InterfaceMemberTypes = PropertySignature | MethodSignature | ConstructSignatureDeclaration | CallSignatureDeclaration | IndexSignatureDeclaration;

export const InterfaceDeclarationBase = ChildOrderableNode(TextInsertableNode(ExtendsClauseableNode(HeritageClauseableNode(TypeParameteredNode(
JSDocableNode(AmbientableNode(NamespaceChildableNode(ExportableNode(ModifierableNode(NamedNode(Statement))))))
Expand All @@ -31,8 +32,12 @@ export class InterfaceDeclaration extends InterfaceDeclarationBase<ts.InterfaceD
fill(structure: Partial<InterfaceDeclarationStructure>) {
callBaseFill(InterfaceDeclarationBase.prototype, this, structure);

if (structure.callSignatures != null)
this.addCallSignatures(structure.callSignatures);
if (structure.constructSignatures != null)
this.addConstructSignatures(structure.constructSignatures);
if (structure.indexSignatures != null)
this.addIndexSignatures(structure.indexSignatures);
if (structure.properties != null)
this.addProperties(structure.properties);
if (structure.methods != null)
Expand Down Expand Up @@ -214,6 +219,84 @@ export class InterfaceDeclaration extends InterfaceDeclarationBase<ts.InterfaceD
.map(m => this.getNodeFromCompilerNode<CallSignatureDeclaration>(m as ts.CallSignatureDeclaration));
}

/**
* Add index signature.
* @param structure - Structure representing the index signature.
*/
addIndexSignature(structure: IndexSignatureDeclarationStructure) {
return this.addIndexSignatures([structure])[0];
}

/**
* Add index signatures.
* @param structures - Structures representing the index signatures.
*/
addIndexSignatures(structures: IndexSignatureDeclarationStructure[]) {
return this.insertIndexSignatures(getEndIndexFromArray(this.compilerNode.members), structures);
}

/**
* Insert index signature.
* @param index - Index to insert at.
* @param structure - Structure representing the index signature.
*/
insertIndexSignature(index: number, structure: IndexSignatureDeclarationStructure) {
return this.insertIndexSignatures(index, [structure])[0];
}

/**
* Insert properties.
* @param index - Index to insert at.
* @param structures - Structures representing the index signatures.
*/
insertIndexSignatures(index: number, structures: IndexSignatureDeclarationStructure[]) {
const indentationText = this.getChildIndentationText();

// create code
const codes = structures.map(s => {
// todo: pass in the StructureToText to the function below
const writer = this.getWriterWithChildIndentation();
const structureToText = new structureToTexts.IndexSignatureDeclarationStructureToText(writer);
structureToText.writeText(s);
return writer.toString();
});

return insertIntoBracesOrSourceFileWithFillAndGetChildren<IndexSignatureDeclaration, IndexSignatureDeclarationStructure>({
getIndexedChildren: () => this.getAllMembers(),
sourceFile: this.getSourceFile(),
parent: this,
index,
childCodes: codes,
structures,
expectedKind: ts.SyntaxKind.IndexSignature,
fillFunction: (node, structure) => node.fill(structure)
});
}

/**
* Gets the first index signature by a find function.
* @param findFunction - Function to find the index signature by.
*/
getIndexSignature(findFunction: (member: IndexSignatureDeclaration) => boolean): IndexSignatureDeclaration | undefined {
return ArrayUtils.find(this.getIndexSignatures(), findFunction);
}

/**
* Gets the first index signature by a find function or throws if not found.
* @param findFunction - Function to find the index signature by.
*/
getIndexSignatureOrThrow(findFunction: (member: IndexSignatureDeclaration) => boolean): IndexSignatureDeclaration {
return errors.throwIfNullOrUndefined(this.getIndexSignature(findFunction), "Expected to find a index signature with the provided condition.");
}

/**
* Gets the interface index signatures.
*/
getIndexSignatures(): IndexSignatureDeclaration[] {
return this.compilerNode.members.filter(m => m.kind === ts.SyntaxKind.IndexSignature)
.map(m => this.getNodeFromCompilerNode<IndexSignatureDeclaration>(m as ts.IndexSignatureDeclaration));
}

/**
* Add method.
* @param structure - Structure representing the method.
Expand Down
1 change: 1 addition & 0 deletions src/compiler/interface/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./CallSignatureDeclaration";
export * from "./ConstructSignatureDeclaration";
export * from "./IndexSignatureDeclaration";
export * from "./InterfaceDeclaration";
export * from "./MethodSignature";
export * from "./PropertySignature";
17 changes: 9 additions & 8 deletions src/factories/nodeToWrapperMappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,17 @@ export const nodeToWrapperMappings: { [key: number]: any } = {
[ts.SyntaxKind.ImportDeclaration]: compiler.ImportDeclaration,
[ts.SyntaxKind.ImportEqualsDeclaration]: compiler.ImportEqualsDeclaration,
[ts.SyntaxKind.ImportSpecifier]: compiler.ImportSpecifier,
[ts.SyntaxKind.IndexSignature]: compiler.IndexSignatureDeclaration,
[ts.SyntaxKind.InterfaceDeclaration]: compiler.InterfaceDeclaration,
[ts.SyntaxKind.IntersectionType]: compiler.IntersectionTypeNode,
[ts.SyntaxKind.JSDocTag]: compiler.JSDocUnknownTag,
[ts.SyntaxKind.JSDocAugmentsTag]: compiler.JSDocAugmentsTag,
[ts.SyntaxKind.JSDocClassTag]: compiler.JSDocClassTag,
[ts.SyntaxKind.JSDocReturnTag]: compiler.JSDocReturnTag,
[ts.SyntaxKind.JSDocTypeTag]: compiler.JSDocTypeTag,
[ts.SyntaxKind.JSDocTypedefTag]: compiler.JSDocTypedefTag,
[ts.SyntaxKind.JSDocParameterTag]: compiler.JSDocParameterTag,
[ts.SyntaxKind.JSDocPropertyTag]: compiler.JSDocPropertyTag,
[ts.SyntaxKind.LabeledStatement]: compiler.LabeledStatement,
[ts.SyntaxKind.LiteralType]: compiler.LiteralTypeNode,
[ts.SyntaxKind.MetaProperty]: compiler.MetaProperty,
Expand Down Expand Up @@ -113,14 +122,6 @@ export const nodeToWrapperMappings: { [key: number]: any } = {
[ts.SyntaxKind.JSDocComment]: compiler.JSDoc,
[ts.SyntaxKind.FirstTypeNode]: compiler.TypeNode, // todo: should be changed when implementing TypePredicateNode
[ts.SyntaxKind.LastTypeNode]: compiler.LiteralTypeNode,
[ts.SyntaxKind.JSDocTag]: compiler.JSDocUnknownTag,
[ts.SyntaxKind.JSDocAugmentsTag]: compiler.JSDocAugmentsTag,
[ts.SyntaxKind.JSDocClassTag]: compiler.JSDocClassTag,
[ts.SyntaxKind.JSDocReturnTag]: compiler.JSDocReturnTag,
[ts.SyntaxKind.JSDocTypeTag]: compiler.JSDocTypeTag,
[ts.SyntaxKind.JSDocTypedefTag]: compiler.JSDocTypedefTag,
[ts.SyntaxKind.JSDocParameterTag]: compiler.JSDocParameterTag,
[ts.SyntaxKind.JSDocPropertyTag]: compiler.JSDocPropertyTag,
[ts.SyntaxKind.SemicolonToken]: compiler.Node,
[ts.SyntaxKind.TypeOfExpression]: compiler.TypeOfExpression,
[ts.SyntaxKind.UndefinedKeyword]: compiler.Node,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { IndexSignatureDeclarationStructure } from "./../../structures";
import { StructureToText } from "./../StructureToText";

export class IndexSignatureDeclarationStructureToText extends StructureToText<IndexSignatureDeclarationStructure> {
writeText(structure: IndexSignatureDeclarationStructure) {
this.writer.write(`[${structure.keyName || "key"}: ${structure.keyType || "string"}]: ${structure.returnType};`);
}
}
1 change: 1 addition & 0 deletions src/structureToTexts/interface/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./CallSignatureDeclarationStructureToText";
export * from "./ConstructSignatureDeclarationStructureToText";
export * from "./IndexSignatureDeclarationStructureToText";
export * from "./InterfaceDeclarationStructureToText";
export * from "./MethodSignatureStructureToText";
export * from "./PropertySignatureStructureToText";
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import {JSDocableNodeStructure} from "./../base";

export interface IndexSignatureDeclarationStructure extends JSDocableNodeStructure {
keyName?: string;
keyType?: string;
returnType: string;
}
6 changes: 5 additions & 1 deletion src/structures/interface/InterfaceDeclarationStructure.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import {PropertySignatureStructure} from "./PropertySignatureStructure";
import {MethodSignatureStructure} from "./MethodSignatureStructure";
import {ConstructSignatureDeclarationStructure} from "./ConstructSignatureDeclarationStructure";
import {CallSignatureDeclarationStructure} from "./CallSignatureDeclarationStructure";
import {IndexSignatureDeclarationStructure} from "./IndexSignatureDeclarationStructure";

export interface InterfaceDeclarationStructure
extends NamedNodeStructure, InterfaceDeclarationSpecificStructure, ExtendsClauseableNodeStructure, TypeParameteredNodeStructure,
Expand All @@ -11,7 +13,9 @@ export interface InterfaceDeclarationStructure
}

export interface InterfaceDeclarationSpecificStructure {
callSignatures?: CallSignatureDeclarationStructure[];
constructSignatures?: ConstructSignatureDeclarationStructure[];
properties?: PropertySignatureStructure[];
indexSignatures?: IndexSignatureDeclarationStructure[];
methods?: MethodSignatureStructure[];
properties?: PropertySignatureStructure[];
}
1 change: 1 addition & 0 deletions src/structures/interface/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./CallSignatureDeclarationStructure";
export * from "./ConstructSignatureDeclarationStructure";
export * from "./IndexSignatureDeclarationStructure";
export * from "./InterfaceDeclarationStructure";
export * from "./MethodSignatureStructure";
export * from "./PropertySignatureStructure";

0 comments on commit 3dab39f

Please sign in to comment.