adding function to analyze the classes

This commit is contained in:
Martin Karkowski 2020-08-21 23:50:41 +02:00
parent 8948ca4f9b
commit 36f936ddc2

View File

@ -5,7 +5,7 @@ import { ClassDeclaration, Decorator, MethodDeclaration, Node, Project, Property
* to custom names. this will then be mapped to the original name * to custom names. this will then be mapped to the original name
* @param file The Source File. * @param file The Source File.
*/ */
function getImportsOfFile(file: SourceFile) { export function getImportsOfFile(file: SourceFile) {
const mapping: { const mapping: {
[index: string]: { [index: string]: {
@ -250,7 +250,7 @@ export function getMatchingProperties(cl: ClassDeclaration, reqType: string, cas
* @param caseSensitive Turn off / on case sensitive for the checked decorator * @param caseSensitive Turn off / on case sensitive for the checked decorator
* @param extractArgs Turn off / on extracting the Arguments of the Decorator. * @param extractArgs Turn off / on extracting the Arguments of the Decorator.
*/ */
export function getDecorators(declaration: MethodDeclaration | PropertyDeclaration, decorator: string, aliasToOriginal: { [index: string]: string }, caseSensitive = true, extractArgs = true) { export function getDecorators(declaration: MethodDeclaration | PropertyDeclaration | ClassDeclaration, decorator: string, aliasToOriginal: { [index: string]: string }, caseSensitive = true, extractArgs = true) {
if (!caseSensitive) { if (!caseSensitive) {
decorator = decorator.toLowerCase(); decorator = decorator.toLowerCase();
@ -314,8 +314,7 @@ export function isPropertyInjectedWith(prop: PropertyDeclaration, decorator: str
return decorators.decorators.length > 0; return decorators.decorators.length > 0;
} }
export function getMethodInfo(declaration: MethodDeclaration) {
function getMethodInfo(declaration: MethodDeclaration) {
const abstract = declaration.isAbstract(); const abstract = declaration.isAbstract();
const isAsync = declaration.isAsync(); const isAsync = declaration.isAsync();
@ -362,7 +361,6 @@ function getMethodInfo(declaration: MethodDeclaration) {
} }
/** /**
* Function to extrac the Modifiers of a declaration. * Function to extrac the Modifiers of a declaration.
* @param declaration * @param declaration
@ -409,33 +407,58 @@ export function getModifiers(declaration: MethodDeclaration | PropertyDeclaratio
} }
} }
export function analyzeClasses(sources: SourceFile[], classDecorator: string, classInterface: string, methodDecorator: string, propertyType: string, propertyDecorator: string,){
const ret: {
className: string,
methods: any[],
properties: any[]
}[] = [];
// Function to Determine new project files. // Iterate over the Files:
const project = new Project({ for (const file of sources){
tsConfigFilePath: "./tsconfigBackend.json", // For Each File => Analyze the imported Files.
addFilesFromTsConfig: false, // Create a Mapping File for the Improts.
}); const importMapping = getImportsOfFile(file);
project.addSourceFileAtPath("./dist/test.ts");
const testSourceFiles = project.getSourceFiles()
const file = testSourceFiles[0];
// Create a Mapping File. // After all Imports has been detected => filter for all Classes that implement the provided classDecorator
const importMapping = getImportsOfFile(file); const relevantClasses = file.getClasses().filter(cl => {
const injectedClasses = file.getClasses().filter(cl => isClassImplementingInterface(cl, 'ISharedObservables', importMapping.aliasToOriginal)); return (
classInterface === '' ||
isClassImplementingInterface(cl, classInterface, importMapping.aliasToOriginal)
) && (
classDecorator === '' ||
getDecorators(cl, classDecorator, importMapping.aliasToOriginal)
)
});
// Extract the Methods. // Now after each class is known => ierate over the relevant classes
const sharedMethods = injectedClasses[0].getMethods() // and get their relevant Methods and Attributes.
.map(method => getDecorators(method, 'online', importMapping.aliasToOriginal)) for (const relevantClass of relevantClasses) {
.filter(methodObject => methodObject.decorators.length > 0 && getModifiers(methodObject.declaration).isPublic); // Extract the Methods.
const sharedMethodsOfClass = relevantClass.getMethods()
.map(method => getDecorators(method, methodDecorator, importMapping.aliasToOriginal))
.filter(methodObject => methodObject.decorators.length > 0 && getModifiers(methodObject.declaration as MethodDeclaration).isPublic);
const parsedMethods = sharedMethods.map(methodObject => getMethodInfo(methodObject.declaration as MethodDeclaration)); // Parsed Method
const parsedMethods = sharedMethodsOfClass.map(methodObject => getMethodInfo(methodObject.declaration as MethodDeclaration));
// Get the Properties // Get the Properties
const sharedObservables = getMatchingProperties(injectedClasses[0], 'NopeObersvable', false) const relevantProperties = getMatchingProperties(relevantClass, propertyType, false)
.filter(property => .filter(property =>
property.isPublic && property.isPublic &&
getDecorators(property.declaration, 'inject', importMapping.aliasToOriginal, false, false) getDecorators(property.declaration, propertyDecorator, importMapping.aliasToOriginal, false, false)
); );
console.log('Done'); const item = {
className: relevantClass.getName(),
methods: parsedMethods,
properties: relevantProperties
};
ret.push(item)
}
}
return ret;
}