diff --git a/src/declarations/ClassDeclaration.ts b/src/declarations/ClassDeclaration.ts index bb5264f..fcf06ac 100644 --- a/src/declarations/ClassDeclaration.ts +++ b/src/declarations/ClassDeclaration.ts @@ -1,6 +1,8 @@ import { AccessorDeclaration } from './AccessorDeclaration'; import { ConstructorDeclaration } from './ConstructorDeclaration'; -import { ClassLikeDeclaration, ExportableDeclaration, GenericDeclaration } from './Declaration'; +import { AbstractDeclaration, ClassLikeDeclaration, ExportableDeclaration, GenericDeclaration, +} from './Declaration'; +import { InterfaceDeclaration } from './InterfaceDeclaration'; import { MethodDeclaration } from './MethodDeclaration'; import { PropertyDeclaration } from './PropertyDeclaration'; @@ -12,18 +14,27 @@ import { PropertyDeclaration } from './PropertyDeclaration'; * @implements {ClassLikeDeclaration} * @implements {ExportableDeclaration} * @implements {GenericDeclaration} + * @implements {AbstractDeclaration} */ -export class ClassDeclaration implements ClassLikeDeclaration, ExportableDeclaration, GenericDeclaration { +export class ClassDeclaration + implements + ClassLikeDeclaration, + ExportableDeclaration, + GenericDeclaration, + AbstractDeclaration +{ public ctor: ConstructorDeclaration | undefined; public accessors: AccessorDeclaration[] = []; public properties: PropertyDeclaration[] = []; public methods: MethodDeclaration[] = []; public typeParameters: string[] | undefined; - + public isAbstract: boolean = false; + public implements: InterfaceDeclaration[] = []; + public extends: ClassDeclaration[] = []; constructor( public name: string, public isExported: boolean, public start?: number, public end?: number, - ) { } + ) {} } diff --git a/src/declarations/Declaration.ts b/src/declarations/Declaration.ts index f685513..99d4871 100644 --- a/src/declarations/Declaration.ts +++ b/src/declarations/Declaration.ts @@ -1,6 +1,8 @@ import { Node } from '../Node'; import { AccessorDeclaration } from './AccessorDeclaration'; +import { ClassDeclaration } from './ClassDeclaration'; import { DeclarationVisibility } from './DeclarationVisibility'; +import { InterfaceDeclaration } from './InterfaceDeclaration'; import { MethodDeclaration } from './MethodDeclaration'; import { ParameterDeclaration } from './ParameterDeclaration'; import { PropertyDeclaration } from './PropertyDeclaration'; @@ -131,6 +133,22 @@ export interface ClassLikeDeclaration extends Declaration { * @memberof ClassLikeDeclaration */ methods: MethodDeclaration[]; + + /** + * The methods of the declaration. + * + * @type {InterfaceDeclaration[]} + * @memberof ClassLikeDeclaration + */ + implements: InterfaceDeclaration[]; + + /** + * The methods of the declaration. + * + * @type {ClassDeclaration[]} + * @memberof ClassLikeDeclaration + */ + extends: ClassDeclaration[]; } /** diff --git a/src/declarations/InterfaceDeclaration.ts b/src/declarations/InterfaceDeclaration.ts index 30a356c..c82817c 100644 --- a/src/declarations/InterfaceDeclaration.ts +++ b/src/declarations/InterfaceDeclaration.ts @@ -1,4 +1,5 @@ import { AccessorDeclaration } from './AccessorDeclaration'; +import { ClassDeclaration } from './ClassDeclaration'; import { ClassLikeDeclaration, ExportableDeclaration, GenericDeclaration } from './Declaration'; import { MethodDeclaration } from './MethodDeclaration'; import { PropertyDeclaration } from './PropertyDeclaration'; @@ -16,6 +17,8 @@ export class InterfaceDeclaration implements ClassLikeDeclaration, ExportableDec public typeParameters: string[] | undefined; public properties: PropertyDeclaration[] = []; public methods: MethodDeclaration[] = []; + implements: InterfaceDeclaration[] = []; + extends: ClassDeclaration[] = []; constructor( public name: string, diff --git a/src/node-parser/class-parser.ts b/src/node-parser/class-parser.ts index d0cedd3..eb5b6e5 100644 --- a/src/node-parser/class-parser.ts +++ b/src/node-parser/class-parser.ts @@ -6,10 +6,12 @@ import { Node, ObjectBindingPattern, SyntaxKind, + isHeritageClause, } from 'typescript'; import { GetterDeclaration, SetterDeclaration } from '../declarations/AccessorDeclaration'; import { ClassDeclaration as TshClass } from '../declarations/ClassDeclaration'; +import { InterfaceDeclaration as TshInterface } from '../declarations/InterfaceDeclaration'; import { ConstructorDeclaration as TshConstructor } from '../declarations/ConstructorDeclaration'; import { DefaultDeclaration as TshDefault } from '../declarations/DefaultDeclaration'; import { MethodDeclaration as TshMethod } from '../declarations/MethodDeclaration'; @@ -130,6 +132,9 @@ export function parseClass(tsResource: Resource, node: ClassDeclaration): void { classDeclaration.typeParameters = node.typeParameters.map(param => param.getText()); } + classDeclaration.isAbstract = node.modifiers !== undefined + && node.modifiers.some(m => m.kind === SyntaxKind.AbstractKeyword); + if (node.members) { node.members.forEach((o) => { if (isPropertyDeclaration(o)) { @@ -214,6 +219,33 @@ export function parseClass(tsResource: Resource, node: ClassDeclaration): void { } }); } + + if (node.heritageClauses) { + node.heritageClauses.forEach((o) => { + if(isHeritageClause(o)){ + o.types.forEach((type) => { + if(o.token == SyntaxKind.ExtendsKeyword){ + const className = (type.expression as Identifier).escapedText; + classDeclaration.extends.push( + new TshClass( + className.toString(), + classDeclaration.isExported + ) + ); + }else if(o.token == SyntaxKind.ImplementsKeyword){ + const interfaceName = (type.expression as Identifier).escapedText; + classDeclaration.implements.push( + new TshInterface( + interfaceName.toString(), + classDeclaration.isExported + ) + ); + } + }); + } + }) + + } parseClassIdentifiers(tsResource, node); diff --git a/src/type-guards/TypescriptGuards.ts b/src/type-guards/TypescriptGuards.ts index 6e2931e..97bb9aa 100644 --- a/src/type-guards/TypescriptGuards.ts +++ b/src/type-guards/TypescriptGuards.ts @@ -5,6 +5,7 @@ import { ExternalModuleReference, FunctionDeclaration, GetAccessorDeclaration, + HeritageClause, Identifier, ImportDeclaration, ImportEqualsDeclaration, @@ -230,3 +231,14 @@ export function isGetAccessorDeclaration(node?: Node): node is GetAccessorDeclar export function isSetAccessorDeclaration(node?: Node): node is SetAccessorDeclaration { return node !== undefined && node.kind === SyntaxKind.SetAccessor; } + +/** + * Determines if the given node is a HeritageClause. + * + * @export + * @param {Node} [node] + * @returns {node is SetAccessorDeclaration} + */ +export function isHeritageClause(node?: Node): node is HeritageClause { + return node !== undefined && node.kind === SyntaxKind.HeritageClause; +}