ph-dev-tools
Version:
Development Tools for PHibernate
150 lines (135 loc) • 3.83 kB
text/typescript
import * as ts from "typescript";
import SyntaxKind = ts.SyntaxKind;
import NodeArray = ts.NodeArray;
import Decorator = ts.Decorator;
/**
* Created by Papa on 3/27/2016.
*/
export function isDecoratedAsEntity(
decorators:NodeArray<Decorator>
):boolean {
if(!decorators || !decorators.length) {
return false;
}
let isDecoratedAsEntity = decorators.some((
decorator:Decorator
) => {
let expression:ts.Identifier = <any>decorator.expression;
if(!expression) {
return false;
}
if(expression.kind === SyntaxKind.CallExpression) {
expression = <ts.Identifier>(<ts.CallExpression><any>expression).expression;
}
if (expression.kind !== SyntaxKind.Identifier) {
return false;
}
let decoratorName = expression.text;
let isEntityDecorator = decoratorName === 'Entity';
return isEntityDecorator;
});
return isDecoratedAsEntity;
}
export function getClassPath(
classSymbol:ts.Node
):string {
let classPath:string = null;
let parent = <ts.Symbol><any>classSymbol.parent;
if (!parent) {
return classPath;
}
let valueDeclaration:ts.SourceFile = <ts.SourceFile>parent.valueDeclaration;
if (!valueDeclaration || valueDeclaration.kind !== SyntaxKind.SourceFile) {
return classPath;
}
classPath = valueDeclaration.path;
return classPath;
}
export function getParentClassImport(
classSymbol:ts.Node,
parentClassName:string
):string {
let parentClassImport:string = null;
let parent = <ts.Symbol><any>classSymbol.parent;
if (!parent) {
return parentClassImport;
}
let valueDeclaration:ts.SourceFile = <ts.SourceFile>parent.valueDeclaration;
if (!valueDeclaration || valueDeclaration.kind !== SyntaxKind.SourceFile) {
return parentClassImport;
}
let imports:ts.Identifier[] = (<any>valueDeclaration)['imports'];
if (!imports || !imports.length) {
return parentClassImport;
}
imports.some((
anImport:ts.Identifier
) => {
if (anImport.kind !== SyntaxKind.StringLiteral) {
return false;
}
let parent = anImport.parent;
if (!parent || parent.kind !== SyntaxKind.ImportDeclaration) {
return false;
}
let nameMatches = endsWith(anImport.text, parentClassName);
if (nameMatches && anImport.text.length > parentClassName.length) {
nameMatches = endsWith(anImport.text, `/${parentClassName}`);
}
if (nameMatches) {
parentClassImport = anImport.text;
return true;
}
});
return parentClassImport;
}
export function getParentClassName(
classSymbol:ts.Symbol
):string {
let parentEntityName:string = null;
if (!classSymbol.declarations || !classSymbol.declarations.length) {
return parentEntityName;
}
classSymbol.declarations.some((
declaration:ts.ClassLikeDeclaration
) => {
if (declaration.kind !== SyntaxKind.ClassDeclaration) {
return false;
}
let heritageClauses = declaration.heritageClauses;
if (!heritageClauses || !heritageClauses.length) {
return false;
}
return heritageClauses.some((
heritageClause:ts.HeritageClause
) => {
if (heritageClause.kind !== SyntaxKind.HeritageClause) {
return false;
}
if (heritageClause.token !== SyntaxKind.ExtendsKeyword) {
return false;
}
let types = heritageClause.types;
if (!types || !types.length) {
return false;
}
return types.some((
type:ts.ExpressionWithTypeArguments
) => {
let expression:ts.Identifier = <any>type.expression;
if (!expression || expression.kind !== SyntaxKind.Identifier) {
return false;
}
parentEntityName = expression.text;
return true;
});
});
});
return parentEntityName;
}
export function endsWith(
target:string,
suffix:string
) {
return target.indexOf(suffix, target.length - suffix.length) !== -1;
}