Skip to content

Commit

Permalink
feat: wrap TypeOperator node (#1208)
Browse files Browse the repository at this point in the history
  • Loading branch information
jfangrad committed Oct 30, 2021
1 parent ad4fdbd commit 4722c29
Show file tree
Hide file tree
Showing 11 changed files with 113 additions and 63 deletions.
11 changes: 11 additions & 0 deletions deno/ts_morph.js
Expand Up @@ -7618,8 +7618,19 @@ class DecoratorStructurePrinter extends NodePrinter {
}
printTextInternal(writer, structure) {
writer.write(`@${structure.name}`);
this.printTypeArguments(writer, structure);
this.printArguments(writer, structure);
}
printTypeArguments(writer, structure) {
if (structure.typeArguments == null || structure.typeArguments.length === 0)
return;
writer.write("<");
for (let i = 0; i < structure.typeArguments.length; i++) {
writer.conditionalWrite(i > 0, ", ");
writer.write(this.getTextWithQueuedChildIndentation(writer, structure.typeArguments[i]));
}
writer.write(">");
}
printArguments(writer, structure) {
if (structure.arguments == null)
return;
Expand Down
16 changes: 9 additions & 7 deletions packages/ts-morph/src/compiler/ast/common/Node.ts
Expand Up @@ -2733,7 +2733,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
*/
static isFunctionLikeDeclaration<T extends compiler.Node>(node: T | undefined): node is compiler.FunctionLikeDeclaration & compiler.FunctionLikeDeclarationExtensionType & T {
switch (node?.getKind()) {
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
Expand Down Expand Up @@ -3352,7 +3351,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
switch (node?.getKind()) {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
Expand Down Expand Up @@ -3548,7 +3546,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
*/
static isParameteredNode<T extends compiler.Node>(node: T | undefined): node is compiler.ParameteredNode & compiler.ParameteredNodeExtensionType & T {
switch (node?.getKind()) {
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
Expand Down Expand Up @@ -3800,7 +3797,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
*/
static isReturnTypedNode<T extends compiler.Node>(node: T | undefined): node is compiler.ReturnTypedNode & compiler.ReturnTypedNodeExtensionType & T {
switch (node?.getKind()) {
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
Expand Down Expand Up @@ -3866,7 +3862,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
*/
static isSignaturedDeclaration<T extends compiler.Node>(node: T | undefined): node is compiler.SignaturedDeclaration & compiler.SignaturedDeclarationExtensionType & T {
switch (node?.getKind()) {
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
Expand Down Expand Up @@ -3968,7 +3963,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
*/
static isStaticableNode<T extends compiler.Node>(node: T | undefined): node is compiler.StaticableNode & compiler.StaticableNodeExtensionType & T {
switch (node?.getKind()) {
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
case SyntaxKind.PropertyDeclaration:
Expand Down Expand Up @@ -4179,6 +4173,7 @@ export class Node<NodeType extends ts.Node = ts.Node> {
case SyntaxKind.ThisType:
case SyntaxKind.TupleType:
case SyntaxKind.TypeLiteral:
case SyntaxKind.TypeOperator:
case SyntaxKind.TypePredicate:
case SyntaxKind.TypeReference:
case SyntaxKind.UnionType:
Expand All @@ -4191,6 +4186,14 @@ export class Node<NodeType extends ts.Node = ts.Node> {
/** Gets if the node is a TypeOfExpression. */
static readonly isTypeOfExpression: (node: compiler.Node | undefined) => node is compiler.TypeOfExpression = Node.is(SyntaxKind.TypeOfExpression);

/**
* Gets if the node is a TypeOperatorTypeNode.
* @param node - Node to check.
*/
static isTypeOperatorTypeNode(node: compiler.Node | undefined): node is compiler.TypeOperatorTypeNode {
return node?.getKind() === SyntaxKind.TypeOperator;
}

/**
* Gets if the node is a TypeParameterDeclaration.
* @param node - Node to check.
Expand All @@ -4207,7 +4210,6 @@ export class Node<NodeType extends ts.Node = ts.Node> {
switch (node?.getKind()) {
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.ClassStaticBlockDeclaration:
case SyntaxKind.Constructor:
case SyntaxKind.GetAccessor:
case SyntaxKind.MethodDeclaration:
Expand Down
1 change: 1 addition & 0 deletions packages/ts-morph/src/compiler/ast/kindToNodeMappings.ts
Expand Up @@ -163,6 +163,7 @@ export interface ImplementedKindToNodeMappings {
[SyntaxKind.TypeAliasDeclaration]: compiler.TypeAliasDeclaration;
[SyntaxKind.TypeAssertionExpression]: compiler.TypeAssertion;
[SyntaxKind.TypeLiteral]: compiler.TypeLiteralNode;
[SyntaxKind.TypeOperator]: compiler.TypeOperatorTypeNode;
[SyntaxKind.TypeParameter]: compiler.TypeParameterDeclaration;
[SyntaxKind.TypePredicate]: compiler.TypePredicateNode;
[SyntaxKind.TypeReference]: compiler.TypeReferenceNode;
Expand Down
11 changes: 11 additions & 0 deletions packages/ts-morph/src/compiler/ast/type/TypeOperatorTypeNode.ts
@@ -0,0 +1,11 @@
import { ts } from "@ts-morph/common";
import { TypeNode } from "./TypeNode";

export class TypeOperatorTypeNode extends TypeNode<ts.TypeOperatorNode> {
/**
* Gets the node within the type operator.
*/
getTypeNode(): TypeNode {
return this._getNodeFromCompilerNode(this.compilerNode.type);
}
}
1 change: 1 addition & 0 deletions packages/ts-morph/src/compiler/ast/type/index.ts
Expand Up @@ -18,6 +18,7 @@ export * from "./TupleTypeNode";
export * from "./TypeAliasDeclaration";
export * from "./TypeLiteralNode";
export * from "./TypeNode";
export * from "./TypeOperatorTypeNode";
export * from "./TypeParameterDeclaration";
export * from "./TypePredicateNode";
export * from "./TypeReferenceNode";
Expand Down
2 changes: 1 addition & 1 deletion packages/ts-morph/src/factories/StructurePrinterFactory.ts
@@ -1,7 +1,7 @@
// DO NOT EDIT - Automatically maintained by createStructurePrinterFactory.ts
import { Memoize } from "@ts-morph/common";
import { SupportedFormatCodeSettings } from "../options";
import * as structurePrinters from "../structurePrinters";
import { SupportedFormatCodeSettings } from "../options";

/** Cached lazy factory for StructurePrinters. */
export class StructurePrinterFactory {
Expand Down
1 change: 1 addition & 0 deletions packages/ts-morph/src/factories/kindToWrapperMappings.ts
Expand Up @@ -164,6 +164,7 @@ export const kindToWrapperMappings: { [key: number]: unknown; } = {
[SyntaxKind.TypeAliasDeclaration]: compiler.TypeAliasDeclaration,
[SyntaxKind.TypeAssertionExpression]: compiler.TypeAssertion,
[SyntaxKind.TypeLiteral]: compiler.TypeLiteralNode,
[SyntaxKind.TypeOperator]: compiler.TypeOperatorTypeNode,
[SyntaxKind.TypeParameter]: compiler.TypeParameterDeclaration,
[SyntaxKind.TypePredicate]: compiler.TypePredicateNode,
[SyntaxKind.TypeReference]: compiler.TypeReferenceNode,
Expand Down
78 changes: 36 additions & 42 deletions packages/ts-morph/src/structures/Structure.ts
Expand Up @@ -90,7 +90,6 @@ export const Structure = {
isTypeParametered<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & TypeParameteredNodeStructure {
switch (structure.kind) {
case StructureKind.Class:
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.ConstructorOverload:
case StructureKind.GetAccessor:
Expand Down Expand Up @@ -190,10 +189,31 @@ export const Structure = {
isClassStaticBlock(structure: Structure & { kind: StructureKind; }): structure is ClassStaticBlockDeclarationStructure {
return structure.kind === StructureKind.ClassStaticBlock;
},
/** Gets if the provided structure is a StaticableNodeStructure. */
isStaticable<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & StaticableNodeStructure {
/** Gets if the provided structure is a StatementedNodeStructure. */
isStatemented<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & StatementedNodeStructure {
switch (structure.kind) {
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.GetAccessor:
case StructureKind.Method:
case StructureKind.SetAccessor:
case StructureKind.Function:
case StructureKind.Module:
case StructureKind.SourceFile:
return true;
default:
return false;
}
},
/** Gets if the provided structure is a ConstructorDeclarationStructure. */
isConstructor(structure: Structure & { kind: StructureKind; }): structure is ConstructorDeclarationStructure {
return structure.kind === StructureKind.Constructor;
},
/** Gets if the provided structure is a ScopedNodeStructure. */
isScoped<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & ScopedNodeStructure {
switch (structure.kind) {
case StructureKind.Constructor:
case StructureKind.ConstructorOverload:
case StructureKind.GetAccessor:
case StructureKind.Method:
case StructureKind.MethodOverload:
Expand All @@ -207,7 +227,6 @@ export const Structure = {
/** Gets if the provided structure is a FunctionLikeDeclarationStructure. */
isFunctionLike<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & FunctionLikeDeclarationStructure {
switch (structure.kind) {
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.GetAccessor:
case StructureKind.Method:
Expand All @@ -221,7 +240,6 @@ export const Structure = {
/** Gets if the provided structure is a SignaturedDeclarationStructure. */
isSignatured<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & SignaturedDeclarationStructure {
switch (structure.kind) {
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.ConstructorOverload:
case StructureKind.GetAccessor:
Expand All @@ -241,7 +259,6 @@ export const Structure = {
/** Gets if the provided structure is a ParameteredNodeStructure. */
isParametered<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & ParameteredNodeStructure {
switch (structure.kind) {
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.ConstructorOverload:
case StructureKind.GetAccessor:
Expand All @@ -261,7 +278,6 @@ export const Structure = {
/** Gets if the provided structure is a ReturnTypedNodeStructure. */
isReturnTyped<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & ReturnTypedNodeStructure {
switch (structure.kind) {
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.ConstructorOverload:
case StructureKind.GetAccessor:
Expand All @@ -279,41 +295,6 @@ export const Structure = {
return false;
}
},
/** Gets if the provided structure is a StatementedNodeStructure. */
isStatemented<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & StatementedNodeStructure {
switch (structure.kind) {
case StructureKind.ClassStaticBlock:
case StructureKind.Constructor:
case StructureKind.GetAccessor:
case StructureKind.Method:
case StructureKind.SetAccessor:
case StructureKind.Function:
case StructureKind.Module:
case StructureKind.SourceFile:
return true;
default:
return false;
}
},
/** Gets if the provided structure is a ConstructorDeclarationStructure. */
isConstructor(structure: Structure & { kind: StructureKind; }): structure is ConstructorDeclarationStructure {
return structure.kind === StructureKind.Constructor;
},
/** Gets if the provided structure is a ScopedNodeStructure. */
isScoped<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & ScopedNodeStructure {
switch (structure.kind) {
case StructureKind.Constructor:
case StructureKind.ConstructorOverload:
case StructureKind.GetAccessor:
case StructureKind.Method:
case StructureKind.MethodOverload:
case StructureKind.Property:
case StructureKind.SetAccessor:
return true;
default:
return false;
}
},
/** Gets if the provided structure is a ConstructorDeclarationOverloadStructure. */
isConstructorDeclarationOverload(structure: Structure & { kind: StructureKind; }): structure is ConstructorDeclarationOverloadStructure {
return structure.kind === StructureKind.ConstructorOverload;
Expand All @@ -338,6 +319,19 @@ export const Structure = {
return false;
}
},
/** Gets if the provided structure is a StaticableNodeStructure. */
isStaticable<T extends Structure & { kind: StructureKind; }>(structure: T): structure is T & StaticableNodeStructure {
switch (structure.kind) {
case StructureKind.GetAccessor:
case StructureKind.Method:
case StructureKind.MethodOverload:
case StructureKind.Property:
case StructureKind.SetAccessor:
return true;
default:
return false;
}
},
/** Gets if the provided structure is a MethodDeclarationStructure. */
isMethod(structure: Structure & { kind: StructureKind; }): structure is MethodDeclarationStructure {
return structure.kind === StructureKind.Method;
Expand Down
25 changes: 13 additions & 12 deletions packages/ts-morph/src/structures/utils/forEachStructureChild.ts
Expand Up @@ -139,7 +139,19 @@ function forJSDocableNode<TStructure>(structure: JSDocableNodeStructure, callbac

/** @generated */
function forClassStaticBlockDeclaration<TStructure>(structure: ClassStaticBlockDeclarationStructure, callback: (structure: Structures) => TStructure | void): TStructure | undefined {
return forFunctionLikeDeclaration(structure, callback);
return forJSDocableNode(structure, callback)
|| forStatementedNode(structure, callback);
}

/** @generated */
function forStatementedNode<TStructure>(structure: StatementedNodeStructure, callback: (structure: Structures) => TStructure | void): TStructure | undefined {
return forAllUnknownKindIfStructure(structure.statements, callback);
}

/** @generated */
function forConstructorDeclaration<TStructure>(structure: ConstructorDeclarationStructure, callback: (structure: Structures) => TStructure | void): TStructure | undefined {
return forFunctionLikeDeclaration(structure, callback)
|| forAll(structure.overloads, callback, StructureKind.ConstructorOverload);
}

/** @generated */
Expand All @@ -160,17 +172,6 @@ function forParameteredNode<TStructure>(structure: ParameteredNodeStructure, cal
return forAll(structure.parameters, callback, StructureKind.Parameter);
}

/** @generated */
function forStatementedNode<TStructure>(structure: StatementedNodeStructure, callback: (structure: Structures) => TStructure | void): TStructure | undefined {
return forAllUnknownKindIfStructure(structure.statements, callback);
}

/** @generated */
function forConstructorDeclaration<TStructure>(structure: ConstructorDeclarationStructure, callback: (structure: Structures) => TStructure | void): TStructure | undefined {
return forFunctionLikeDeclaration(structure, callback)
|| forAll(structure.overloads, callback, StructureKind.ConstructorOverload);
}

/** @generated */
function forConstructorDeclarationOverload<TStructure>(structure: ConstructorDeclarationOverloadStructure, callback: (structure: Structures) => TStructure | void): TStructure | undefined {
return forSignaturedDeclaration(structure, callback)
Expand Down
@@ -0,0 +1,17 @@
import { SyntaxKind } from "@ts-morph/common";
import { expect } from "chai";
import { TypeOperatorTypeNode } from "../../../../compiler";
import { getInfoFromTextWithDescendant } from "../../testHelpers";

describe(nameof(TypeOperatorTypeNode), () => {
function getNode(text: string) {
return getInfoFromTextWithDescendant<TypeOperatorTypeNode>(text, SyntaxKind.TypeOperator);
}

describe(nameof<TypeOperatorTypeNode>(d => d.getType), () => {
it("should get the type", () => {
const { descendant } = getNode("var t: readonly string;");
expect(descendant.getTypeNode().getText()).to.equal("string");
});
});
});
13 changes: 12 additions & 1 deletion packages/ts-morph/wrapped-nodes.md
Expand Up @@ -6,7 +6,7 @@ The disadvantage to a node not being wrapped is that it won't have helper method

## Exist

**Total:** 200
**Total:** 204

* [ArrayBindingPattern](src/compiler/ast/binding/ArrayBindingPattern.ts)
* :heavy_check_mark: elements
Expand Down Expand Up @@ -61,6 +61,8 @@ The disadvantage to a node not being wrapped is that it won't have helper method
* [ClassElement](src/compiler/ast/class/ClassElement.ts)
* :heavy_check_mark: name
* [ClassExpression](src/compiler/ast/class/ClassExpression.ts)
* [ClassStaticBlockDeclaration](src/compiler/ast/class/ClassStaticBlockDeclaration.ts)
* :heavy_check_mark: body
* [CommaListExpression](src/compiler/ast/expression/CommaListExpression.ts)
* :heavy_check_mark: elements
* [ComputedPropertyName](src/compiler/ast/name/ComputedPropertyName.ts)
Expand Down Expand Up @@ -210,6 +212,15 @@ The disadvantage to a node not being wrapped is that it won't have helper method
* [JSDocLink](src/compiler/ast/doc/JSDocLink.ts)
* :x: name
* :x: text
* [JSDocLinkCode](src/compiler/ast/doc/JSDocLinkCode.ts)
* :x: name
* :x: text
* [JSDocLinkPlain](src/compiler/ast/doc/JSDocLinkPlain.ts)
* :x: name
* :x: text
* [JSDocMemberName](src/compiler/ast/doc/JSDocMemberName.ts)
* :x: left
* :x: right
* [JSDocOverrideTag](src/compiler/ast/doc/JSDocOverrideTag.ts)
* [JSDocParameterTag](src/compiler/ast/doc/JSDocParameterTag.ts)
* [JSDocPrivateTag](src/compiler/ast/doc/JSDocPrivateTag.ts)
Expand Down

0 comments on commit 4722c29

Please sign in to comment.