diff --git a/.gitignore b/.gitignore index e09c85c..8bea030 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ *.app Testfiles/.vscode/settings.json GraphVisualizer/node_modules +.vscode GraphVisualizer/.vscode/launch.json @@ -42,3 +43,5 @@ IngoredNamespaces.txt compile_commands.json CodeSmellDetector/node_modules CodeSmellDetector/code-smell-detector-GUI/node_modules/* + +.vscode \ No newline at end of file diff --git a/GraphGenerator/.gitignore b/GraphGenerator/.gitignore new file mode 100644 index 0000000..2d82e85 --- /dev/null +++ b/GraphGenerator/.gitignore @@ -0,0 +1 @@ +Build \ No newline at end of file diff --git a/GraphGenerator/CMakeLists.txt b/GraphGenerator/CMakeLists.txt new file mode 100644 index 0000000..ef06718 --- /dev/null +++ b/GraphGenerator/CMakeLists.txt @@ -0,0 +1,57 @@ +cmake_minimum_required(VERSION 3.13.0) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +project(GraphGenerator CXX) + +if(MSVC) + add_compile_options(/W4 /WX) +else() + add_compile_options(-Wall -Wextra -pedantic) +endif() + +find_package(wxWidgets REQUIRED gl core base OPTIONAL_COMPONENTS net) +include(${wxWidgets_USE_FILE}) + +add_library(${PROJECT_NAME}) + +add_definitions("-fno-rtti -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS") + +set(CLANG_LIBS libclang-cpp.so) +set(JSONCPP_LIBS libjsoncpp.so) + +# Try to guess the clang include paths (linux) +set(CLANG_INCLUDE_DIR "/usr/lib/llvm-15/lib/clang/15.0.2/include" CACHE STRING "The directory path to the .h files for clang.") +set(INCREMENTAL_GENERATION TRUE CACHE BOOL "Wether to mine incrementally after cancel and re-run.") +set(GUI TRUE CACHE BOOL "Wether to render the gui progress bar.") + +message("CLANG_INCLUDE_DIR: " ${CLANG_INCLUDE_DIR}) +message("INCREMENTAL_GENERATION: " ${INCREMENTAL_GENERATION}) +message("GUI: " ${GUI}) + +add_definitions(-DCLANG_INCLUDE_DIR="${CLANG_INCLUDE_DIR}") +target_compile_definitions(${PROJECT_NAME} PUBLIC INCREMENTAL_GENERATION=${INCREMENTAL_GENERATION}) +target_compile_definitions(${PROJECT_NAME} PUBLIC GUI=${GUI}) + +target_link_libraries(${PROJECT_NAME} PRIVATE ${CLANG_LIBS} ${JSONCPP_LIBS} ${wxWidgets_LIBRARIES}) + +set(SUBDIRECTORIES + DependenciesMining + FileSystem + Graph + GraphGeneration + GraphToJson + Gui + Incremental + Main + Messages + SourceLoader + Utilities +) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() diff --git a/GraphGenerator/DependenciesMining/CMakeLists.txt b/GraphGenerator/DependenciesMining/CMakeLists.txt new file mode 100644 index 0000000..efc0dbc --- /dev/null +++ b/GraphGenerator/DependenciesMining/CMakeLists.txt @@ -0,0 +1,15 @@ +set(FILES ) +set(SUBDIRECTORIES + ClangTool + Ignored + SymbolTable +) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/ClangTool/CMakeLists.txt b/GraphGenerator/DependenciesMining/ClangTool/CMakeLists.txt new file mode 100644 index 0000000..265cc81 --- /dev/null +++ b/GraphGenerator/DependenciesMining/ClangTool/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + DependenciesMining.cpp + DependenciesMining.h +) +set(SUBDIRECTORIES Utilities) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.cpp b/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.cpp index 040c2c7..318fba7 100644 --- a/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.cpp +++ b/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.cpp @@ -1,9 +1,12 @@ #include "DependenciesMining.h" #include "Utilities.h" +#include "FileSystem.h" #include "clang/Frontend/CompilerInstance.h" #include "clang/Lex/PreprocessorOptions.h" -//#include "clang/Tooling/CompilationDatabase.h" #include +#include +#include +#include #define CLASS_DECL "ClassDecl" #define STRUCT_DECL "StructDecl" @@ -11,31 +14,27 @@ #define METHOD_DECL "MethodDecl" #define METHOD_VAR_OR_ARG "MethodVarOrArg" -using namespace dependenciesMining; +namespace dependenciesMining { -// ---------------------------------------------------------------------------------------------- - -DeclarationMatcher ClassDeclMatcher = anyOf(cxxRecordDecl(isClass()).bind(CLASS_DECL), cxxRecordDecl(isStruct()).bind(STRUCT_DECL)); -DeclarationMatcher FieldDeclMatcher = fieldDecl().bind(FIELD_DECL); -DeclarationMatcher MethodDeclMatcher = cxxMethodDecl().bind(METHOD_DECL); -DeclarationMatcher MethodVarMatcher = varDecl().bind(METHOD_VAR_OR_ARG); +using namespace filesystem; // ---------------------------------------------------------------------------------------------- -SymbolTable dependenciesMining::structuresTable; -std::unordered_map dependenciesMining::ignored; +SymbolTable structuresTable; +Sources parsedFiles; +IgnoreRegistry ignored; -void initializeIgnored(const std::string& ignoredFiles, const std::string& ignoredNamespaces = "") { - ignored["filePaths"] = new IgnoredFilePaths(ignoredFiles); - ignored["namespaces"] = new IgnoredNamespaces(ignoredNamespaces); -} +inline bool IsFilePathIgnored(const std::string& path) { return ignored["filePaths"]->isIgnored(path); } +inline bool IsNamespaceIgnored(const std::string& name) { return ignored["namespaces"]->isIgnored(name); } // ---------------------------------------------------------------------------------------------- // Handle all the Classes and Structs and the Bases void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { const CXXRecordDecl* d; + Structure structure; + if ((d = result.Nodes.getNodeAs(CLASS_DECL))) { structure.SetStructureType(StructureType::Class); } @@ -46,60 +45,61 @@ void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { assert(0); } - if (isIgnoredDecl(d)) { - return; - } - // gia ta declarations if (!(d->isCompleteDefinition())) { - if (!d->hasDefinition()){ // for templateDefinition Declarations only - if(!d->getDescribedClassTemplate()) + if (!d->hasDefinition()) { // for templateDefinition Declarations only + if (!d->getDescribedClassTemplate()) return; } else { d = d->getDefinition(); } } - + + assert(d); + + const auto structID = GetIDfromDecl(d); + + if (isIgnoredDecl(d)) + return; // Templates - if (d->getDescribedClassTemplate()) { + if (d->getDescribedClassTemplate()) { structure.SetStructureType(StructureType::TemplateDefinition); - } + } else if (d->getKind() == d->ClassTemplatePartialSpecialization) { structure.SetStructureType(StructureType::TemplatePartialSpecialization); - } + } else if (d->getKind() == d->ClassTemplateSpecialization) { - if(d->getTemplateSpecializationKind() == 1) + if (d->getTemplateSpecializationKind() == 1) structure.SetStructureType(StructureType::TemplateInstantiationSpecialization); - else + else structure.SetStructureType(StructureType::TemplateFullSpecialization); - }else if (d->getKind() == d->TemplateTemplateParm) { + } + else if (d->getKind() == d->TemplateTemplateParm) { assert(0); } else if (d->getKind() == d->TemplateTypeParm) { assert(0); } - auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); + const auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); structure.SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); - if (ignored["filePaths"]->isIgnored(srcLocation.getFilename())) { + if (IsFilePathIgnored(srcLocation.getFilename())) { return; } - auto structID = GetIDfromDecl(d); //assert(structID); - structure.SetName(GetFullStructureName(d)); + structure.SetName(d->getNameAsString()); structure.SetID(structID); // Namespace std::string fullEnclosingNamespace = GetFullNamespaceName(d); - if (ignored["namespaces"]->isIgnored(fullEnclosingNamespace)) { + if (IsNamespaceIgnored(fullEnclosingNamespace)) { return; } structure.SetNamespace(fullEnclosingNamespace); - // Templates if (!d->hasDefinition()) { // Templates that has Declaration only assert(structure.GetStructureType() == StructureType::TemplateDefinition); @@ -109,65 +109,62 @@ void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { } if (d->getKind() == d->ClassTemplateSpecialization || d->getKind() == d->ClassTemplatePartialSpecialization) { - //if (structure.IsTemplateInstantiationSpecialization()){ // Template parent std::string parentName; - ID_T parentID; + ID_T parentID; - Structure* templateParent; + Structure* templateParent{ nullptr }; if (structure.IsTemplateInstantiationSpecialization()) { // template Instantiation Specialization auto* parent = d->getTemplateInstantiationPattern(); - parentID = GetIDfromDecl(parent); - //assert(parentID); + parentID = GetIDfromDecl(parent); parentName = GetFullStructureName(parent); templateParent = (Structure*)structuresTable.Lookup(parentID); } - else { // template Full and Parsial Specialization - parentName = d->getQualifiedNameAsString(); + else { // template Full and Partial Specialization + parentName = d->getQualifiedNameAsString(); + parentID = GetIDfromDecl(d); templateParent = (Structure*)structuresTable.Lookup(parentName); - assert(templateParent); - parentID = templateParent->GetID(); } + if (!templateParent) templateParent = (Structure*)structuresTable.Install(parentID, parentName); + structure.SetTemplateParent(templateParent); //Template Arguments auto* temp = (ClassTemplateSpecializationDecl*)d; for (unsigned i = 0; i < temp->getTemplateArgs().size(); ++i) { const auto& templateArg = temp->getTemplateArgs()[i]; - TemplateArgsVisit(templateArg, [](TemplateArgument templateArg, Structure *structure) { - RecordDecl* d = nullptr; - if (templateArg.getKind() == TemplateArgument::Template) { - d = (RecordDecl*)templateArg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()->getTemplatedDecl(); - if (!d) // a set of function templates - return; - } + TemplateArgsVisit(templateArg, [](TemplateArgument templateArg, Structure* structure) { + RecordDecl* d = nullptr; + if (templateArg.getKind() == TemplateArgument::Template) { + d = (RecordDecl*)templateArg.getAsTemplateOrTemplatePattern().getAsTemplateDecl()->getTemplatedDecl(); + if (!d) // a set of function templates + return; + } - if (d || GetTemplateArgType(templateArg)->isStructureOrClassType()) { - if (!d) - d = GetTemplateArgType(templateArg)->getAsCXXRecordDecl(); - std::string argStructName = GetFullStructureName(d); - auto argStructID = GetIDfromDecl(d); - //assert(argStructID); - Structure* argStruct = (Structure*)structuresTable.Lookup(argStructID); - if(argStruct == nullptr) - argStruct = (Structure*)structuresTable.Install(argStructID, argStructName); - structure->InstallTemplateSpecializationArguments(argStructID, argStruct); - } - }, &structure); + if (d || GetTemplateArgType(templateArg)->isStructureOrClassType()) { + if (!d) + d = GetTemplateArgType(templateArg)->getAsCXXRecordDecl(); + std::string argStructName = GetFullStructureName(d); + auto argStructID = GetIDfromDecl(d); + Structure* argStruct = (Structure*)structuresTable.Lookup(argStructID); + if (argStruct == nullptr) + argStruct = (Structure*)structuresTable.Install(argStructID, argStructName); + structure->InstallTemplateSpecializationArgument(argStructID, argStruct); + } + }, &structure); } } - + // Bases - for(const auto& it : d->bases()){ - auto* baseRecord = it.getType()->getAsCXXRecordDecl(); + for (const auto& it : d->bases()) { + auto* baseRecord = it.getType()->getAsCXXRecordDecl(); if (baseRecord == nullptr) // otan base einai template or partial specialization Ignored continue; std::string baseName = GetFullStructureName(baseRecord); - auto baseID = GetIDfromDecl(baseRecord); - //assert(baseID); + auto baseID = GetIDfromDecl(baseRecord); Structure* base = (Structure*)structuresTable.Lookup(baseID); if (!base) base = (Structure*)structuresTable.Install(baseID, baseName); @@ -181,9 +178,8 @@ void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { auto parent = type->getType()->getAsCXXRecordDecl(); if (!parent) // ignore decls that does not have definitions continue; - auto parentID = GetIDfromDecl(parent); - //assert(parentID); - std::string parentName = GetFullStructureName(type->getType()->getAsCXXRecordDecl()) ; + auto parentID = GetIDfromDecl(parent); + std::string parentName = GetFullStructureName(type->getType()->getAsCXXRecordDecl()); Structure* parentStructure = (Structure*)structuresTable.Lookup(parentID); if (!parentStructure) parentStructure = (Structure*)structuresTable.Install(parentID, parentName); @@ -193,31 +189,30 @@ void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { auto* decl = it->getFriendDecl(); auto kind = decl->getKind(); if (decl->getKind() == d->CXXMethod || decl->getKind() == d->FunctionTemplate) { - CXXMethodDecl* methodDecl; + CXXMethodDecl* methodDecl; if (decl->getKind() == d->FunctionTemplate) { // Template Methods auto funcdecl = ((FunctionTemplateDecl*)decl)->getTemplatedDecl(); auto parent = funcdecl->getParent(); - if(!parent->isRecord()) // Ignore Template Function + if (!parent->isRecord()) // Ignore Template Function continue; - methodDecl = (CXXMethodDecl*)funcdecl; + methodDecl = (CXXMethodDecl*)funcdecl; } else { methodDecl = (CXXMethodDecl*)decl; } std::string methodName = GetFullMethodName(methodDecl); auto* parentClass = methodDecl->getParent(); - auto parentClassID = GetIDfromDecl(parentClass); - //assert(parentClassID); + auto parentClassID = GetIDfromDecl(parentClass); Structure* parentStructure = (Structure*)structuresTable.Lookup(parentClassID); if (!parentStructure) continue; // meta thn allagh se ids ws keys den krataw info gia to idio to method alla mono gia to structure pou anoikei structure.InstallFriend(parentClassID, parentStructure); } else if (decl->isTemplateDecl()) { // Template Classes - auto recdecl = (RecordDecl*)((TemplateDecl*)decl)->getTemplatedDecl(); - auto structureDefinition = recdecl->getDefinition(); + auto recdecl = (RecordDecl*)((TemplateDecl*)decl)->getTemplatedDecl(); + auto structureDefinition = recdecl->getDefinition(); if (!structureDefinition) // ignore decls that does not have definitions - continue; + continue; auto parentID = GetIDfromDecl(structureDefinition); auto parentName = GetFullStructureName(structureDefinition); @@ -239,7 +234,6 @@ void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { assert(parent); std::string parentName = GetFullStructureName((RecordDecl*)parent); auto parentID = GetIDfromDecl((RecordDecl*)parent); - //assert(parentID); if (isIgnoredDecl((RecordDecl*)parent)) { return; } @@ -251,25 +245,14 @@ void ClassDeclsCallback::run(const MatchFinder::MatchResult& result) { } } structuresTable.Install(structure.GetID(), structure); - /*FindFieldStmt visitor; - visitor.TraverseAST(d->getASTContext()); - auto fields = d->fields(); - for (auto field : fields) { - std::cout << field-> << std::endl; - }*/ } -//bool ClassDeclsCallback::FindFieldStmt::TraverseAST(clang::ASTContext& ast) { -// //ast -// //std::cout << ast. << std::endl; -// //FindFieldStmt::TraverseAST(ast); -// return true; -//} - // ---------------------------------------------------------------------------------------------- // Hanlde all the Fields in classes/structs (non structure fields) void FeildDeclsCallback::installFundamentalField(const MatchFinder::MatchResult& result) { if (const FieldDecl* d = result.Nodes.getNodeAs(FIELD_DECL)) { + const auto fieldID = GetIDfromDecl(d); + auto* parent = d->getParent(); // Ignored @@ -278,31 +261,9 @@ void FeildDeclsCallback::installFundamentalField(const MatchFinder::MatchResult& std::string parentName = GetFullStructureName(parent); std::string typeName = d->getType().getAsString(); ID_T parentID = GetIDfromDecl(parent); - //if (d->getType()->isPointerType() || d->getType()->isReferenceType()) { - // typeName = GetFullStructureName(d->getType()->getPointeeType()->getAsRecordDecl()); // CXX - // typeID = GetIDfromDecl(d->getType()->getPointeeType()->getAsRecordDecl()); // CXX - //} - //else { - // typeName = GetFullStructureName(d->getType()->getAsCXXRecordDecl()); - // typeID = GetIDfromDecl(d->getType()->getAsCXXRecordDecl()); - //} - - - Structure* parentStructure = (Structure*)structuresTable.Lookup(parentID); - - //Structure* typeStructure = (Structure*)structuresTable.Lookup(typeID); - - - //if (parentStructure->IsTemplateInstantiationSpecialization()) // insertion speciallization inherit its dependencies from the parent template - // return; - //if (!typeStructure) - // typeStructure = (Structure*)structuresTable.Install(typeID, typeName); - - auto fieldID = GetIDfromDecl(d); - //assert(fieldID); - Definition field(fieldID, d->getQualifiedNameAsString(), parentStructure->GetNamespace()); + Definition field(fieldID, d->getNameAsString(), parentStructure->GetNamespace()); field.SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); field.SetFullType(typeName); auto* _field = parentStructure->InstallField(fieldID, field); @@ -311,24 +272,30 @@ void FeildDeclsCallback::installFundamentalField(const MatchFinder::MatchResult& } - // Hanlde all the Fields in classes/structs (structure fields) void FeildDeclsCallback::run(const MatchFinder::MatchResult& result) { if (const FieldDecl* d = result.Nodes.getNodeAs(FIELD_DECL)) { + assert(d); - auto* parent = d->getParent(); + const auto fieldID = GetIDfromDecl(d); + const auto* parent = d->getParent(); + assert(parent); + + if (!parent->isClass() and !parent->isStruct()) + return; + + const auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); // Ignored - auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); - if (ignored["filePaths"]->isIgnored(srcLocation.getFilename())) { + if (IsFilePathIgnored(srcLocation.getFilename())) { return; } - - if (ignored["namespaces"]->isIgnored(GetFullNamespaceName(parent))) { + + if (IsNamespaceIgnored(GetFullNamespaceName(parent))) { return; } - if(isIgnoredDecl(parent)) { + if (isIgnoredDecl(parent)) { return; } @@ -350,8 +317,6 @@ void FeildDeclsCallback::run(const MatchFinder::MatchResult& result) { typeName = GetFullStructureName(d->getType()->getAsCXXRecordDecl()); typeID = GetIDfromDecl(d->getType()->getAsCXXRecordDecl()); } - //assert(parentID); - //assert(typeID); Structure* parentStructure = (Structure*)structuresTable.Lookup(parentID); Structure* typeStructure = (Structure*)structuresTable.Lookup(typeID); @@ -360,9 +325,7 @@ void FeildDeclsCallback::run(const MatchFinder::MatchResult& result) { if (!typeStructure) typeStructure = (Structure*)structuresTable.Install(typeID, typeName); - auto fieldID = GetIDfromDecl(d); - //assert(fieldID); - Definition field(fieldID, d->getQualifiedNameAsString(), parentStructure->GetNamespace(), typeStructure); + Definition field(fieldID, d->getNameAsString(), parentStructure->GetNamespace(), typeStructure); field.SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); field.SetFullType(d->getType().getAsString()); auto* _field = parentStructure->InstallField(fieldID, field); @@ -376,24 +339,24 @@ void FeildDeclsCallback::run(const MatchFinder::MatchResult& result) { // Handle all the Methods void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { if (const CXXMethodDecl* d = result.Nodes.getNodeAs(METHOD_DECL)) { + assert(d); + + const auto methodID = GetIDfromDecl(d); + const RecordDecl* parent = d->getParent(); std::string parentName = GetFullStructureName(parent); auto parentID = GetIDfromDecl(parent); - auto methodID = GetIDfromDecl(d); - //assert(parentID); - //assert(methodID); - - if(!(d->isThisDeclarationADefinition())){ + if (!(d->isThisDeclarationADefinition())) { return; } + const auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); // Ignored - auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); - if (ignored["filePaths"]->isIgnored(srcLocation.getFilename())) { + if (IsFilePathIgnored(srcLocation.getFilename())) { return; } - if (ignored["namespaces"]->isIgnored(GetFullNamespaceName(parent))) { + if (IsNamespaceIgnored(GetFullNamespaceName(parent))) { return; } @@ -403,10 +366,7 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { Structure* parentStructure = (Structure*)structuresTable.Lookup(parentID); assert(parentStructure); - /*if (!parentStructure) { - parentStructure = (Structure*)structuresTable.Install(parentID, parentName); - }*/ - Method method(methodID, GetFullMethodName(d), parentStructure->GetNamespace()); + Method method(methodID, d->getNameAsString(), parentStructure->GetNamespace()); method.SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); // Method's Type @@ -460,21 +420,6 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { //Template if (method.IsTemplateFullSpecialization() || method.IsTemplateInstantiationSpecialization()) { - /* // Tempalte Method's parent - Method* templateParentMethod = nullptr; - std::string parentMethodName = GetFullMethodName(d); - size_t start = parentMethodName.find("<"); - size_t end = parentMethodName.find(">"); - parentMethodName.erase(parentMethodName.begin() + start, parentMethodName.begin() + end + 1); - if (parentStructure->IsTemplateFullSpecialization() || parentStructure->IsTemplateInstantiationSpecialization()) { - - templateParentMethod = parentStructure->GetTemplateParent()->GetMethod(parentMethodName); - } - else { - templateParentMethod = parentStructure->GetMethod(parentMethodName); - } - assert(templateParentMethod); - method.SetTemplateParent(templateParentMethod);*/ //Template Arguments auto args = d->getTemplateSpecializationArgs()->asArray(); for (auto it : args) { @@ -497,7 +442,7 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { Structure* argStruct = (Structure*)structuresTable.Lookup(argStructID); if (argStruct == nullptr) argStruct = (Structure*)structuresTable.Install(argStructID, argStructName); - method->InstallTemplateSpecializationArguments(argStructID, argStruct); + method->InstallTemplateSpecializationArgument(argStructID, argStruct); } }, &method); } @@ -516,7 +461,6 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { typeName = GetFullStructureName(returnType->getAsCXXRecordDecl()); typeID = GetIDfromDecl(returnType->getAsCXXRecordDecl()); } - //assert(typeID); Structure* typeStructure = (Structure*)structuresTable.Lookup(typeID); if (!typeStructure) typeStructure = (Structure*)structuresTable.Install(typeID, typeName); @@ -525,14 +469,14 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { currentMethod = (Method*)parentStructure->InstallMethod(methodID, method); sm = result.SourceManager; - + // Body - MemberExpr auto* body = d->getBody(); if (body == nullptr) { currentMethod = nullptr; return; } - FindMemberExprVisitor visitor; + FindMemberExprVisitor visitor; literal_count = 0; statement_count = 0; @@ -542,9 +486,7 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { scope_max_depth = 0; visitor.TraverseStmt(body); - - //std::cout << d->getAccess() << std::endl; currentMethod->SetAccessType((AccessType)d->getAccess()); currentMethod->SetLiterals(literal_count); currentMethod->SetStatements(statement_count); @@ -555,7 +497,7 @@ void MethodDeclsCallback::run(const MatchFinder::MatchResult& result) { currentMethod->SetVirtual(d->isVirtual()); currentMethod = nullptr; - + } } @@ -568,41 +510,31 @@ bool MethodDeclsCallback::FindMemberExprVisitor::TraverseStmt(Stmt* stmt) { std::string class_name = stmt->getStmtClassName(); switch (stmt->getStmtClass()) { - case Stmt::StmtClass::CompoundStmtClass: - MethodDeclsCallback::statement_count += std::distance(stmt->child_begin(), stmt->child_end()); - scope_depth++; - if (scope_max_depth < scope_depth) - scope_max_depth = scope_depth; - break; - - case Stmt::StmtClass::IfStmtClass: - case Stmt::StmtClass::SwitchStmtClass: - case Stmt::StmtClass::BreakStmtClass: - case Stmt::StmtClass::ContinueStmtClass: - case Stmt::StmtClass::GotoStmtClass: - case Stmt::StmtClass::ReturnStmtClass: - MethodDeclsCallback::branch_count++; - break; - - case Stmt::StmtClass::ForStmtClass: - case Stmt::StmtClass::WhileStmtClass: - MethodDeclsCallback::loop_count++; - break; - /*case Stmt::StmtClass::CStyleCastExprClass: { - std::cout << ((CStyleCastExpr*)stmt)->getType().getAsString() << std::endl; - auto children = stmt->children(); - for (auto child : children) { - - std::cout << ((ImplicitCastExpr*)child)->getCastKindName() << std::endl; - } - break; - }*/ - - - default: { - if (class_name.find("Literal") != std::string::npos) - MethodDeclsCallback::literal_count++; - } + case Stmt::StmtClass::CompoundStmtClass: + MethodDeclsCallback::statement_count += std::distance(stmt->child_begin(), stmt->child_end()); + scope_depth++; + if (scope_max_depth < scope_depth) + scope_max_depth = scope_depth; + break; + + case Stmt::StmtClass::IfStmtClass: + case Stmt::StmtClass::SwitchStmtClass: + case Stmt::StmtClass::BreakStmtClass: + case Stmt::StmtClass::ContinueStmtClass: + case Stmt::StmtClass::GotoStmtClass: + case Stmt::StmtClass::ReturnStmtClass: + MethodDeclsCallback::branch_count++; + break; + + case Stmt::StmtClass::ForStmtClass: + case Stmt::StmtClass::WhileStmtClass: + MethodDeclsCallback::loop_count++; + break; + + default: { + if (class_name.find("Literal") != std::string::npos) + MethodDeclsCallback::literal_count++; + } } RecursiveASTVisitor::TraverseStmt(stmt); if (stmt->getStmtClass() == Stmt::StmtClass::CompoundStmtClass) @@ -617,15 +549,13 @@ bool MethodDeclsCallback::FindMemberExprVisitor::VisitMemberExpr(MemberExpr* mem auto type = memberExpr->getType(); auto* base = memberExpr->getBase(); - - if (base) { base = base->IgnoreUnlessSpelledInSource(); // clean all the invisble AST nodes that may surround this stmt if (base->getStmtClass() == memberExpr->CXXThisExprClass) // ignore this return true; - std::string str; + std::string str; Method::Member::MemberType memType; if (base->getStmtClass() == memberExpr->DeclRefExprClass) { str = "__LOCAL DEF__"; @@ -633,7 +563,7 @@ bool MethodDeclsCallback::FindMemberExprVisitor::VisitMemberExpr(MemberExpr* mem } else if (base->getStmtClass() == memberExpr->MemberExprClass && ((MemberExpr*)base)->getBase()->getStmtClass() == memberExpr->CXXThisExprClass) { str = "__CLASS FIELD__"; - memType = ClassField_mem_t; + memType = ClassField_mem_t; } else if (base->getStmtClass() == memberExpr->CXXMemberCallExprClass) { str = "__CLASS METHOD__"; @@ -643,16 +573,16 @@ bool MethodDeclsCallback::FindMemberExprVisitor::VisitMemberExpr(MemberExpr* mem str = "__??__"; memType = Value_mem_t; } - + auto baseType = base->getType(); auto baseRange = base->getSourceRange(); auto baseScLocationBegin = MethodDeclsCallback::sm->getPresumedLoc(baseRange.getBegin()); auto baseScLocationEnd = MethodDeclsCallback::sm->getPresumedLoc(baseRange.getEnd()); SourceInfo baseLocBegin(baseScLocationBegin.getFilename(), baseScLocationBegin.getLine(), baseScLocationBegin.getColumn()); SourceInfo baseLocEnd(baseScLocationEnd.getFilename(), baseScLocationEnd.getLine(), baseScLocationEnd.getColumn()); - std::string exprString = str; + std::string exprString = str; Method::MemberExpr methodMemberExpr("__DUMMY EXPR__", baseLocEnd, baseLocBegin.GetFileName(), baseLocBegin.GetLine(), baseLocBegin.GetColumn()); - + std::string typeName; ID_T typeID; if (baseType->isPointerType() || baseType->isReferenceType()) { @@ -669,9 +599,9 @@ bool MethodDeclsCallback::FindMemberExprVisitor::VisitMemberExpr(MemberExpr* mem Method::Member member(str, typeStructure, baseLocEnd, memType); MethodDeclsCallback::currentMethod->InsertMemberExpr(methodMemberExpr, member, baseLocBegin.toString()); - + } - + auto range = memberExpr->getSourceRange(); auto srcLocationBegin = MethodDeclsCallback::sm->getPresumedLoc(range.getBegin()); auto srcLocationEnd = MethodDeclsCallback::sm->getPresumedLoc(range.getEnd()); @@ -679,62 +609,9 @@ bool MethodDeclsCallback::FindMemberExprVisitor::VisitMemberExpr(MemberExpr* mem SourceInfo locEnd(srcLocationEnd.getFilename(), srcLocationEnd.getLine(), srcLocationEnd.getColumn()); std::string exprString; - //if (decl->getKind() == decl->CXXMethod) { - // auto end = sm->getCharacterData(range.getEnd()); - // int openCount = 0, closeCount = 0; - // while (!(openCount == closeCount && openCount)) { - // if (*end == '(') { - // openCount++; - // } - // else if (*end == ')') { - // closeCount++; - // } - // end++; - // } - // const char* beginstr = sm->getCharacterData(range.getBegin()); - // exprString = std::string(beginstr, end); - //} - //else { - // exprString = std::string(sm->getCharacterData(range.getBegin()), sm->getCharacterData(range.getEnd())) + decl->getNameAsString(); - //} - Method::MemberExpr methodMemberExpr(exprString, locEnd, locBegin.GetFileName(), locBegin.GetLine(), locBegin.GetColumn()); MethodDeclsCallback::currentMethod->UpdateMemberExpr(methodMemberExpr, locBegin.toString()); - /*if (!isStructureOrStructurePointerType(type)) { - if (decl->getKind() == decl->CXXMethod) { - CXXMethodDecl* methodDecl = (CXXMethodDecl*)decl; - type = methodDecl->getReturnType(); - //if (!isStructureOrStructurePointerType(type)) { - MethodDeclsCallback::currentMethod->UpdateMemberExpr(methodMemberExpr, locBegin.toString()); // to get the full expr if I have fields with not a class type - return true; - //} - } - else { - MethodDeclsCallback::currentMethod->UpdateMemberExpr(methodMemberExpr, locBegin.toString()); - return true; - } - } - - std::string typeName; - ID_T typeID; - if (type->isPointerType() || type->isReferenceType()) { - typeName = GetFullStructureName(type->getPointeeType()->getAsCXXRecordDecl()); - typeID = GetIDfromDecl(type->getPointeeType()->getAsCXXRecordDecl()); - } - else { - typeName = GetFullStructureName(type->getAsCXXRecordDecl()); - typeID = GetIDfromDecl(type->getAsCXXRecordDecl()); - } - //assert(typeID); - Structure* typeStructure = (Structure*)structuresTable.Lookup(typeID); - if (!typeStructure) - typeStructure = (Structure*)structuresTable.Install(typeID, typeName); - - Method::Member member(decl->getNameAsString(), typeStructure, locEnd, Value_mem_t); - - MethodDeclsCallback::currentMethod->InsertMemberExpr(methodMemberExpr, member, locBegin.toString());*/ - return true; } @@ -743,200 +620,246 @@ bool MethodDeclsCallback::FindMemberExprVisitor::VisitMemberExpr(MemberExpr* mem // Handle Method's Vars and Args void MethodVarsCallback::run(const MatchFinder::MatchResult& result) { if (const VarDecl* d = result.Nodes.getNodeAs(METHOD_VAR_OR_ARG)) { - auto* parentMethodDecl = d->getParentFunctionOrMethod(); + assert(d); + + const auto* parentMethodDecl = d->getParentFunctionOrMethod(); // Ignore the methods declarations - if (!parentMethodDecl || !(((CXXMethodDecl*)parentMethodDecl)->isThisDeclarationADefinition())) { + if (!parentMethodDecl || !(((CXXMethodDecl*)parentMethodDecl)->isThisDeclarationADefinition())) return; - } - if (d->isLocalVarDeclOrParm() && parentMethodDecl->getDeclKind() == d->CXXMethod) { // including params - //if(d->isFunctionOrMethodVarDecl() && parentMethod->getDeclKind() == d->CXXMethod){ // excluding params - d->isFunctionOrMethodVarDecl()-> like isLocalVarDecl() but excludes variables declared in blocks?. - auto* parentClass = (CXXRecordDecl*)parentMethodDecl->getParent(); + const auto parentMethodID = GetIDfromDecl((CXXMethodDecl*)parentMethodDecl); - if (isIgnoredDecl(parentClass)) { - return; - } + const auto defID = GetIDfromDecl(d); - auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); - if (ignored["filePaths"]->isIgnored(srcLocation.getFilename())) { - return; - } - if (ignored["namespaces"]->isIgnored(GetFullNamespaceName(parentClass))) { - return; - } - - auto parentClassName = GetFullStructureName(parentClass); - auto parentMethodName = GetFullMethodName((CXXMethodDecl*)parentMethodDecl); - auto parentClassID = GetIDfromDecl(parentClass); - auto parentMethodID = GetIDfromDecl((CXXMethodDecl*)parentMethodDecl); - //assert(parentClassID); - //assert(parentMethodID); - Structure* parentStructure = (Structure*)structuresTable.Lookup(parentClassID); - Method* parentMethod = (Method*)parentStructure->LookupMethod(parentMethodID); - //assert(parentMethod); - - // remove from TemplateInstantiationSpecialization methods the decletarions and arguments - //if (parentMethod->isTemplateInstantiationSpecialization()) { - // return; - //} + // Ignore non method declarations + if (!d->isLocalVarDeclOrParm() or parentMethodDecl->getDeclKind() != d->CXXMethod) + return; - std::string typeName; - ID_T typeID; - auto defID = GetIDfromDecl(d); - Definition* def = nullptr; + auto* parentClass = (CXXRecordDecl*)parentMethodDecl->getParent(); - if (isStructureOrStructurePointerType(d->getType())) { - if (d->getType()->isPointerType() || d->getType()->isReferenceType()) { - typeName = GetFullStructureName(d->getType()->getPointeeType()->getAsCXXRecordDecl()); - typeID = GetIDfromDecl(d->getType()->getPointeeType()->getAsCXXRecordDecl()); - } - else { - typeName = GetFullStructureName(d->getType()->getAsCXXRecordDecl()); - typeID = GetIDfromDecl(d->getType()->getAsCXXRecordDecl()); - } - //assert(typeID); - Structure* typeStructure = (Structure*)structuresTable.Lookup(typeID); - if (!typeStructure) - typeStructure = (Structure*)structuresTable.Install(typeID, typeName); - //assert(defID); - def = new Definition (defID, d->getQualifiedNameAsString(), parentMethod->GetNamespace(), typeStructure); - def->SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); - } - else { + if (isIgnoredDecl(parentClass)) { + return; + } - typeName = d->getType().getAsString(); - def = new Definition (defID, d->getQualifiedNameAsString(), parentStructure->GetNamespace()); - def->SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); - def->SetFullType(typeName); - } + const auto srcLocation = result.SourceManager->getPresumedLoc(d->getLocation()); + + if (IsFilePathIgnored(srcLocation.getFilename())) { + return; + } + if (IsNamespaceIgnored(GetFullNamespaceName(parentClass))) { + return; + } + + auto parentClassName = GetFullStructureName(parentClass); + auto parentMethodName = GetFullMethodName((CXXMethodDecl*)parentMethodDecl); + auto parentClassID = GetIDfromDecl(parentClass); + + Structure* parentStructure = (Structure*)structuresTable.Lookup(parentClassID); + Method* parentMethod = (Method*)parentStructure->LookupMethod(parentMethodID); + std::string typeName; + ID_T typeID; + Definition* def = nullptr; - - - if (d->isLocalVarDecl()) { - parentMethod->InstallDefinition(defID, *def); + if (isStructureOrStructurePointerType(d->getType())) { + if (d->getType()->isPointerType() || d->getType()->isReferenceType()) { + typeName = GetFullStructureName(d->getType()->getPointeeType()->getAsCXXRecordDecl()); + typeID = GetIDfromDecl(d->getType()->getPointeeType()->getAsCXXRecordDecl()); } else { - parentMethod->InstallArg(defID, *def); + typeName = GetFullStructureName(d->getType()->getAsCXXRecordDecl()); + typeID = GetIDfromDecl(d->getType()->getAsCXXRecordDecl()); } + Structure* typeStructure = (Structure*)structuresTable.Lookup(typeID); + if (!typeStructure) + typeStructure = (Structure*)structuresTable.Install(typeID, typeName); + def = new Definition(defID, d->getNameAsString(), parentMethod->GetNamespace(), typeStructure); + def->SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); + def->SetFullType(typeName); + } + else { + + typeName = d->getType().getAsString(); + def = new Definition(defID, d->getNameAsString(), parentStructure->GetNamespace()); + def->SetSourceInfo(srcLocation.getFilename(), srcLocation.getLine(), srcLocation.getColumn()); + def->SetFullType(typeName); + } - delete def; + if (d->isLocalVarDecl()) { + parentMethod->InstallDefinition(defID, *def); } + else { + parentMethod->InstallArg(defID, *def); + } + + delete def; } } // ---------------------------------------------------------------------------------------------- -/* - returns nullptr on fail. -*/ -std::unique_ptr dependenciesMining::LoadCompilationDatabase(const char* cmpDBPath) { - std::string errorMsg; - auto cmpDB = CompilationDatabase::autoDetectFromSource(cmpDBPath, errorMsg); - if (!cmpDB) { // Input error, exit program. - std::cerr << "In '" << cmpDBPath << "'\n"; - std::cerr << errorMsg << "\n"; - std::cerr << "Make sure Compilation Database .json is named: 'compile_commands.json'\n"; - return nullptr; - } +std::unique_ptr CreateClangTool(const char* cmpDBPath, std::string& errorMsg) { + assert(cmpDBPath); + static auto database = CompilationDatabase::autoDetectFromSource(cmpDBPath, errorMsg); + +#ifdef INCREMENTAL_GENERATION + return database ? std::make_unique(*database, DropParsedFiles(database->getAllFiles(), parsedFiles)) : nullptr; +#else + return database ? std::make_unique(*database, database->getAllFiles()) : nullptr; +#endif +} - /*auto srcs = cmpDB->getAllFiles(); - std::cout << "Files from Compilation Database:\n\n"; - for (auto file : srcs) { - std::cout << file << std::endl; - }*/ - return cmpDB; +std::unique_ptr CreateClangTool(const char* cmpDBPath) { + std::string ignoredErrorMsg; + return CreateClangTool(cmpDBPath, ignoredErrorMsg); } -// returns true only if str ends with ending -static inline bool hasEnding(std::string const& str, std::string const& ending) { - if (str.length() >= ending.length()) - return (0 == str.compare(str.length() - ending.length(), ending.length(), ending)); - return false; +std::unique_ptr CreateClangTool(const std::vector& srcs) { + static llvm::cl::OptionCategory myToolCategory("my-tool options"); + static llvm::cl::extrahelp commonHelp(CommonOptionsParser::HelpMessage); + static llvm::cl::extrahelp moreHelp("\nA help message for this specific tool can be added afterwards..\n"); + + static auto argc = 3; + const char* argv[3] = {"", "", "--"}; + static auto parser = CommonOptionsParser::create(argc, argv, myToolCategory); + +#ifdef INCREMENTAL_GENERATION + return parser ? std::make_unique(parser->getCompilations(), DropParsedFiles(srcs, parsedFiles)) : nullptr; +#else + return parser ? std::make_unique(parser->getCompilations(), srcs) : nullptr; +#endif +} + +void SetIgnoredRegions(const char* filesPath, const char* namespacesPath) { + ignored["filePaths"] = std::make_unique(filesPath); + ignored["namespaces"] = std::make_unique(namespacesPath); } -/* - Clears srcs and headers vectors. - Fills srcs and headers vectors with paths extracted from the ClangTool -*/ -void dependenciesMining::SetFiles(ClangTool* Tool, std::vector& srcs, std::vector& headers) { - srcs.clear(); - headers.clear(); +// NOTE: +// We use this anonymous namespace in order to mark source files that were bypassed in the AST due to disruptions from the GUI. +// These files must not be exported, since their contents have not been loaded into the native symbol table. +namespace { + + auto skippedFiles = std::unordered_set< std::string_view >(); + + inline void MarkFileAsSkipped(std::string_view fileName) { skippedFiles.insert(fileName); } + + inline bool WasFileSkipped(std::string_view fileName) { return skippedFiles.find(fileName) != std::cend(skippedFiles); } + +} // namespace + +// NOTE: +// Usage of a clang::tooling::SourceFileCallbacks derivative, in order to signal the parsing of source files. +namespace { + + BeginSourceSignal beginSrcSignal; + EndSourceSignal endSrcSignal; + + inline std::string_view GetCurrentFileName(const CompilerInstance& compiler) { + auto parsed = SmallVector< const FileEntry* >(); + compiler.getSourceManager().getFileManager().GetUniqueIDMapping(parsed); + assert(!parsed.empty()); + return parsed.back()->getName().data(); + } + + class SourceFileTracker : public SourceFileCallbacks { + public: + SourceFileTracker() = default; + ~SourceFileTracker() override = default; + + bool handleBeginSource(CompilerInstance& compiler) override { + const auto currentFileName = GetCurrentFileName(compiler); + + if (!IsFilePathIgnored(std::string(currentFileName))) beginSrcSignal(currentFileName); + if (IsMiningDisrupted()) MarkFileAsSkipped(currentFileName); + + return IsMiningDisrupted() ? false : true; // false breaks the AST recursion. + } + + void handleEndSource() override { endSrcSignal(); } + }; + +} // namespace + +int MineArchitecture(ClangTool& tool) { + assert(ignored.find("filePaths") != std::end(ignored) && "Make a call to SetIgnoredRegions()"); + assert(ignored.find("namespaces") != std::end(ignored) && "Make a call to SetIgnoredRegions()"); + + static DeclarationMatcher classDeclMatcher = anyOf(cxxRecordDecl(isClass()).bind(CLASS_DECL), cxxRecordDecl(isStruct()).bind(STRUCT_DECL)); + static DeclarationMatcher fieldDeclMatcher = fieldDecl().bind(FIELD_DECL); + static DeclarationMatcher methodDeclMatcher = cxxMethodDecl().bind(METHOD_DECL); + static DeclarationMatcher methodVarMatcher = varDecl().bind(METHOD_VAR_OR_ARG); + + clang::CompilerInstance comp; + comp.getPreprocessorOpts().addMacroDef("_W32BIT_"); + + ClassDeclsCallback classCallback; + FeildDeclsCallback fieldCallback; + MethodDeclsCallback methodCallback; + MethodVarsCallback methodVarCallback; + MatchFinder finder; + SourceFileTracker fileTracker; + + finder.addMatcher(classDeclMatcher, &classCallback); + finder.addMatcher(fieldDeclMatcher, &fieldCallback); + finder.addMatcher(methodDeclMatcher, &methodCallback); + finder.addMatcher(methodVarMatcher, &methodVarCallback); + +// NOTE: Need to add clang include directory as argument, else system headers won't be found, and the st will be incomplete on unix systems. +#ifdef __unix__ + static const auto clang_dir = "-I" + std::string(CLANG_INCLUDE_DIR); + + auto ardj1 = getInsertArgumentAdjuster(clang_dir.c_str()); + tool.appendArgumentsAdjuster(ardj1); +#endif + + return tool.run(newFrontendActionFactory(&finder, &fileTracker).get()); +} + +void GetMinedFiles(ClangTool& tool, std::vector& srcs, std::vector& headers) { + assert(srcs.empty()); + assert(headers.empty()); + +#ifdef INCREMENTAL_GENERATION + std::copy(std::begin(parsedFiles), std::end(parsedFiles) - 1, std::back_inserter(srcs)); // In order to include previously mined files. +#endif - std::string path; - auto& file_manager = Tool->getFiles(); SmallVector files; + auto& file_manager = tool.getFiles(); file_manager.GetUniqueIDMapping(files); - for (auto file : files) { - path = file->getName().str(); - if (ignored["filePaths"]->isIgnored(path)) + + for (auto* file : files) { + const auto path = file->getName().str(); + + if (IsFilePathIgnored(path)) continue; - if (hasEnding(path, ".h")) { + if (IsHeaderFile(path)) { headers.push_back(path); } - else if (hasEnding(path, ".cpp")) { + else if (IsSourceFile(path) && !WasFileSkipped(path)) { srcs.push_back(path); } - //else { - // std::cerr << "Unexpected code file: '" << path << "'\n"; - //} } } -/* - Clang Tool Creation -*/ -static llvm::cl::OptionCategory MyToolCategory("my-tool options"); -static llvm::cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage); -static llvm::cl::extrahelp MoreHelp("\nA help message for this specific tool can be added afterwards..\n"); - -int dependenciesMining::CreateClangTool(const char* cmpDBPath, std::vector& srcs, std::vector& headers, const char* ignoredFilePaths, const char* ignoredNamespaces) { - ClangTool* Tool; - std::unique_ptr cmpDB; - //CommonOptionsParser *OptionsParser = nullptr; - - if (cmpDBPath == nullptr) { - int argc = 3; - const char* argv[3]; - argv[0] = ""; - argv[1] = ""; - argv[2] = "--"; - - auto OptionsParser = CommonOptionsParser::create(argc, argv, MyToolCategory); - //OptionsParser = new CommonOptionsParser(argc, argv, MyToolCategory); - - Tool = new ClangTool(OptionsParser->getCompilations(), srcs); - } - else { - cmpDB = LoadCompilationDatabase(cmpDBPath); - if (!cmpDB) - return -1; - Tool = new ClangTool(*cmpDB, cmpDB->getAllFiles()); - } +// ------------------------------------ // +Connection ConnectToBeginSource(const BeginSourceSlot& f) { + return beginSrcSignal.connect(f); +} - - clang::CompilerInstance comp; - comp.getPreprocessorOpts().addMacroDef("_W32BIT_"); +Connection ConnectToEndSource(const EndSourceSlot& f) { + return endSrcSignal.connect(f); +} - initializeIgnored(ignoredFilePaths, ignoredNamespaces); +static std::atomic_bool disrupted { false }; - ClassDeclsCallback classCallback; - FeildDeclsCallback fieldCallback; - MethodDeclsCallback methodCallback; - MethodVarsCallback methodVarCallback; - MatchFinder Finder; - Finder.addMatcher(ClassDeclMatcher, &classCallback); - Finder.addMatcher(FieldDeclMatcher, &fieldCallback); - Finder.addMatcher(MethodDeclMatcher, &methodCallback); - Finder.addMatcher(MethodVarMatcher, &methodVarCallback); - int result = Tool->run(newFrontendActionFactory(&Finder).get()); - - SetFiles(Tool, srcs, headers); - - delete Tool; - return result; -} +bool IsMiningDisrupted(void) { return disrupted; } + +void DisruptMining(void) { disrupted = true; } + + +} // dependenciesMining \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.h b/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.h index ebd8a85..27f6d02 100644 --- a/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.h +++ b/GraphGenerator/DependenciesMining/ClangTool/DependenciesMining.h @@ -2,9 +2,13 @@ #pragma warning(disable : 4996) #pragma warning(disable : 4146) +#include #include +#include + #include "SymbolTable.h" -#include "../Ignored/Ignored.h"; +#include "Incremental.h" +#include "../Ignored/Ignored.h" #include "clang/Frontend/FrontendActions.h" #include "clang/Tooling/CommonOptionsParser.h" #include "clang/Tooling/Tooling.h" @@ -16,21 +20,21 @@ using namespace clang; using namespace clang::ast_matchers; using namespace llvm; using namespace clang::tooling; +using namespace incremental; namespace dependenciesMining { + using IgnoreRegistry = std::unordered_map>; + extern SymbolTable structuresTable; - extern std::unordered_map ignored; - + extern Sources parsedFiles; + extern IgnoreRegistry ignored; + // ---------------------------------------------------------------------------------- class ClassDeclsCallback : public MatchFinder::MatchCallback { public: virtual void run(const MatchFinder::MatchResult& result); - /*class FindFieldStmt : public RecursiveASTVisitor { - public: - bool TraverseAST(clang::ASTContext& ast); - };*/ }; class FeildDeclsCallback : public MatchFinder::MatchCallback { @@ -68,8 +72,30 @@ namespace dependenciesMining { // ---------------------------------------------------------------------------------- - std::unique_ptr LoadCompilationDatabase(const char*); - void SetFiles(ClangTool* tool, std::vector& srcs, std::vector& headers); - int CreateClangTool(const char* cmpDBPath, std::vector& srcs, std::vector& headers, const char* ignoredFilePaths, const char* ignoredNamespaces); + std::unique_ptr CreateClangTool(const char* cmpDBPath, std::string& errorMsg); // From a compile_commands.json, returns nullptr on error. + std::unique_ptr CreateClangTool(const char* cmpDBPath); // From a compile_commands.json, returns nullptr on error. + std::unique_ptr CreateClangTool(const std::vector& srcs); // From a collection of file paths, returns nullptr on error. + + void SetIgnoredRegions(const char* filesPath = "", const char* namespacesPath = ""); + + int MineArchitecture(ClangTool& tool); // Requires ignored regions to hav been set. + + void GetMinedFiles(ClangTool& tool, std::vector& srcs, std::vector& headers); // Ignores set ignored regions. + + // ---------------------------------------------------------------------------------- + + bool IsMiningDisrupted(void); + void DisruptMining(void); + + using BeginSourceSignal = boost::signals2::signal< void(std::string_view) >; + using EndSourceSignal = boost::signals2::signal< void() >; + + using BeginSourceSlot = BeginSourceSignal::slot_type; + using EndSourceSlot = EndSourceSignal::slot_type; + + using Connection = boost::signals2::connection; + + Connection ConnectToBeginSource(const BeginSourceSlot& f); + Connection ConnectToEndSource(const EndSourceSlot& f); -} +} // dependenciesMining diff --git a/GraphGenerator/DependenciesMining/ClangTool/Utilities/CMakeLists.txt b/GraphGenerator/DependenciesMining/ClangTool/Utilities/CMakeLists.txt new file mode 100644 index 0000000..c784045 --- /dev/null +++ b/GraphGenerator/DependenciesMining/ClangTool/Utilities/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + Utilities.cpp + Utilities.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.cpp b/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.cpp index 9a2381a..7e8c407 100644 --- a/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.cpp +++ b/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.cpp @@ -26,11 +26,10 @@ QualType dependenciesMining::GetTemplateArgType(const TemplateArgument& arg) { return arg.getAsType(); case TemplateArgument::Template: case TemplateArgument::TemplateExpansion: - //assert(0); return QualType();// arg.getAsTemplateOrTemplatePattern().getAsQualifiedTemplateName(); case TemplateArgument::Pack: // den tha mpei pote edw giati to kanw handle ekswterika - assert(0); + assert(0); return QualType(); case TemplateArgument::Integral: return arg.getIntegralType(); @@ -40,7 +39,6 @@ QualType dependenciesMining::GetTemplateArgType(const TemplateArgument& arg) { case TemplateArgument::Declaration: return arg.getParamTypeForDecl(); - //return arg.getAsDecl()->getType(); case TemplateArgument::NullPtr: return arg.getNullPtrType(); @@ -60,10 +58,10 @@ void dependenciesMining::AppendTemplateArgNameCallback(const TemplateArgument& t } auto argType = GetTemplateArgType(templateArg); if (d || argType->isStructureOrClassType()) { - if(!d) + if (!d) d = argType->getAsCXXRecordDecl(); auto qualifiedName = d->getQualifiedNameAsString(); - auto name = d->getName().str(); + auto name = d->getName().str(); if (templateArg.getKind() == TemplateArgument::Integral) { llvm::SmallVector str; templateArg.getAsIntegral().toString(str); @@ -73,10 +71,9 @@ void dependenciesMining::AppendTemplateArgNameCallback(const TemplateArgument& t } } if (d->getKind() == d->ClassTemplateSpecialization || d->getKind() == d->ClassTemplatePartialSpecialization) { - *args += qualifiedName + GetInnerTemplateArgs(d); - } + *args += qualifiedName + GetInnerTemplateArgs(d); + } else { - //*args += qualifiedName; // gia na einai idio me ta args sta methods *args += name; } } @@ -105,13 +102,13 @@ std::string dependenciesMining::GetInnerTemplateArgs(const RecordDecl* d) { } std::string dependenciesMining::GetFullStructureName(const RecordDecl* d) { - std::string name; + std::string name; if (d->getKind() == d->ClassTemplateSpecialization || d->getKind() == d->ClassTemplatePartialSpecialization) { std::string args = GetInnerTemplateArgs(d); name = (d->getQualifiedNameAsString() + args + "::" + d->getNameAsString()); } else if (d->isCXXClassMember() && ((CXXRecordDecl*)d)->getInstantiatedFromMemberClass()) { - name = d->getQualifiedNameAsString() + "::" + d->getNameAsString(); + name = d->getQualifiedNameAsString() + "::" + d->getNameAsString(); } else { name = d->getQualifiedNameAsString(); @@ -122,11 +119,11 @@ std::string dependenciesMining::GetFullStructureName(const RecordDecl* d) { std::string dependenciesMining::GetFullMethodName(const CXXMethodDecl* d) { - std::string name; + std::string name; std::string str = d->getType().getAsString(); std::size_t pos = str.find("("); std::string argList = str.substr(pos); - if (d->getTemplatedKind() == d->TK_FunctionTemplateSpecialization || d->getTemplatedKind() == d->TK_DependentFunctionTemplateSpecialization ){ + if (d->getTemplatedKind() == d->TK_FunctionTemplateSpecialization || d->getTemplatedKind() == d->TK_DependentFunctionTemplateSpecialization) { std::string templateArgs = "<"; auto args = d->getTemplateSpecializationArgs()->asArray(); for (auto it : args) { @@ -135,8 +132,8 @@ std::string dependenciesMining::GetFullMethodName(const CXXMethodDecl* d) { templateArgs += ">"; name = d->getQualifiedNameAsString() + templateArgs + argList; } - else if (d->getTemplatedKind() == d->TK_FunctionTemplate) { - auto funcTempl = d->getDescribedFunctionTemplate(); + else if (d->getTemplatedKind() == d->TK_FunctionTemplate) { + auto funcTempl = d->getDescribedFunctionTemplate(); auto params = funcTempl->getTemplateParameters()->asArray();// ->getPackAsArray(); std::string templateArgs = "<"; for (auto it : params) { @@ -150,7 +147,6 @@ std::string dependenciesMining::GetFullMethodName(const CXXMethodDecl* d) { else { name = d->getQualifiedNameAsString() + argList; } - //name.erase(std::remove_if(name.begin(), name.end(), isspace), name.end()); return name; } @@ -196,7 +192,7 @@ bool dependenciesMining::isIgnoredDecl(const RecordDecl* d) { return true; } - if(d->isCXXClassMember()) { + if (d->isCXXClassMember()) { const auto* parent = d->getParent(); if (isIgnoredDecl((RecordDecl*)parent)) { return true; diff --git a/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.h b/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.h index 7fadc35..bdcc0bc 100644 --- a/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.h +++ b/GraphGenerator/DependenciesMining/ClangTool/Utilities/Utilities.h @@ -5,6 +5,7 @@ #include "clang/ASTMatchers/ASTMatchers.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include +#include #define ID_T std::string @@ -61,5 +62,5 @@ namespace dependenciesMining { auto loc = d->getLocation().printToString(sm); std::cout << "\t" << loc << "\n\n"; } - + } \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/Ignored/CMakeLists.txt b/GraphGenerator/DependenciesMining/Ignored/CMakeLists.txt new file mode 100644 index 0000000..3b83fe6 --- /dev/null +++ b/GraphGenerator/DependenciesMining/Ignored/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + Ignored.cpp + Ignored.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/Ignored/Ignored.cpp b/GraphGenerator/DependenciesMining/Ignored/Ignored.cpp index f141629..22dc738 100644 --- a/GraphGenerator/DependenciesMining/Ignored/Ignored.cpp +++ b/GraphGenerator/DependenciesMining/Ignored/Ignored.cpp @@ -1,5 +1,6 @@ #include "Ignored.h" #include +#include using namespace dependenciesMining; diff --git a/GraphGenerator/DependenciesMining/Ignored/Ignored.h b/GraphGenerator/DependenciesMining/Ignored/Ignored.h index 3ac171f..b7de326 100644 --- a/GraphGenerator/DependenciesMining/Ignored/Ignored.h +++ b/GraphGenerator/DependenciesMining/Ignored/Ignored.h @@ -1,10 +1,13 @@ #pragma once + #include #include #include #include #include #include +#include +#include namespace dependenciesMining { diff --git a/GraphGenerator/DependenciesMining/SymbolTable/CMakeLists.txt b/GraphGenerator/DependenciesMining/SymbolTable/CMakeLists.txt new file mode 100644 index 0000000..ad7339a --- /dev/null +++ b/GraphGenerator/DependenciesMining/SymbolTable/CMakeLists.txt @@ -0,0 +1,17 @@ +set(FILES + STVisitor.h + SymbolTable.cpp + SymbolTable.h + SymbolTableTempl.cpp + SymbolTableTempl.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.cpp b/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.cpp index 912d188..8ee7bdd 100644 --- a/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.cpp +++ b/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.cpp @@ -1,10 +1,11 @@ #include "SymbolTable.h" #include "STVisitor.h" +#include using namespace dependenciesMining; // SourceInfo -std::string SourceInfo::GetFileName() const { +const std::string& SourceInfo::GetFileName() const { return fileName; } @@ -83,11 +84,11 @@ bool SourceInfo::operator==(SourceInfo const& loc) const { // Symbol -ID_T Symbol::GetID() const { +const ID_T& Symbol::GetID() const { return id; } -std::string Symbol::GetName() const { +const std::string& Symbol::GetName() const { return name; } @@ -95,11 +96,11 @@ ClassType Symbol::GetClassType() const { return classType; } -std::string Symbol::GetClassTypeAsString() const { +const char* Symbol::GetClassTypeAsString() const { if (classType == ClassType::Structure) { return "Structure"; } - else if(classType == ClassType::Method){ + else if (classType == ClassType::Method) { return "Method"; } else if (classType == ClassType::Definition) { @@ -115,7 +116,7 @@ const SourceInfo& Symbol::GetSourceInfo() const { return srcInfo; } -std::string Symbol::GetNamespace() const { +const std::string& Symbol::GetNamespace() const { return nameSpace; } @@ -164,13 +165,12 @@ void Symbol::SetAccessType(const AccessType& access_type) { this->access_type = access_type; } - // Template template Parent_T* Template::GetParent() const { return parent; } -template SymbolTable Template::GetArguments() const { +template const SymbolTable& Template::GetArguments() const { return arguments; } @@ -178,7 +178,7 @@ template void Template::SetParent(Parent_T* parent) this->parent = parent; } -template Symbol* Template::InstallArguments(const ID_T& id, Structure* structure) { +template Symbol* Template::InstallArgument(const ID_T& id, Structure* structure) { return arguments.Install(id, structure); } @@ -193,7 +193,7 @@ const Structure* Definition::GetType() const { return type; } -std::string Definition::GetFullType() const { +const std::string& Definition::GetFullType() const { return full_type; } @@ -210,7 +210,7 @@ MethodType Method::GetMethodType() const { return methodType; } -std::string Method::GetMethodTypeAsString() const { +const char* Method::GetMethodTypeAsString() const { if (methodType == MethodType::Constructor_UserDefined) { return "Constructor_UserDefined"; } @@ -242,7 +242,7 @@ std::string Method::GetMethodTypeAsString() const { return "TemplateInstantiationSpecialization"; } else { - assert(0); + assert(0); } } @@ -252,19 +252,19 @@ Structure* Method::GetReturnType() const { return returnType; } -SymbolTable Method::GetArguments() const { +const SymbolTable& Method::GetArguments() const { return arguments; } -SymbolTable Method::GetDefinitions() const { +const SymbolTable& Method::GetDefinitions() const { return definitions; } -SymbolTable Method::GetTemplateArguments() const { +const SymbolTable& Method::GetTemplateArguments() const { return templateInfo.GetArguments(); } -std::map Method::GetMemberExpr() const { +const std::map& Method::GetMemberExpr() const { return memberExprs; } @@ -332,29 +332,29 @@ void Method::SetVirtual(bool is_virtual) { this->is_virtual = is_virtual; } -void Method::InstallArg(const ID_T& id, const Definition& definition) { - arguments.Install(id, definition); +Symbol* Method::InstallArg(const ID_T& id, const Definition& definition) { + return arguments.Install(id, definition); } -void Method::InstallDefinition(const ID_T& id, const Definition& definition) { - definitions.Install(id, definition); +Symbol* Method::InstallDefinition(const ID_T& id, const Definition& definition) { + return definitions.Install(id, definition); } -void Method::InstallTemplateSpecializationArguments(const ID_T& id, Structure* structure) { - templateInfo.InstallArguments(id, structure); +Symbol* Method::InstallTemplateSpecializationArgument(const ID_T& id, Structure* structure) { + return templateInfo.InstallArgument(id, structure); } void Method::InsertMemberExpr(MemberExpr const& memberExpr, Member const& member, const std::string& locBegin) { //if (memberExpr.GetExpr() != "__$Ignore__") { - if (memberExprs.find(locBegin) == memberExprs.end()) { - memberExprs[locBegin] = memberExpr; - } - else { - if (memberExpr.GetLocEnd() > memberExprs[locBegin].GetLocEnd()) { - memberExprs[locBegin].SetExpr(memberExpr.GetExpr()); - memberExprs[locBegin].SetLocEnd(memberExpr.GetLocEnd()); - } + if (memberExprs.find(locBegin) == memberExprs.end()) { + memberExprs[locBegin] = memberExpr; + } + else { + if (memberExpr.GetLocEnd() > memberExprs[locBegin].GetLocEnd()) { + memberExprs[locBegin].SetExpr(memberExpr.GetExpr()); + memberExprs[locBegin].SetLocEnd(memberExpr.GetLocEnd()); } + } //} memberExprs[locBegin].InsertMember(member); } @@ -373,7 +373,7 @@ void Method::UpdateMemberExpr(MemberExpr const& memberExpr, const std::string& l bool Method::IsConstructor() const { if (methodType == MethodType::Constructor_UserDefined || methodType == MethodType::Constructor_Trivial) - return true; + return true; return false; } @@ -427,7 +427,7 @@ bool Method::IsVirtual() const { } // Member -std::string Method::Member::GetName() const { +const std::string& Method::Member::GetName() const { return name; } @@ -444,11 +444,11 @@ Method::Member::MemberType Method::Member::GetMemberType() const { } void Method::Member::SetName(const std::string& name) { - this->name = name; + this->name = name; } void Method::Member::SetLocEnd(const SourceInfo& locEnd) { - this->locEnd = locEnd; + this->locEnd = locEnd; } void Method::Member::SetType(Structure* type) { @@ -507,7 +507,7 @@ StructureType Structure::GetStructureType() const { return structureType; } -std::string Structure::GetStructureTypeAsString() const{ +const char* Structure::GetStructureTypeAsString() const { if (structureType == StructureType::Class) { return "Class"; } @@ -539,28 +539,28 @@ Structure* Structure::GetNestedParent() const { return nestedParent; } -SymbolTable Structure::GetMethods() const { +const SymbolTable& Structure::GetMethods() const { return methods; } -SymbolTable Structure::GetFields() const { +const SymbolTable& Structure::GetFields() const { return fields; } -SymbolTable Structure::GetBases() const { +const SymbolTable& Structure::GetBases() const { return bases; } -SymbolTable Structure::GetContains() const { +const SymbolTable& Structure::GetContains() const { return contains; } -SymbolTable Structure::GetFriends() const { +const SymbolTable& Structure::GetFriends() const { return friends; } -SymbolTable Structure::GetTemplateArguments() const { - return templateInfo.GetArguments(); +const SymbolTable& Structure::GetTemplateArguments() const { + return templateInfo.GetArguments(); } @@ -600,8 +600,8 @@ Symbol* Structure::InstallFriend(const ID_T& id, Structure* structure) { return friends.Install(id, structure); } -Symbol* Structure::InstallTemplateSpecializationArguments(const ID_T& id, Structure* structure) { - return templateInfo.InstallArguments(id, structure); +Symbol* Structure::InstallTemplateSpecializationArgument(const ID_T& id, Structure* structure) { + return templateInfo.InstallArgument(id, structure); } bool Structure::IsTemplateDefinition() const { @@ -675,6 +675,8 @@ Symbol* SymbolTable::Install(const ID_T& id, const std::string& name, const Clas } Symbol* SymbolTable::Install(const ID_T& id, const Symbol& symbol) { + std::cout << "Compiled: " << id << '\n'; + auto it = byID.find(id); if (it != byID.end()) { if (symbol.GetClassType() == ClassType::Structure && ((Structure*)(it->second))->GetStructureType() == StructureType::Undefined) { @@ -695,15 +697,17 @@ Symbol* SymbolTable::Install(const ID_T& id, const Symbol& symbol) { Symbol* SymbolTable::Install(const ID_T& id, const Structure& symbol) { + std::cout << "Compiled: " << id << '\n'; + auto it = byID.find(id); if (it != byID.end()) { - if (((Structure*)(it->second))->GetStructureType() == StructureType::Undefined) { + if (((Structure*)(it->second))->GetStructureType() == StructureType::Undefined) { (*(Structure*)(it->second)) = symbol; } else { // Ignpre it, only for debugging use return it->second; // } // - return it->second; + return it->second; } Symbol* newSymbol = new Structure(symbol); @@ -714,10 +718,29 @@ Symbol* SymbolTable::Install(const ID_T& id, const Structure& symbol) { return newSymbol; } +Symbol* SymbolTable::Install2(const ID_T& id, const Structure& symbol) { + std::cout << "Compiled: " << id << '\n'; + + const auto iter = byID.find(id); + if (iter != byID.end()) { + assert(iter->second); + return iter->second; + } + + auto* newSymbol = new Structure(symbol); + + byID[id] = newSymbol; + byName[symbol.GetName()].push_back(newSymbol); + + return newSymbol; +} + Symbol* SymbolTable::Install(const ID_T& id, const Method& symbol) { + std::cout << "Compiled: " << id << '\n'; + auto it = byID.find(id); if (it != byID.end()) { - return it->second; + return it->second; } Symbol* newSymbol = new Method(symbol); @@ -728,8 +751,10 @@ Symbol* SymbolTable::Install(const ID_T& id, const Method& symbol) { } Symbol* SymbolTable::Install(const ID_T& id, const Definition& symbol) { + std::cout << "Compiled: " << id << '\n'; + auto it = byID.find(id); - if (it != byID.end()) + if (it != byID.end()) return it->second; Symbol* newSymbol = new Definition(symbol); @@ -742,6 +767,8 @@ Symbol* SymbolTable::Install(const ID_T& id, const Definition& symbol) { } Symbol* SymbolTable::Install(const ID_T& id, Symbol* symbol) { + std::cout << "Compiled: " << id << '\n'; + auto it = byID.find(id); if (it != byID.end()) { if (symbol->GetClassType() == ClassType::Structure && ((Structure*)(it->second))->GetStructureType() == StructureType::Undefined) { @@ -753,7 +780,7 @@ Symbol* SymbolTable::Install(const ID_T& id, Symbol* symbol) { byID[id] = symbol; auto& nameList = byName[symbol->GetName()]; nameList.push_back(symbol); - + return symbol; } @@ -765,17 +792,6 @@ Symbol* SymbolTable::Lookup(const ID_T& id) { return nullptr; } - -//Symbol* SymbolTable::Lookup(const std::string& name) { -// auto it = byName.find(name); -// if (it != byName.end()) { -// //assert(it->second.size() == 1); -// return it->second.front(); -// } -// else -// return nullptr; -//} - const Symbol* SymbolTable::Lookup(const ID_T& id) const { auto it = byID.find(id); if (it != byID.end()) @@ -784,180 +800,82 @@ const Symbol* SymbolTable::Lookup(const ID_T& id) const { return nullptr; } - -//const Symbol* SymbolTable::Lookup(const std::string& name) const{ -// auto it = byName.find(name); -// if (it != byName.end()) { -// //assert(it->second.size() == 1); -// return it->second.front(); -// } -// else -// return nullptr; -//} - static Json::Value GetJsonSourceInfo(Symbol* symbol) { Json::Value json_src_info; - auto src_info = symbol->GetSourceInfo(); + const auto& src_info = symbol->GetSourceInfo(); json_src_info["file"] = src_info.GetFileName(); json_src_info["line"] = src_info.GetLine(); json_src_info["col"] = src_info.GetColumn(); return json_src_info; } -// -//void SymbolTable::Print() { -// for (auto& t : byName) { -// std::cout << "Name: " << t.first << std::endl; -// std::cout << "--------------------------------------------\n"; -// } -//} -// -//// Testing purpose. -//void SymbolTable::Print2(int level) { -// for (auto& t : byID) { -// std::cout << "level " << level << ", Name: " << t.first << std::endl; -// //std::cout << "--------------------------------------------\n"; -// if (t.second->GetClassType() == ClassType::Structure) { -// Structure* structure = (Structure*)t.second; -// structure->GetMethods().Print2(level + 1); -// structure->GetFields().Print2(level + 1); -// structure->GetBases().Print2(level + 1); -// structure->GetContains().Print2(level + 1); -// structure->GetFriends().Print2(level + 1); -// } -// else if (t.second->GetClassType() == ClassType::Method) { -// Method* method = (Method*)t.second; -// std::cout << "args: ---------\n"; -// method->GetArguments().Print2(level + 1); -// std::cout << "end : ---------\n"; -// method->GetDefinitions().Print2(level + 1); -// method->GetTemplateArguments().Print2(level + 1); -// const auto& member_expr = method->GetMemberExpr(); -// for (auto& i : member_expr) { -// std::cout << "Member EXPR: " << i.first << std::endl; -// for (auto& it : i.second.GetMembers()) { -// std::cout << "Member: " << it.GetName() << std::endl; -// } -// } -// -// } -// } -//} -// -//Json::Value SymbolTable::GetJsonStructure(dependenciesMining::Structure* structure) { -// Json::Value json_structure; -// -// -// json_structure["methods"] = structure->GetMethods().GetJsonSymbolTable(); -// json_structure["fields"] = structure->GetFields().GetJsonSymbolTable(); -// json_structure["bases"] = structure->GetBases().GetJsonSymbolTable(); -// json_structure["contains"] = structure->GetContains().GetJsonSymbolTable(); -// json_structure["friends"] = structure->GetFriends().GetJsonSymbolTable(); -// json_structure["src_info"] = GetJsonSourceInfo(structure); -// -// return json_structure; -//} -// -//Json::Value SymbolTable::GetJsonMethod(dependenciesMining::Method* method) { -// Json::Value json_method; -// -// /*auto iss = method->GetMemberExpr(); -// std::cout << iss.size() << std::endl; -// for (auto is : iss) { -// std::cout << is.first << std::endl; -// }*/ -// auto* ret_type = method->GetReturnType(); -//#pragma warning ("FIX ME!!!!") -// if (!ret_type) -// json_method["ret_type"] = "void"; -// else -// json_method["ret_type"] = ret_type->GetID(); -// json_method["args"] = method->GetArguments().GetJsonSymbolTable(); -// json_method["definitions"] = method->GetDefinitions().GetJsonSymbolTable(); -// json_method["template_args"] = method->GetTemplateArguments().GetJsonSymbolTable(); -// json_method["literals"] = method->GetLiterals(); -// json_method["statements"] = method->GetStatements(); -// json_method["branches"] = method->GetBranches(); -// json_method["loops"] = method->GetLoops(); -// json_method["src_info"] = GetJsonSourceInfo(method); -// json_method["max_scope"] = method->GetMaxScopeDepth(); -// json_method["lines"] = method->GetLineCount(); -// json_method["access"] = method->GetAccessTypeStr(); -// -//#pragma warning(">>>>>>>>>>>>>> GetMemberExpr() <<<<<<<<<<<<<<<<<") -// return json_method; -//} -// -//Json::Value SymbolTable::GetJsonDefinition(dependenciesMining::Definition* definition) { -// Json::Value json_definition; -// if (definition->isStructure()) -// json_definition["type"] = definition->GetType()->GetID(); -// else // is fundamental -// json_definition["type"] = definition->GetFundamental(); -// -// return json_definition; -//} -// -//Json::Value SymbolTable::GetJsonSymbolTable(void) { -// Json::Value vec(Json::arrayValue); -// -// for (auto& t : byID) { -// Json::Value new_obj; -// -// if (t.second->GetClassType() == ClassType::Structure) { -// new_obj = GetJsonStructure((dependenciesMining::Structure*)t.second); -// } -// else if (t.second->GetClassType() == ClassType::Definition) { -// new_obj = GetJsonDefinition((dependenciesMining::Definition*)t.second); -// } -// else if (t.second->GetClassType() == ClassType::Method) { -// new_obj = GetJsonMethod(((dependenciesMining::Method*)t.second)); -// } -// else if (t.second->GetClassType() == ClassType::Undefined) { -// // new_obj = ... -// } -// else -// assert(0); -// new_obj["id"] = t.second->GetID(); -// vec.append(new_obj); -// } -// -// return vec; -//} - -void SymbolTable::AddJsonStructure(dependenciesMining::Structure* structure, Json::Value &json_structure) { - //Json::Value json_structure; +namespace { + + inline void Put(Json::Value& val, const char* key) { + val[key]; + } + +} // namespace + + +void SymbolTable::AddJsonStructure(dependenciesMining::Structure* structure, Json::Value& json_structure) const { + assert(structure); structure->GetMethods().AddJsonSymbolTable(json_structure["methods"]); structure->GetFields().AddJsonSymbolTable(json_structure["fields"]); - const auto bases = structure->GetBases(); - for (const auto& base : bases) { - json_structure["bases"].append(base.second->GetID()); - } - //structure->GetBases().AddJsonSymbolTable(json_structure["bases"]); // FIXME need only id - structure->GetContains().AddJsonSymbolTable(json_structure["contains"]); - structure->GetFriends().AddJsonSymbolTable(json_structure["friends"]); + + Put(json_structure, "bases"); + for (const auto& [id, base] : structure->GetBases()) + json_structure["bases"].append(id); + + Put(json_structure, "contains"); + for (const auto& [id, nested] : structure->GetContains()) + json_structure["contains"].append(id); + + + Put(json_structure, "friends"); + for (const auto& [id, buddy] : structure->GetFriends()) + json_structure["friends"].append(id); + json_structure["src_info"] = GetJsonSourceInfo(structure); -} -void SymbolTable::AddJsonMethod(dependenciesMining::Method* method, Json::Value &json_method) { - //Json::Value json_method; + json_structure["namespace"] = structure->GetNamespace(); + json_structure["structure_type"] = structure->GetStructureTypeAsString(); + + Put(json_structure, "template_parent"); + if (structure->GetTemplateParent()) + json_structure["template_parent"] = structure->GetTemplateParent()->GetID(); - /*auto iss = method->GetMemberExpr(); - std::cout << iss.size() << std::endl; - for (auto is : iss) { - std::cout << is.first << std::endl; - }*/ + Put(json_structure, "nested_parent"); + if (structure->GetNestedParent()) + json_structure["nested_parent"] = structure->GetNestedParent()->GetID(); + + Put(json_structure, "template_args"); + for (const auto& [id, arg] : structure->GetTemplateArguments()) + json_structure["template_args"].append(id); + + json_structure["name"] = structure->GetName(); +} + +void SymbolTable::AddJsonMethod(dependenciesMining::Method* method, Json::Value& json_method) const { + assert(method); auto* ret_type = method->GetReturnType(); #pragma warning ("FIX ME!!!!") if (!ret_type) json_method["ret_type"] = "void"; else json_method["ret_type"] = ret_type->GetID(); + + + method->GetArguments().AddJsonSymbolTable(json_method["args"]); method->GetDefinitions().AddJsonSymbolTable(json_method["definitions"]); - method->GetTemplateArguments().AddJsonSymbolTable(json_method["template_args"]); + + Put(json_method, "template_args"); + for (const auto& [id, arg] : method->GetTemplateArguments()) + json_method["template_args"].append(id); + json_method["literals"] = method->GetLiterals(); json_method["statements"] = method->GetStatements(); json_method["branches"] = method->GetBranches(); @@ -968,17 +886,31 @@ void SymbolTable::AddJsonMethod(dependenciesMining::Method* method, Json::Value json_method["access"] = method->GetAccessTypeStr(); json_method["virtual"] = method->IsVirtual(); + json_method["method_type"] = method->GetMethodTypeAsString(); + + json_method["name"] = method->GetName(); + #pragma warning(">>>>>>>>>>>>>> GetMemberExpr() <<<<<<<<<<<<<<<<<") } -void SymbolTable::AddJsonDefinition(dependenciesMining::Definition* definition, Json::Value& json_definition) { - json_definition["type"] = definition->GetFullType(); +void SymbolTable::AddJsonDefinition(dependenciesMining::Definition* definition, Json::Value& json_definition) const { + assert(definition); + + json_definition["full_type"] = definition->GetFullType(); + + Put(json_definition, "type"); + if (definition->GetType()) + json_definition["type"] = definition->GetType()->GetID(); + + json_definition["src_info"] = GetJsonSourceInfo(definition); if (definition->GetAccessType() != AccessType::unknown) json_definition["access"] = definition->GetAccessTypeStr(); + + json_definition["name"] = definition->GetName(); } -void SymbolTable::AddJsonSymbolTable(Json::Value& st) { +void SymbolTable::AddJsonSymbolTable(Json::Value& st) const { for (auto& t : byID) { Json::Value new_obj; @@ -987,13 +919,13 @@ void SymbolTable::AddJsonSymbolTable(Json::Value& st) { continue; if (t.second->GetClassType() == ClassType::Structure) { - AddJsonStructure((dependenciesMining::Structure*)t.second, new_obj); + AddJsonStructure((dependenciesMining::Structure*)t.second, new_obj); } else if (t.second->GetClassType() == ClassType::Definition) { - AddJsonDefinition((dependenciesMining::Definition*)t.second, new_obj); + AddJsonDefinition((dependenciesMining::Definition*)t.second, new_obj); } else if (t.second->GetClassType() == ClassType::Method) { - AddJsonMethod((dependenciesMining::Method*)t.second, new_obj); + AddJsonMethod((dependenciesMining::Method*)t.second, new_obj); } else if (t.second->GetClassType() == ClassType::Undefined) { // new_obj = ... @@ -1024,7 +956,6 @@ void SymbolTable::Accept(STVisitor* visitor) { } } - void SymbolTable::Accept(STVisitor* visitor) const { for (auto it : byID) { auto* symbol = it.second; @@ -1041,4 +972,4 @@ void SymbolTable::Accept(STVisitor* visitor) const { assert(0); } } -} +} \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.h b/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.h index 0297892..6d2a335 100644 --- a/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.h +++ b/GraphGenerator/DependenciesMining/SymbolTable/SymbolTable.h @@ -3,8 +3,10 @@ #include #include #include +#include #include -#include +#include +#include #include "json/writer.h" #define ID_T std::string @@ -27,7 +29,6 @@ namespace dependenciesMining { TemplatePartialSpecialization }; - enum class MethodType { Undefined = -1, Constructor_Trivial, @@ -65,7 +66,7 @@ namespace dependenciesMining { public: SourceInfo() = default; SourceInfo(const std::string& fileName, int line, int column) : fileName(fileName), line(line), column(column) {}; - std::string GetFileName() const; + const std::string& GetFileName() const; int GetLine() const; int GetColumn() const; std::string toString() const; @@ -81,6 +82,10 @@ namespace dependenciesMining { bool operator==(SourceInfo const& loc) const; }; + inline bool operator!=(const SourceInfo& lhs, const SourceInfo& rhs) { + return !(lhs == rhs); + } + // ---------------------------------------------------------------------------------------- class Symbol { @@ -96,14 +101,16 @@ namespace dependenciesMining { Symbol() = default; Symbol(ClassType classType) : classType(classType) {}; Symbol(const ID_T& id, const std::string& name, const std::string& nameSpace = "", ClassType classType = ClassType::Undefined, const std::string& fileName = "", int line = -1, int column = -1) - : id(id), name(name), nameSpace(nameSpace), classType(classType), srcInfo(SourceInfo(fileName, line, column)) {}; + : id(id), name(name), nameSpace(nameSpace), classType(classType), srcInfo(fileName, line, column) {}; + + virtual ~Symbol() = default; - virtual ID_T GetID() const; - virtual std::string GetName() const; + virtual const ID_T& GetID() const; + virtual const std::string& GetName() const; virtual ClassType GetClassType() const; - virtual std::string GetClassTypeAsString() const; + virtual const char* GetClassTypeAsString() const; virtual const SourceInfo& GetSourceInfo() const; - virtual std::string GetNamespace() const; + virtual const std::string& GetNamespace() const; const char* GetAccessTypeStr() const; AccessType GetAccessType() const; @@ -114,7 +121,6 @@ namespace dependenciesMining { virtual void SetSourceInfo(const std::string& fileName, int line, int column); virtual void SetNamespace(const std::string& nameSpace); void SetAccessType(const AccessType& access_type); - }; // ---------------------------------------------------------------------------------------- @@ -124,12 +130,20 @@ namespace dependenciesMining { std::unordered_map byID; std::unordered_map> byName; public: + using Size = std::unordered_map::size_type; + + bool IsEmpty() const { return byID.empty(); } + Size GetSize() const { return byID.size(); } + Symbol* Install(const ID_T& id, const std::string& name, const ClassType& type = ClassType::Structure); // TO FIX Symbol* Install(const ID_T& id, const Symbol& symbol); Symbol* Install(const ID_T& id, const Structure& symbol); Symbol* Install(const ID_T& id, const Method& symbol); Symbol* Install(const ID_T& id, const Definition& symbol); Symbol* Install(const ID_T& id, Symbol* symbol); + + Symbol* Install2(const ID_T& id, const Structure& symbol); // cause of Install implementation, didnt want to break anything + Symbol* Lookup(const ID_T& id); //Symbol* Lookup(const std::string& name); const Symbol* Lookup(const ID_T& id) const; @@ -137,14 +151,18 @@ namespace dependenciesMining { void Print(); void Print2(int level); - Json::Value GetJsonStructure(dependenciesMining::Structure* structure); - Json::Value GetJsonMethod(dependenciesMining::Method* method); - Json::Value GetJsonDefinition(dependenciesMining::Definition* definition); - void AddJsonStructure(dependenciesMining::Structure* structure, Json::Value& json_structure); - void AddJsonMethod(dependenciesMining::Method* method, Json::Value& json_method); - void AddJsonDefinition(dependenciesMining::Definition* definition, Json::Value& json_definition); - void AddJsonSymbolTable(Json::Value& st); + + Json::Value GetJsonStructure(Structure* structure); + Json::Value GetJsonMethod(Method* method); + Json::Value GetJsonDefinition(Definition* definition); + + void AddJsonStructure(Structure* structure, Json::Value& json_structure) const; + void AddJsonMethod(Method* method, Json::Value& json_method) const; + void AddJsonDefinition(Definition* definition, Json::Value& json_definition) const; + void AddJsonSymbolTable(Json::Value& st) const; + Json::Value GetJsonSymbolTable(void); + void Accept(STVisitor* visitor); void Accept(STVisitor* visitor) const; @@ -158,7 +176,6 @@ namespace dependenciesMining { iterator end() { return byID.end(); } const_iterator end() const { return byID.end(); } - }; // ---------------------------------------------------------------------------------------- @@ -172,17 +189,17 @@ namespace dependenciesMining { Template() = default; Parent_T* GetParent() const; - SymbolTable GetArguments() const; + const SymbolTable& GetArguments() const; void SetParent(Parent_T* structure); - Symbol* InstallArguments(const ID_T& id, Structure* structure); + Symbol* InstallArgument(const ID_T& id, Structure* structure); }; // ---------------------------------------------------------------------------------------- class Definition : public Symbol { private: - Structure* type = nullptr; - std::string full_type = ""; + Structure* type = nullptr; // Definition type, can be nullptr in case of non-user-defined types. + std::string full_type = ""; // Full definition type. public: Definition() : Symbol(ClassType::Definition) {}; @@ -191,9 +208,11 @@ namespace dependenciesMining { Definition(const ID_T& id, const std::string& name, const std::string& nameSpace, Structure* type, const std::string& fileName, int line, int column) : Symbol(id, name, nameSpace, ClassType::Definition, fileName, line, column), type(type) {}; + virtual ~Definition() override = default; + bool isStructure() const; const Structure* GetType() const; - std::string GetFullType() const; + const std::string& GetFullType() const; void SetType(Structure* structure); void SetFullType(const std::string& type); }; @@ -217,7 +236,7 @@ namespace dependenciesMining { public: Member() = default; Member(const std::string& name, Structure* type, SourceInfo locEnd, MemberType memType = Value_mem_t) : name(name), type(type), locEnd(locEnd), memType(memType) {}; - std::string GetName() const; + const std::string& GetName() const; SourceInfo GetLocEnd() const; Structure* GetType() const; MemberType GetMemberType() const; @@ -258,20 +277,23 @@ namespace dependenciesMining { int max_scope_depth = 0; int line_count = 0; bool is_virtual; + public: Method() : Symbol(ClassType::Method) {}; Method(const ID_T& id, const std::string& name, const std::string& nameSpace = "") : Symbol(id, name, nameSpace, ClassType::Method) {}; Method(const ID_T& id, const std::string& name, const std::string& nameSpace, const std::string& fileName, int line, int column) : Symbol(id, name, nameSpace, ClassType::Method, fileName, line, column) {}; + virtual ~Method() override = default; + MethodType GetMethodType() const; - std::string GetMethodTypeAsString() const; + const char* GetMethodTypeAsString() const; Structure* GetReturnType() const; - SymbolTable GetArguments() const; - SymbolTable GetDefinitions() const; - SymbolTable GetTemplateArguments() const; - std::map GetMemberExpr() const; + const SymbolTable& GetArguments() const; + const SymbolTable& GetDefinitions() const; + const SymbolTable& GetTemplateArguments() const; + const std::map& GetMemberExpr() const; int GetLiterals() const; int GetStatements() const; int GetBranches() const; @@ -290,9 +312,9 @@ namespace dependenciesMining { void SetLineCount(int line_count); void SetVirtual(bool is_virtual); - void InstallArg(const ID_T& id, const Definition& definition); - void InstallDefinition(const ID_T& id, const Definition& definition); - void InstallTemplateSpecializationArguments(const ID_T& id, Structure* structure); + Symbol* InstallArg(const ID_T& id, const Definition& definition); + Symbol* InstallDefinition(const ID_T& id, const Definition& definition); + Symbol* InstallTemplateSpecializationArgument(const ID_T& id, Structure* structure); void InsertMemberExpr(MemberExpr const& memberExpr, Member const& member, const std::string& locBegin); void UpdateMemberExpr(MemberExpr const& memberExpr, const std::string& locBegin); @@ -322,25 +344,29 @@ namespace dependenciesMining { SymbolTable contains; SymbolTable friends; // About Structures: Key->structureID, Value->Structure* // About Methods: Key->methodID, Value->Structure* (the parent Class which owns this method) + public: Structure() : Symbol(ClassType::Structure) {}; + Structure(const ID_T& id) : Symbol{id, id, "", ClassType::Structure} {} Structure(const ID_T& id, const std::string& name, const std::string& nameSpace = "", StructureType structureType = StructureType::Undefined) : Symbol(id, name, nameSpace, ClassType::Structure), structureType(structureType) {}; Structure(const ID_T& id, const std::string& name, const std::string& nameSpace, StructureType structureType, const std::string& fileName, int line, int column) : Symbol(id, name, nameSpace, ClassType::Structure, fileName, line, column), structureType(structureType) {}; Structure(const Structure& s); + + virtual ~Structure() override = default; StructureType GetStructureType() const; - std::string GetStructureTypeAsString() const; + const char* GetStructureTypeAsString() const; Structure* GetTemplateParent() const; Structure* GetNestedParent() const; - SymbolTable GetMethods() const; - SymbolTable GetFields() const; - SymbolTable GetBases() const; - SymbolTable GetContains() const; - SymbolTable GetFriends() const; - SymbolTable GetTemplateArguments() const; + const SymbolTable& GetMethods() const; + const SymbolTable& GetFields() const; + const SymbolTable& GetBases() const; + const SymbolTable& GetContains() const; + const SymbolTable& GetFriends() const; + const SymbolTable& GetTemplateArguments() const; void SetStructureType(const StructureType& structureType); void SetTemplateParent(Structure* structure); @@ -353,7 +379,7 @@ namespace dependenciesMining { Symbol* InstallBase(const ID_T& id, Structure* structure); Symbol* InstallNestedClass(const ID_T& id, Structure* structure); Symbol* InstallFriend(const ID_T& id, Structure* structure); - Symbol* InstallTemplateSpecializationArguments(const ID_T& id, Structure* structure); + Symbol* InstallTemplateSpecializationArgument(const ID_T& id, Structure* structure); bool IsTemplateDefinition() const; bool IsTemplateFullSpecialization() const; @@ -367,4 +393,5 @@ namespace dependenciesMining { /*class Fundamental : public Symbol { };*/ + } \ No newline at end of file diff --git a/GraphGenerator/DependenciesMining/SymbolTable/SymbolTableTempl.h b/GraphGenerator/DependenciesMining/SymbolTable/SymbolTableTempl.h index 1b48622..f4a6933 100644 --- a/GraphGenerator/DependenciesMining/SymbolTable/SymbolTableTempl.h +++ b/GraphGenerator/DependenciesMining/SymbolTable/SymbolTableTempl.h @@ -3,7 +3,8 @@ #include #include #include -#include +#include +#include #include #define ID_T int64_t diff --git a/GraphGenerator/FileSystem/CMakeLists.txt b/GraphGenerator/FileSystem/CMakeLists.txt new file mode 100644 index 0000000..2785712 --- /dev/null +++ b/GraphGenerator/FileSystem/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + FileSystem.cpp + FileSystem.h +) +set(SUBDIRECTORIES) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/FileSystem/FileSystem.cpp b/GraphGenerator/FileSystem/FileSystem.cpp new file mode 100644 index 0000000..229813c --- /dev/null +++ b/GraphGenerator/FileSystem/FileSystem.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include "FileSystem.h" + +namespace filesystem { + + namespace { + + // returns true only if str ends with ending + inline bool EndsWith(std::string const& str, std::string const& ending) { // TODO Optimize + if (str.length() >= ending.length()) + return (0 == str.compare(str.length() - ending.length(), ending.length(), ending)); + return false; + } + + } // namespace + + bool IsHeaderFile(const std::string& fileName) { // TODO Optimize + return EndsWith(fileName, ".h") or EndsWith(fileName, ".hpp"); // TODO More + } + + bool IsSourceFile(const std::string& fileName) { // TODO Optimize + return EndsWith(fileName, ".cpp") or EndsWith(fileName, ".cc"); // TODO More + } + +} // filesystem \ No newline at end of file diff --git a/GraphGenerator/FileSystem/FileSystem.h b/GraphGenerator/FileSystem/FileSystem.h new file mode 100644 index 0000000..51f7aed --- /dev/null +++ b/GraphGenerator/FileSystem/FileSystem.h @@ -0,0 +1,8 @@ +#include + +namespace filesystem { + + bool IsHeaderFile(const std::string& fileName); + bool IsSourceFile(const std::string& fileName); + +} // filesystem \ No newline at end of file diff --git a/GraphGenerator/Graph/CMakeLists.txt b/GraphGenerator/Graph/CMakeLists.txt new file mode 100644 index 0000000..d2fff70 --- /dev/null +++ b/GraphGenerator/Graph/CMakeLists.txt @@ -0,0 +1,15 @@ +set(FILES + Graph.cpp + Graph.h + GraphVisitor.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/GraphGeneration/CMakeLists.txt b/GraphGenerator/GraphGeneration/CMakeLists.txt new file mode 100644 index 0000000..f1a677b --- /dev/null +++ b/GraphGenerator/GraphGeneration/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + GraphGeneration.cpp + GraphGeneration.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/GraphGeneration/GraphGeneration.cpp b/GraphGenerator/GraphGeneration/GraphGeneration.cpp index 3a03a74..3f384cd 100644 --- a/GraphGenerator/GraphGeneration/GraphGeneration.cpp +++ b/GraphGenerator/GraphGeneration/GraphGeneration.cpp @@ -1,16 +1,20 @@ #include "GraphGeneration.h" +#include -using namespace dependenciesMining; +using namespace dependenciesMining; using namespace graph; using namespace graphGeneration; +// FIXME Dependencies cardinalities + // GraphGenerationSTVisitor void GraphGenerationSTVisitor::VisitStructure(Structure* s) { - + assert(s); + if (s->IsUndefined()) return; - + if (graph.GetNode(s->GetID())) { if (currNode && currNode->GetID() != s->GetID()) { // Ignore the self dependencies assert(currDepType != Undefined_dep_t); @@ -18,7 +22,7 @@ void GraphGenerationSTVisitor::VisitStructure(Structure* s) { } return; } - + Node* oldCurrNode = currNode; Edge::DependencyType oldCurrDepType = currDepType; currNode = new Node(); @@ -95,12 +99,12 @@ void GraphGenerationSTVisitor::VisitStructure(Structure* s) { } } nodeData.Set("templateArguments", templArgsObj); - + untyped::Object fieldsObj; currDepType = ClassField_dep_t; for (auto& it : s->GetFields()) { auto* field = it.second; - if(((Definition*)field)->isStructure()){ + if (((Definition*)field)->isStructure()) { if (!((Definition*)field)->GetType()->IsUndefined()) { VisitDefinition(static_cast(field)); fieldsObj.Set(it.first, innerObj); @@ -130,6 +134,8 @@ void GraphGenerationSTVisitor::VisitStructure(Structure* s) { void GraphGenerationSTVisitor::VisitMethod(Method* s) { + assert(s); + Edge::DependencyType oldCurrDepType = currDepType; untyped::Object data; @@ -156,7 +162,7 @@ void GraphGenerationSTVisitor::VisitMethod(Method* s) { data.Set("returnType", returnType->GetID()); } } - + untyped::Object argsObj; currDepType = MethodArg_dep_t; for (auto& it : s->GetArguments()) { @@ -196,7 +202,7 @@ void GraphGenerationSTVisitor::VisitMethod(Method* s) { data.Set("templateArguments", templArgsObj); // memberexpr - untyped::Object memberExprsObj; + untyped::Object memberExprsObj; currDepType = MemberExpr_dep_t; for (auto it : s->GetMemberExpr()) { auto expr = it.second; @@ -231,17 +237,10 @@ void GraphGenerationSTVisitor::VisitMethod(Method* s) { locEnd.Set("column", (double)member.GetLocEnd().GetColumn()); memberObj.Set("locEnd", locEnd); - /*if (member.GetMemberType() == Value_mem_t) - currDepType = MemberExpr_Value_dep_t; - else if (member.GetMemberType() == ClassField_mem_t) - currDepType = MemberExpr_ClassField_dep_t; - else - currDepType = MemberExpr_MethodDefinition_dep_t;*/ - VisitStructure(static_cast(memberType)); membersObj.Set(index2++, memberObj); } - memberExprObj.Set("members", membersObj); + memberExprObj.Set("members", membersObj); } memberExprsObj.Set(it.first, memberExprObj); @@ -256,9 +255,13 @@ void GraphGenerationSTVisitor::VisitMethod(Method* s) { void GraphGenerationSTVisitor::VisitDefinition(Definition* s) { + assert(s); + Edge::DependencyType oldCurrDepType = currDepType; - + Structure* typeStruct = (Structure*)s->GetType(); + assert(typeStruct); + if (typeStruct->IsUndefined()) assert(0); @@ -294,7 +297,7 @@ Graph& GraphGenerationSTVisitor::GetGraph() { } -Graph graphGeneration::GenetareDependenciesGraph(const SymbolTable& st) { +Graph graphGeneration::GenerateDependenciesGraph(const SymbolTable& st) { GraphGenerationSTVisitor visitor; st.Accept(&visitor); return visitor.GetGraph(); diff --git a/GraphGenerator/GraphGeneration/GraphGeneration.h b/GraphGenerator/GraphGeneration/GraphGeneration.h index 1a8605d..461ccbf 100644 --- a/GraphGenerator/GraphGeneration/GraphGeneration.h +++ b/GraphGenerator/GraphGeneration/GraphGeneration.h @@ -36,5 +36,5 @@ namespace graphGeneration { Graph& GetGraph(); }; - Graph GenetareDependenciesGraph(const SymbolTable& st); + Graph GenerateDependenciesGraph(const SymbolTable& st); } \ No newline at end of file diff --git a/GraphGenerator/GraphToJson/CMakeLists.txt b/GraphGenerator/GraphToJson/CMakeLists.txt new file mode 100644 index 0000000..b943367 --- /dev/null +++ b/GraphGenerator/GraphToJson/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + GraphToJson.cpp + GraphToJson.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/Gui/CMakeLists.txt b/GraphGenerator/Gui/CMakeLists.txt new file mode 100644 index 0000000..1964f9a --- /dev/null +++ b/GraphGenerator/Gui/CMakeLists.txt @@ -0,0 +1,16 @@ +set(FILES + Gui.cpp + Gui.h + GuiController.cpp + GuiController.h +) +set(SUBDIRECTORIES) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/Gui/Gui.cpp b/GraphGenerator/Gui/Gui.cpp new file mode 100644 index 0000000..9c43f05 --- /dev/null +++ b/GraphGenerator/Gui/Gui.cpp @@ -0,0 +1,39 @@ +#include "Gui.h" + +namespace gui { + + bool Gui::OnInit(void) { + m_frame = std::make_unique< wxFrame >(nullptr, wxID_ANY, wxT("")); + GetFrame()->Show(false); + SetTopWindow(GetFrame()); + + m_dialog = std::make_unique< wxProgressDialog >( + GetTitle(), + GetCaption(), + 100, + GetFrame(), + wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT | + wxPD_ELAPSED_TIME | wxPD_ESTIMATED_TIME | wxPD_REMAINING_TIME | + wxPD_SMOOTH + ); + m_dialog->SetWindowStyleFlag(wxRESIZE_BORDER); + + assert(GetFrame()); + assert(GetDialog()); + return true; + } + + int Gui::OnExit(void) { + m_dialog.reset(); + m_frame.reset(); + return 0; + } + + void Gui::Render(void) { + assert(GetDialog()); + + if (GetDialog()->WasCancelled()) EmitCancel(); + GetDialog()->Update(GetProgress(), GetCaption()); + } + +} \ No newline at end of file diff --git a/GraphGenerator/Gui/Gui.h b/GraphGenerator/Gui/Gui.h new file mode 100644 index 0000000..4d52e53 --- /dev/null +++ b/GraphGenerator/Gui/Gui.h @@ -0,0 +1,57 @@ +#pragma once + +#include +#include +#include +#include +#include + +namespace gui { + + class Gui : public wxApp { + private: + using CancelSignal = boost::signals2::signal< void() >; + + public: + using CancelSlot = CancelSignal::slot_type; + using Connection = boost::signals2::connection; + + public: + Gui() = default; + virtual ~Gui() override = default; + + unsigned GetProgress(void) const { return m_progress; } + void SetProgress(unsigned curr) { m_progress = curr; } + + const std::string& GetCaption(void) const { return m_caption; } + void SetCaption(std::string caption) { m_caption = std::move(caption); } + + const std::string& GetTitle(void) const { return m_title; } + void SetTitle(std::string title) { m_title = std::move(title); } + + bool OnInit(void) override; + int OnExit(void) override; + + void Render(void); + + Connection ConnectToCancel(const CancelSlot& f) { return m_cancel_signal.connect(f); } + + protected: + wxProgressDialog* GetDialog() const { return m_dialog.get(); } + wxFrame* GetFrame() const { return m_frame.get(); } + + void EmitCancel(void) const { m_cancel_signal(); } + + private: + unsigned m_progress { 0 }; + std::string m_caption { "Parsed files: " }; + std::string m_title { "Mining..." }; + std::unique_ptr< wxProgressDialog > m_dialog; + std::unique_ptr< wxFrame > m_frame; + + CancelSignal m_cancel_signal; + }; + +} + +DECLARE_APP(gui::Gui); diff --git a/GraphGenerator/Gui/GuiController.cpp b/GraphGenerator/Gui/GuiController.cpp new file mode 100644 index 0000000..a3abc4b --- /dev/null +++ b/GraphGenerator/Gui/GuiController.cpp @@ -0,0 +1,45 @@ +#include "GuiController.h" +#include "Gui.h" +#include + +IMPLEMENT_APP_NO_MAIN(gui::Gui); + +namespace gui { + + GuiController& GuiController::GetSingleton() { + static auto singleton = GuiController(); + return singleton; + } + + const Gui& GuiController::GetGui(void) const { + return wxGetApp(); + } + + Gui& GuiController::GetGui(void) { + return wxGetApp(); + } + + void GuiController::AdvanceGuiProgress(unsigned units) { + SetUnitsDone(GetUnitsDone() + units); + const auto percentageDone = (GetUnitsDone() * 100) / GetTotalUnits(); + GetGui().SetProgress(percentageDone); + } + + void GuiController::UpdateGuiCaption(std::string_view currFileName) { + auto&& caption = std::string(currFileName) + '\t' + std::to_string(GetUnitsDone()) + "/" + std::to_string(GetTotalUnits()); + GetGui().SetCaption(std::move(caption)); + } + + void GuiController::AdvanceAndUpdateGui(std::string_view currFileName, unsigned units) { + AdvanceGuiProgress(units); + UpdateGuiCaption(currFileName); + } + + void GuiController::SetUnitsDone(unsigned units) { + assert(GetTotalUnits() >= GetUnitsDone()); + assert(units <= GetTotalUnits()); + m_units_done = units; + assert(GetTotalUnits() >= GetUnitsDone()); + } + +} \ No newline at end of file diff --git a/GraphGenerator/Gui/GuiController.h b/GraphGenerator/Gui/GuiController.h new file mode 100644 index 0000000..8ac6789 --- /dev/null +++ b/GraphGenerator/Gui/GuiController.h @@ -0,0 +1,43 @@ +#pragma once + +#include +#include + +namespace gui { + + class Gui; + + class GuiController final { + public: + GuiController(const GuiController&) = delete; + GuiController(GuiController&&) = delete; + + GuiController& operator=(const GuiController&) = delete; + GuiController& operator=(GuiController&&) = delete; + + static GuiController& GetSingleton(); + + unsigned GetTotalUnits(void) const { return m_total_units; } + void SetTotalUnits(unsigned units) { m_total_units = units; } + + unsigned GetUnitsDone(void) const { return m_units_done; } + + const Gui& GetGui(void) const; + Gui& GetGui(void); + + bool IsGuiProgressDone(void) const { return GetTotalUnits() == GetUnitsDone(); } + void AdvanceGuiProgress(unsigned units = 1); + void UpdateGuiCaption(std::string_view currFileName); + void AdvanceAndUpdateGui(std::string_view currFileName, unsigned units = 1); + + private: + GuiController() = default; + ~GuiController() = default; + + void SetUnitsDone(unsigned units); + + unsigned m_total_units { 0 }; + unsigned m_units_done { 0 }; + }; + +} \ No newline at end of file diff --git a/GraphGenerator/Incremental/CMakeLists.txt b/GraphGenerator/Incremental/CMakeLists.txt new file mode 100644 index 0000000..1caeac2 --- /dev/null +++ b/GraphGenerator/Incremental/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + Incremental.cpp + Incremental.h +) +set(SUBDIRECTORIES Details) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/Incremental/Details/CMakeLists.txt b/GraphGenerator/Incremental/Details/CMakeLists.txt new file mode 100644 index 0000000..ae1713e --- /dev/null +++ b/GraphGenerator/Incremental/Details/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + Converters.cpp + Converters.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/Incremental/Details/Converters.cpp b/GraphGenerator/Incremental/Details/Converters.cpp new file mode 100644 index 0000000..7359081 --- /dev/null +++ b/GraphGenerator/Incremental/Details/Converters.cpp @@ -0,0 +1,63 @@ +// Contains from string, to dependenciesMining::enums, converter functions. +// Soultatos Stefanos 2022 + +#include "Converters.h" +#include +#include + +namespace incremental::details { + + using namespace dependenciesMining; + + namespace { + + template + using EnumTable = std::unordered_map; + + // Safe access + template + inline auto Get(const EnumTable& table, const std::string& str) { + assert(table.find(str) != std::end(table)); + return table.at(str); + } + + } // namespace + + AccessType ToAccessType(const std::string& str) { + static const EnumTable table{{ "public", AccessType::_public }, + { "protected", AccessType::_protected }, + { "private", AccessType::_private }, + { "unknown", AccessType::unknown } }; + + return Get(table, str); + } + + StructureType ToStructureType(const std::string& str) { + static const EnumTable table{{ "Class", StructureType::Class }, + { "Struct", StructureType::Struct }, + { "TemplateDefinition", StructureType::TemplateDefinition }, + { "TemplateFullSpecialization", StructureType::TemplateFullSpecialization }, + { "TemplateInstantiationSpecialization", StructureType::TemplateInstantiationSpecialization }, + { "TemplatePartialSpecialization", StructureType::TemplatePartialSpecialization}, + { "Undefined", StructureType::Undefined} }; + + return Get(table, str); + } + + MethodType ToMethodType(const std::string& str) { + static const EnumTable table {{"Constructor_UserDefined", MethodType::Constructor_UserDefined }, + {"Constructor_Trivial", MethodType::Constructor_Trivial }, + {"Destructor_UserDefined", MethodType::Constructor_UserDefined }, + {"Destructor_Trivial", MethodType::Destructor_Trivial }, + {"OverloadedOperator_UserDefined", MethodType::OverloadedOperator_UserDefined }, + {"OverloadedOperator_Trivial", MethodType::OverloadedOperator_Trivial }, + {"UserMethod", MethodType::UserMethod }, + {"TemplateDefinition", MethodType::TemplateDefinition }, + {"TemplateFullSpecialization", MethodType::TemplateFullSpecialization }, + {"TemplateInstantiationSpecialization", MethodType::TemplateInstantiationSpecialization }, + {"Undefined", MethodType::Undefined } }; + + return Get(table, str); + } + +} // incremental::details \ No newline at end of file diff --git a/GraphGenerator/Incremental/Details/Converters.h b/GraphGenerator/Incremental/Details/Converters.h new file mode 100644 index 0000000..c139b95 --- /dev/null +++ b/GraphGenerator/Incremental/Details/Converters.h @@ -0,0 +1,17 @@ +// Contains from string, to dependenciesMining::enums, converter functions. +// Soultatos Stefanos 2022 + +#pragma once + +#include +#include "SymbolTable.h" + +namespace incremental::details { + + dependenciesMining::AccessType ToAccessType(const std::string& str); + + dependenciesMining::StructureType ToStructureType(const std::string& str); + + dependenciesMining::MethodType ToMethodType(const std::string& str); + +} // incremental::details \ No newline at end of file diff --git a/GraphGenerator/Incremental/Incremental.cpp b/GraphGenerator/Incremental/Incremental.cpp new file mode 100644 index 0000000..2bdd776 --- /dev/null +++ b/GraphGenerator/Incremental/Incremental.cpp @@ -0,0 +1,307 @@ +// Incremental Generation module. +// Soultatos Stefanos 2022 + +#include "Incremental.h" +#include "Converters.h" + +#include +#include + +namespace incremental { + + using namespace dependenciesMining; + using namespace details; + + namespace { + + using JsonArchive = std::ifstream; + using JsonVal = Json::Value; + using JsonString = Json::String; + using SymbolID = JsonString; + using namespace dependenciesMining; + + // -------------------------- Json Utilities --------------------------------------- // + + // Utility for safe json access. + inline auto Get(const JsonVal& val, const char* at) { + assert(val.isMember(at)); + return val[at]; + } + + // Utility for id based json iteration. + template + void ForEach(const JsonVal& val, Function f) { + static_assert(std::is_invocable_v, "Invalid function."); + + for (auto iter = std::begin(val); iter != std::end(val); ++iter) + f(iter.name(), *iter); + } + + // --------------------------------------------------------------------------------- // + + // -------------------------- Deserializers ---------------------------------------- // + + inline SourceInfo DeserializeSrcInfo(const JsonVal& val) { + return { Get(val, "file").asString(), Get(val, "line").asInt(), Get(val, "col").asInt() }; + } + + inline void DeserializeDefinition(const SymbolID& id, const JsonVal& val, Definition* d) { + d->SetID(id); + d->SetName(Get(val, "name").asString()); + d->SetFullType(Get(val, "full_type").asString()); + d->SetSourceInfo(DeserializeSrcInfo(Get(val, "src_info"))); + } + + inline void DeserializeDefinitionWithAccessSpecifier(const SymbolID& id, const JsonVal& val, Definition* d) { + DeserializeDefinition(id, val, d); + d->SetAccessType(ToAccessType(Get(val, "access").asString())); + } + + inline void DeserializeMethod(const SymbolID& id, const JsonVal& val, Method* m) { + m->SetID(id); + m->SetName(Get(val, "name").asString()); + m->SetBranches(Get(val, "branches").asInt()); + m->SetLineCount(Get(val, "lines").asInt()); + m->SetLiterals(Get(val, "literals").asInt()); + m->SetLoops(Get(val, "loops").asInt()); + m->SetMaxScopeDepth(Get(val, "max_scope").asInt()); + m->SetAccessType(ToAccessType(Get(val, "access").asString())); + m->SetSourceInfo(DeserializeSrcInfo(Get(val, "src_info"))); + m->SetStatements(Get(val, "statements").asInt()); + m->SetVirtual(Get(val, "virtual").asBool()); + m->SetMethodType(ToMethodType(Get(val, "method_type").asString())); + } + + inline void DeserializeStructure(const SymbolID& id, const JsonVal& val, Structure* s) { + s->SetID(id); + s->SetName(Get(val, "name").asString()); + s->SetNamespace(Get(val, "namespace").asString()); + s->SetStructureType(ToStructureType(Get(val, "structure_type").asString())); + s->SetSourceInfo(DeserializeSrcInfo(Get(val, "src_info"))); + } + + // --------------------------------------------------------------------------------- // + + // --------------------------- Generic Dependency Installers ----------------------- // + + template + void InstallDependency(const JsonVal& val, SymbolTable& table, Installer install) { + static_assert(std::is_invocable_v, "Invalid installer."); + + assert(!val.isArray()); + + if (val.isNull()) { + install((Structure*) nullptr); + } + else { + assert(val.isString()); + + const auto id = val.asString(); + + install((Structure*) table.Install2(id, Structure{ id })); + } + } + + template + void InstallDependencies(const JsonVal& val, SymbolTable& table, Installer install) { + static_assert(std::is_invocable_v, "Invalid installer."); + + for (const auto& v : val) { + assert(v.isString()); + + const auto id = v.asString(); + + install(id, (Structure*) table.Install2(id, Structure{ id })); + } + } + + // --------------------------------------------------------------------------------- // + + // ------------------------------ Importers/Installers ----------------------------- // + + Structure* ImportStructure(const SymbolID& id, const JsonVal& val, SymbolTable& table); // fwd declare for early usage + + inline void InstallStructureNestedClasses(const JsonVal& val, SymbolTable& table, Structure* s) { + InstallDependencies(Get(val, "contains"), table, [s](const auto& id, auto* nested) { + s->InstallNestedClass(id, nested); + }); + } + + inline void InstallStructureFields(const JsonVal& val, SymbolTable& table, Structure* s) { + ForEach(Get(val, "fields"), [s, &table](const auto& id, const auto& val) { + auto* f = (Definition*) s->InstallField(id, {}); + assert(f); + + DeserializeDefinitionWithAccessSpecifier(id, val, f); + + InstallDependency(Get(val, "type"), table, [f](auto* t) { + f->SetType(t); + }); + + f->SetNamespace(s->GetNamespace()); + }); + } + + inline void InstallMethodReturnType(const JsonVal& val, SymbolTable& table, Method* m) { + assert(!Get(val, "ret_type").isNull()); + assert(Get(val, "ret_type").isString()); + + const auto id = Get(val, "ret_type").asString(); + + m->SetReturnType(id == "void" ? nullptr : (Structure*) table.Install2(id, Structure{ id })); + } + + inline void InstallMethodArgs(const JsonVal& val, SymbolTable& table, Method* m) { + ForEach(Get(val, "args"), [m, &table](const auto& id, const auto& val) { + auto* d = (Definition*) m->InstallArg(id, {}); + assert(d); + + DeserializeDefinition(id, val, d); + + InstallDependency(Get(val, "type"), table, [d](auto* t) { + d->SetType(t); + }); + + d->SetNamespace(m->GetNamespace()); + }); + } + + inline void InstallMethodDefinitions(const JsonVal& val, SymbolTable& table, Method* m) { + ForEach(Get(val, "definitions"), [m, &table](const auto& id, const auto& val) { + auto* d = (Definition*) m->InstallDefinition(id, {}); + assert(d); + + DeserializeDefinition(id, val, d); + + InstallDependency(Get(val, "type"), table, [d](auto* t) { + d->SetType(t); + }); + + d->SetNamespace(m->GetNamespace()); + }); + } + + inline void InstallMethodTemplateArgs(const JsonVal& val, SymbolTable& table, Method* m) { + InstallDependencies(Get(val, "template_args"), table, [m](const auto& id, auto* arg) { + m->InstallTemplateSpecializationArgument(id, arg); + }); + } + + inline void InstallStructureFriends(const JsonVal& val, SymbolTable& table, Structure* s) { + InstallDependencies(Get(val, "friends"), table, [s](const auto& id, auto* f) { + assert(f); + + s->InstallFriend(id, f); + }); + } + + inline void InstallStructureMethods(const JsonVal& val, SymbolTable& table, Structure* s) { + ForEach(Get(val, "methods"), [&table, s](const auto& id, const auto& val) { + auto* m = (Method*) s->InstallMethod(id, {}); + assert(m); + + DeserializeMethod(id, val, m); + + m->SetNamespace(s->GetNamespace()); + + InstallMethodReturnType(val, table, m); + InstallMethodArgs(val, table, m); + InstallMethodDefinitions(val, table, m); + InstallMethodTemplateArgs(val, table, m); + }); + } + + inline void InstallStructureBases(const JsonVal& val, SymbolTable& table, Structure* s) { + InstallDependencies(Get(val, "bases"), table, [s](const auto& id, auto* base) { + assert(base); + + s->InstallBase(id, base); + }); + } + + inline void InstalllStructureTemplateParent(const JsonVal& val, SymbolTable& table, Structure* s) { + InstallDependency(Get(val, "template_parent"), table, [s](auto* parent) { + s->SetTemplateParent(parent); + }); + } + + inline void InstalllStructureNestedParent(const JsonVal& val, SymbolTable& table, Structure* s) { + InstallDependency(Get(val, "nested_parent"), table, [s](auto* parent) { + s->SetNestedParent(parent); + }); + } + + inline void InstallStructureTemplateArguments(const JsonVal& val, SymbolTable& table, Structure* s) { + InstallDependencies(Get(val, "template_args"), table, [s](const auto& id, auto* arg) { + assert(arg); + s->InstallTemplateSpecializationArgument(id, arg); + }); + } + + Structure* ImportStructure(const SymbolID& id, const JsonVal& val, SymbolTable& table) { + auto* s = (Structure*) table.Install2(id, Structure{}); // Might return structure that was installed as a dependency. + assert(s); + + DeserializeStructure(id, val, s); + + InstallStructureNestedClasses(val, table, s); + InstallStructureBases(val, table, s); + InstallStructureFields(val, table, s); + InstallStructureFriends(val, table, s); + InstallStructureMethods(val, table, s); + InstalllStructureNestedParent(val, table, s); + InstalllStructureTemplateParent(val, table, s); + InstallStructureTemplateArguments(val, table, s); + + return s; + } + + inline void ImportStructures(const JsonVal& val, SymbolTable& table) { + ForEach(Get(val, "structures"), [&table](const auto& id, const auto& val) { + ImportStructure(id, val, table); + }); + } + + // --------------------------------------------------------------------------------- // + + inline JsonVal GetArchiveRoot(JsonArchive& from) { + JsonVal root; + from >> root; + return root; + } + + } // namespace + + void ImportST(const std::string_view jsonPath, SymbolTable& table) { + JsonArchive from{jsonPath.data()}; + ImportStructures(GetArchiveRoot(from), table); + + assert(from.good()); + assert(from.is_open()); + } + + void ImportSources(const std::string_view jsonPath, Sources& srcs) { + assert(srcs.empty()); + + JsonArchive from{jsonPath.data()}; + const auto srcVal = Get(GetArchiveRoot(from), "sources"); + assert(srcVal.isArray()); + + srcs.reserve(std::distance(std::begin(srcVal), std::end(srcVal))); + std::transform(std::begin(srcVal), std::end(srcVal), std::back_inserter(srcs), [](const auto& val) { + assert(val.isString()); + return val.asString(); + }); + + assert(from.good()); + assert(from.is_open()); + } + + Sources DropParsedFiles(const Sources& sources, const Sources& cached) { + assert(sources.size() >= cached.size()); + assert((std::begin(sources) + (sources.size() - 1)) <= std::end(sources)); + + return cached.empty() ? sources : Sources{std::begin(sources) + (cached.size() - 1), std::end(sources)}; + } + +} // incremental \ No newline at end of file diff --git a/GraphGenerator/Incremental/Incremental.h b/GraphGenerator/Incremental/Incremental.h new file mode 100644 index 0000000..d6b0bc8 --- /dev/null +++ b/GraphGenerator/Incremental/Incremental.h @@ -0,0 +1,25 @@ +// Incremental Generation module. +// Soultatos Stefanos 2022 + +#pragma once + +#include "SymbolTable.h" + +#include +#include +#include +#include +#include + +namespace incremental { + + using Sources = std::vector; + using SourceIDs = std::vector; + + void ImportST(const std::string_view jsonPath, dependenciesMining::SymbolTable& table); + void ImportSources(const std::string_view jsonPath, Sources& srcs); + + // Assumes that all cached files, except the last one, were entirely parsed. + Sources DropParsedFiles(const Sources& sources, const Sources& cached); + +} // incremental \ No newline at end of file diff --git a/GraphGenerator/Main/Architecture Mining.cpp b/GraphGenerator/Main/Architecture Mining.cpp deleted file mode 100644 index dc868ad..0000000 --- a/GraphGenerator/Main/Architecture Mining.cpp +++ /dev/null @@ -1,121 +0,0 @@ -#pragma warning(disable : 4996) -#pragma warning(disable : 4146) -#include -#include -#include "SourceLoader.h" -#include "DependenciesMining.h" -#include "GraphGeneration.h" -#include "GraphToJson.h" -#include "json/writer.h" - -static void PrintMainArgInfo(void) { - std::cout << "MAIN ARGUMENTS:\n\n"; - std::cout << "argv[1]: \"--src\" to mine whole directory with sources (argv[2]: directory/with/sources)\n"; - std::cout << "argv[1]: \"--cmp-db\" to use compilation database (argv[2]: path/to/compile_commands.json)\n"; - std::cout << "argv[3]: (file path) path/to/ignoredFilePaths\n"; - std::cout << "argv[4]: (file path) path/to/ignoredNamespaces\n"; - std::cout << "argv[5]: (file path) path/to/ST-output\n"; -} - -static void SetDepedenciesToST(const Json::Value& graph, Json::Value& ST) { - const Json::Value& all_dependencies = graph["edges"]; - auto& st_dependencies = ST["dependencies"]; - for (const auto& dependencies : all_dependencies) { - - Json::Value dependency_pack; - dependency_pack["types"] = dependencies["dependencies"]; - dependency_pack["from"] = dependencies["from"]; - dependency_pack["to"] = dependencies["to"]; - - st_dependencies.append(dependency_pack); - } -} - -static void SetCodeFilesToST(Json::Value& ST, const std::vector& srcs, const std::vector& headers) { - for (const auto& path : srcs) { - ST["sources"].append(path); - } - for (const auto& path : headers) { - ST["headers"].append(path); - } -} - -int main(int argc, const char** argv) { - if (argc < 6) { - PrintMainArgInfo(); - return 1; - } - std::string option1 = "--src"; - std::string option2 = "--cmp-db"; - const char* cmpDBPath = nullptr; - std::vector srcs; - std::vector headers; - if (option1 == argv[1]) { // --src - sourceLoader::SourceLoader srcLoader(argv[2]); - srcLoader.LoadSources(); - srcs = srcLoader.GetSources(); - } - else if (option2 == argv[1]) { //--cmp-db - cmpDBPath = argv[2]; - } - else { - PrintMainArgInfo(); - return 1; - } - const char* option = argv[1]; // option = "--src", option = "--cmp-db" - - //const char* ignoredFilePaths = (argc >= 4) ? argv[3] : ""; - //const char* ignoredNamespaces = (argc >= 5) ? argv[4] : ""; - const char* ignoredFilePaths = argv[3]; - const char* ignoredNamespaces = argv[4]; - - std::string fullPath = std::string(__FILE__); - std::size_t found = fullPath.find_last_of("/\\"); - /*std::string jsonPath = (argc >= 6) ? argv[5] : fullPath.substr(0, found + 1) + "../../GraphVisualizer/Graph/graph.json"; - std::string jsonSTPath = (argc >= 7) ? argv[6] : fullPath.substr(0, found + 1) + "../../ST0.json";*/ - std::string jsonSTPath = argv[5]; - - /*std::vector srcs; - srcs.push_back(path + "\\classes_simple.cpp"); - srcs.push_back(path + "\\fields.cpp"); - srcs.push_back(path + "\\friends.cpp"); - srcs.push_back(path + "\\member_classes.cpp"); - srcs.push_back(path + "\\methods_args_vars.cpp"); - srcs.push_back(path + "\\methods.cpp"); - srcs.push_back(path + "\\namespaces.cpp"); - //srcs.push_back(path + "\\objects_used_on_methods.cpp"); - srcs.push_back(path + "\\template_methods.cpp"); - srcs.push_back(path + "\\template_types.cpp"); - srcs.push_back(path + "\\templates.cpp"); - - srcs.push_back(path + "\\test0.cpp"); - srcs.push_back(path + "\\include.h"); - srcs.push_back(path + "\\include2.h");*/ - - std::cout << "\n-------------------------------------------------------------------------------------\n\n"; - int result = dependenciesMining::CreateClangTool(cmpDBPath, srcs, headers, ignoredFilePaths, ignoredNamespaces); - - - - - Json::Value json_ST; - structuresTable.AddJsonSymbolTable(json_ST["structures"]); - std::ofstream jsonSTFile(jsonSTPath); - - graph::Graph graph = graphGeneration::GenetareDependenciesGraph(dependenciesMining::structuresTable); - auto g = graphToJson::GetJson(graph); - SetDepedenciesToST(g, json_ST); - SetCodeFilesToST(json_ST, srcs, headers); - jsonSTFile << json_ST; - jsonSTFile.close(); - //std::cout << json_ST << std::endl; - // --------- Phiv ends here ------------------- - /*std::string json_graph_str = graphToJson::GetJsonString(graph); - - std::ofstream jsonFile; - - jsonFile.open(jsonPath); - jsonFile << json_graph_str; - jsonFile.close();*/ - std::cout << "\nCOMPILATION FINISHED\n"; -} \ No newline at end of file diff --git a/GraphGenerator/Main/CMakeLists.txt b/GraphGenerator/Main/CMakeLists.txt new file mode 100644 index 0000000..5cc3fd8 --- /dev/null +++ b/GraphGenerator/Main/CMakeLists.txt @@ -0,0 +1,12 @@ +set(FILES Main.cpp) +set(SUBDIRECTORIES ) +set(EXECUTABLE ArchitectureMining) + +foreach(VAR ${SUBDIRECTORIES}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + add_executable(${EXECUTABLE} ${FILES}) + target_link_libraries(${EXECUTABLE} PUBLIC ${PROJECT_NAME}) +endif() \ No newline at end of file diff --git a/GraphGenerator/Main/Main.cpp b/GraphGenerator/Main/Main.cpp new file mode 100644 index 0000000..dbffce3 --- /dev/null +++ b/GraphGenerator/Main/Main.cpp @@ -0,0 +1,220 @@ +#include "DependenciesMining.h" +#include "Gui.h" +#include "GuiController.h" +#include "SourceLoader.h" +#include "Incremental.h" +#include "Graph.h" +#include "GraphToJson.h" +#include "GraphGeneration.h" +#include "FileSystem.h" +#include "Messages.h" +#include "json/writer.h" +#include +#include +#include + +using namespace dependenciesMining; +using namespace sourceLoader; +using namespace incremental; +using namespace filesystem; +using namespace graph; +using namespace graphGeneration; +using namespace graphToJson; +using namespace gui; +using namespace messages; + +using FilePaths = std::vector; +using FilePathIDs = std::vector; + +// NOTE: Make sure that either there is no .json out file, or the .json out file was generated by mining with the INCREMENTAL_GENERATION flag enabled. + +namespace { + + void PrintMainArgInfo(std::ostream& os = std::cerr) { + os << "MAIN ARGUMENTS:\n\n"; + os << "argv[1]: \"--src\" to mine whole directory with sources (argv[2]: directory/with/sources)\n"; + os << "argv[1]: \"--cmp-db\" to use compilation database (argv[2]: path/to/compile_commands.json)\n"; + os << "argv[3]: (file path) path/to/ignoredFilePaths\n"; + os << "argv[4]: (file path) path/to/ignoredNamespaces\n"; + os << "argv[5]: (file path) path/to/ST-output\n"; + } + + void PrintClangToolInfo(std::string& errorMsg, std::ostream& os = std::cerr) { + os << "Clang Tool creation failed\n"; + os << errorMsg << '\n'; + } + + void PrintMiningResult(int res, std::ostream& os = std::cout) { + switch (res) + { + case 0: + os << "\nCOMPILATION FINISHED\n"; + break; + + case 1: + os << "\nCOMPILATION FAILED\n"; + break; + + case 2: + os << "\nCOMPILATION FINISHED (with skipped files)\n"; + break; + + default: + assert(false && "See: `int clang::tooling::ClangTool::run(clang::tooling::ToolAction *Action)`"); + break; + } + } + +} // namespace + +namespace { + + void SerializeDependencies(const Json::Value& graph, Json::Value& ST) { + const Json::Value& all_dependencies = graph["edges"]; + auto& st_dependencies = ST["dependencies"]; + + for (const auto& dependencies : all_dependencies) { + Json::Value dependency_pack; + dependency_pack["types"] = dependencies["dependencies"]; + dependency_pack["from"] = dependencies["from"]; + dependency_pack["to"] = dependencies["to"]; + + st_dependencies.append(dependency_pack); + } + } + + void SerializeFilePaths(Json::Value& ST, const FilePaths& srcs, const FilePaths& headers) { + for (const auto& path : srcs) + ST["sources"].append(path); + for (const auto& path : headers) + ST["headers"].append(path); + } + + void ProduceJsonOutput(const Graph& dependencyGraph, const SymbolTable& exportedTable, const FilePaths& srcs, const FilePaths& headers, const char* outputPath) { + assert(outputPath); + + Json::Value jsonST; + exportedTable.AddJsonSymbolTable(jsonST["structures"]); + + const auto jsonGraph = GetJson(dependencyGraph); + + SerializeDependencies(jsonGraph, jsonST); + SerializeFilePaths(jsonST, srcs, headers); + + std::ofstream jsonSTFile{outputPath}; + jsonSTFile << jsonST; + std::cout << "\nGRAPH GENERATED\n"; + + assert(jsonSTFile.good()); + assert(std::filesystem::exists(outputPath)); + } + + void ExportDependencies(ClangTool& tool, const SymbolTable& exportedTable, const char* outputPath) { + assert(outputPath); + + const auto dependenciesGraph = GenerateDependenciesGraph(exportedTable); + + FilePaths srcs, headers; + GetMinedFiles(tool, srcs, headers); + + ProduceJsonOutput(dependenciesGraph, structuresTable, srcs, headers, outputPath); + } + +} // namespace + +int main(int argc, char* argv[]) { + if (argc != 6) { + PrintMainArgInfo(); + return EXIT_FAILURE; + } + + constexpr std::string_view srcOption = "--src"; + constexpr std::string_view databaseOption = "--cmp-db"; + + const auto* compilationOption = argv[1]; + const auto* inputPath = argv[2]; + const auto* ignoredFilesPath = argv[3]; + const auto* ignoredNamespacesPath = argv[4]; + const auto* outputPath = argv[5]; + + std::unique_ptr clangTool; + std::string errorMsg; + +#ifdef INCREMENTAL_GENERATION + if (std::filesystem::exists(outputPath)) { + ImportST(outputPath, structuresTable); + ImportSources(outputPath, parsedFiles); + } +#endif + + SetIgnoredRegions(ignoredFilesPath, ignoredNamespacesPath); + + if (compilationOption == srcOption) { + clangTool = CreateClangTool(SourceLoader{ inputPath }.GetSources()); + + } else if (compilationOption == databaseOption) { + clangTool = CreateClangTool(inputPath, errorMsg); + + } else { + PrintMainArgInfo(); + return EXIT_FAILURE; + } + + if (!clangTool) { + PrintClangToolInfo(errorMsg); + return EXIT_FAILURE; + } + + std::cout << "\n-------------------------------------------------------------------------------------\n\n"; + int miningRes { -1 }; + +#ifdef GUI + wxEntryStart(argc, argv); + +// NOTE: Might need to set max from clang::tooling::CompilationDatabase::getAllCompileCommands().size(). +// FIXME? +#ifdef INCREMENTAL_GENERATION + const auto max = clangTool->getSourcePaths().size() + (parsedFiles.empty() ? 0 : parsedFiles.size() - 1); +#else + const auto max = clangTool->getSourcePaths().size(); +#endif + + GuiController::GetSingleton().GetGui().ConnectToCancel(&DisruptMining); + GuiController::GetSingleton().GetGui().OnInit(); + + GuiController::GetSingleton().SetTotalUnits(max); + + ConnectToBeginSource([](auto currFileName) { + PostMessage([currFileName]() { + GuiController::GetSingleton().AdvanceAndUpdateGui(currFileName); + }); + }); + +#ifdef INCREMENTAL_GENERATION + GuiController::GetSingleton().AdvanceGuiProgress(parsedFiles.size()); +#endif + + auto worker = std::thread([&miningRes, &clangTool](){ miningRes = MineArchitecture(*clangTool); }); + + do + { + PollMessage(); + GuiController::GetSingleton().GetGui().Render(); + } while (!GuiController::GetSingleton().IsGuiProgressDone() and !IsMiningDisrupted()); + + worker.join(); + + PrintMiningResult(miningRes); + + ExportDependencies(*clangTool, structuresTable, outputPath); + +#else + miningRes = MineArchitecture(*clangTool); + + PrintMiningResult(miningRes); + + ExportDependencies(*clangTool, structuresTable, outputPath); +#endif + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/GraphGenerator/Main/graph.json b/GraphGenerator/Main/graph.json deleted file mode 100644 index 71455f2..0000000 --- a/GraphGenerator/Main/graph.json +++ /dev/null @@ -1,1777 +0,0 @@ -{ - "edges" : - [ - { - "dependencies" : - { - "ClassField" : 4, - "MemberExpr" : 3, - "MethodDefinition" : 2, - "MethodReturn" : 2 - }, - "from" : "memberExpr::A", - "to" : "memberExpr::B" - }, - { - "dependencies" : - { - "MemberExpr" : 5, - "MethodDefinition" : 6 - }, - "from" : "memberExpr::A", - "to" : "memberExpr::C" - }, - { - "dependencies" : - { - "MethodDefinition" : 2 - }, - "from" : "memberExpr::A", - "to" : "memberExpr::A::A" - }, - { - "dependencies" : - { - "MemberExpr" : 1, - "MethodDefinition" : 4 - }, - "from" : "memberExpr::A", - "to" : "memberExpr::X" - }, - { - "dependencies" : - { - "MemberExpr" : 3 - }, - "from" : "memberExpr::A", - "to" : "memberExpr::Y" - }, - { - "dependencies" : - { - "MemberExpr" : 2 - }, - "from" : "memberExpr::A", - "to" : "memberExpr::K" - }, - { - "dependencies" : - { - "ClassField" : 4 - }, - "from" : "memberExpr::B", - "to" : "memberExpr::C" - }, - { - "dependencies" : - { - "ClassTemplateParent" : 1 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::A" - }, - { - "dependencies" : - { - "ClassTemplateArg" : 1, - "MemberExpr" : 4, - "MethodDefinition" : 4, - "MethodReturn" : 2 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::B" - }, - { - "dependencies" : - { - "MethodDefinition" : 2, - "MethodReturn" : 1 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::A::A" - }, - { - "dependencies" : - { - "MemberExpr" : 11, - "MethodDefinition" : 6 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::C" - }, - { - "dependencies" : - { - "MemberExpr" : 4, - "MethodDefinition" : 4 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::X" - }, - { - "dependencies" : - { - "MemberExpr" : 4 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::Y" - }, - { - "dependencies" : - { - "MemberExpr" : 3 - }, - "from" : "memberExpr::A::A", - "to" : "memberExpr::K" - }, - { - "dependencies" : - { - "ClassField" : 2 - }, - "from" : "memberExpr::Y", - "to" : "memberExpr::K" - }, - { - "dependencies" : - { - "ClassField" : 2, - "MemberExpr" : 1 - }, - "from" : "memberExpr::C", - "to" : "memberExpr::X" - }, - { - "dependencies" : - { - "MethodDefinition" : 2, - "MethodReturn" : 2 - }, - "from" : "memberExpr::X", - "to" : "memberExpr::Y" - } - ], - "nodes" : - { - "memberExpr::A" : - { - "bases" : null, - "fields" : - { - "memberExpr::A::b" : - { - "id" : "memberExpr::A::b", - "name" : "memberExpr::A::b", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 40 - }, - "type" : "memberExpr::B" - }, - "memberExpr::A::b2" : - { - "id" : "memberExpr::A::b2", - "name" : "memberExpr::A::b2", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 41 - }, - "type" : "memberExpr::B" - } - }, - "friends" : null, - "id" : "memberExpr::A", - "methods" : - { - "memberExpr::A::m_a(void)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::m_a(void)", - "memberExprs" : null, - "methodType" : "UserMethod", - "name" : "memberExpr::A::m_a(void)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 47 - }, - "templateArguments" : null - }, - "memberExpr::A::m_b(int)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::m_b(int)", - "memberExprs" : null, - "methodType" : "UserMethod", - "name" : "memberExpr::A::m_b(int)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::B", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 42 - }, - "templateArguments" : null - }, - "memberExpr::A::method(void)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::method(void)", - "memberExprs" : - [ - { - "expr" : "px->m1(1)", - "members" : - [ - { - "locEnd" : - { - "column" : 8, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 60 - }, - "name" : "m1", - "type" : "memberExpr::Y" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 60 - } - }, - { - "expr" : "pc->x", - "members" : - [ - { - "locEnd" : - { - "column" : 18, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 58 - }, - "name" : "x", - "type" : "memberExpr::X" - } - ], - "srcInfo" : - { - "column" : 14, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 58 - } - }, - { - "expr" : "b2->pc", - "members" : - [ - { - "locEnd" : - { - "column" : 16, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 52 - }, - "name" : "pc", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 12, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 52 - } - }, - { - "expr" : "x.m2().k", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 61 - }, - "name" : "k", - "type" : "memberExpr::K" - }, - { - "locEnd" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 61 - }, - "name" : "m2", - "type" : "memberExpr::Y" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 61 - } - }, - { - "expr" : "b.c", - "members" : - [ - { - "locEnd" : - { - "column" : 12, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 53 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 10, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 53 - } - }, - { - "expr" : "(*(px->m1(1))).k", - "members" : - [ - { - "locEnd" : - { - "column" : 19, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - }, - "name" : "k", - "type" : "memberExpr::K" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - } - }, - { - "expr" : "px->m1(1)", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - }, - "name" : "m1", - "type" : "memberExpr::Y" - } - ], - "srcInfo" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - } - }, - { - "expr" : "f(b).c", - "members" : - [ - { - "locEnd" : - { - "column" : 23, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 69 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 18, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 69 - } - }, - { - "expr" : "b.c.i", - "members" : - [ - { - "locEnd" : - { - "column" : 15, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 71 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 13, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 71 - } - }, - { - "expr" : "a.b2", - "members" : - [ - { - "locEnd" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 74 - }, - "name" : "b2", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 74 - } - }, - { - "expr" : "a.b.c.i", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 75 - }, - "name" : "c", - "type" : "memberExpr::C" - }, - { - "locEnd" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 75 - }, - "name" : "b", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 75 - } - }, - { - "expr" : "a.b2", - "members" : - [ - { - "locEnd" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 76 - }, - "name" : "b2", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 76 - } - } - ], - "methodType" : "UserMethod", - "name" : "memberExpr::A::method(void)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::B", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 51 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::A", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 29, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 39 - }, - "structureType" : "TemplateDefinition", - "templateArguments" : null - }, - "memberExpr::A::A" : - { - "bases" : null, - "fields" : null, - "friends" : null, - "id" : "memberExpr::A::A", - "methods" : - { - "memberExpr::A::A(const struct memberExpr::A &)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::A(const struct memberExpr::A &)", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::A::A(const struct memberExpr::A &)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 29, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 39 - }, - "templateArguments" : null - }, - "memberExpr::A::A(struct memberExpr::A &&)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::A(struct memberExpr::A &&)", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::A::A(struct memberExpr::A &&)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 29, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 39 - }, - "templateArguments" : null - }, - "memberExpr::A::A(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::A(void) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::A::A(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 29, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 39 - }, - "templateArguments" : null - }, - "memberExpr::A::m_a(void)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::m_a(void)", - "memberExprs" : null, - "methodType" : "UserMethod", - "name" : "memberExpr::A::m_a(void)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::A::A", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 47 - }, - "templateArguments" : null - }, - "memberExpr::A::m_b(int)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::m_b(int)", - "memberExprs" : null, - "methodType" : "UserMethod", - "name" : "memberExpr::A::m_b(int)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::B", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 42 - }, - "templateArguments" : null - }, - "memberExpr::A::method(void)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::A::method(void)", - "memberExprs" : - [ - { - "expr" : "px->m1(1)", - "members" : - [ - { - "locEnd" : - { - "column" : 8, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 60 - }, - "name" : "m1", - "type" : "memberExpr::Y" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 60 - } - }, - { - "expr" : "bb.c", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 55 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 8, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 55 - } - }, - { - "expr" : "pc->x", - "members" : - [ - { - "locEnd" : - { - "column" : 18, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 58 - }, - "name" : "x", - "type" : "memberExpr::X" - } - ], - "srcInfo" : - { - "column" : 14, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 58 - } - }, - { - "expr" : "b2->pc", - "members" : - [ - { - "locEnd" : - { - "column" : 16, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 52 - }, - "name" : "pc", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 12, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 52 - } - }, - { - "expr" : "x.m2().k", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 61 - }, - "name" : "k", - "type" : "memberExpr::K" - }, - { - "locEnd" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 61 - }, - "name" : "m2", - "type" : "memberExpr::Y" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 61 - } - }, - { - "expr" : "b.c", - "members" : - [ - { - "locEnd" : - { - "column" : 12, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 53 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 10, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 53 - } - }, - { - "expr" : "bb.c.x", - "members" : - [ - { - "locEnd" : - { - "column" : 15, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 57 - }, - "name" : "x", - "type" : "memberExpr::X" - }, - { - "locEnd" : - { - "column" : 13, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 57 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 10, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 57 - } - }, - { - "expr" : "(*(px->m1(1))).k", - "members" : - [ - { - "locEnd" : - { - "column" : 19, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - }, - "name" : "k", - "type" : "memberExpr::K" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - } - }, - { - "expr" : "px->m1(1)", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - }, - "name" : "m1", - "type" : "memberExpr::Y" - } - ], - "srcInfo" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 62 - } - }, - { - "expr" : "bb.c.x.m1(1)->k", - "members" : - [ - { - "locEnd" : - { - "column" : 18, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 65 - }, - "name" : "k", - "type" : "memberExpr::K" - }, - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 65 - }, - "name" : "m1", - "type" : "memberExpr::Y" - }, - { - "locEnd" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 65 - }, - "name" : "x", - "type" : "memberExpr::X" - }, - { - "locEnd" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 65 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 65 - } - }, - { - "expr" : "m_b(2).c.x", - "members" : - [ - { - "locEnd" : - { - "column" : 13, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 67 - }, - "name" : "x", - "type" : "memberExpr::X" - }, - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 67 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 67 - } - }, - { - "expr" : "a.b2", - "members" : - [ - { - "locEnd" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 76 - }, - "name" : "b2", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 76 - } - }, - { - "expr" : "m_a()->b2->pc", - "members" : - [ - { - "locEnd" : - { - "column" : 15, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 68 - }, - "name" : "pc", - "type" : "memberExpr::C" - }, - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 68 - }, - "name" : "b2", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 68 - } - }, - { - "expr" : "f(b).c", - "members" : - [ - { - "locEnd" : - { - "column" : 23, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 69 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 18, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 69 - } - }, - { - "expr" : "b.c.i", - "members" : - [ - { - "locEnd" : - { - "column" : 15, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 71 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 13, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 71 - } - }, - { - "expr" : "bb.c.i", - "members" : - [ - { - "locEnd" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 71 - }, - "name" : "c", - "type" : "memberExpr::C" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 71 - } - }, - { - "expr" : "a.b2", - "members" : - [ - { - "locEnd" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 74 - }, - "name" : "b2", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 4, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 74 - } - }, - { - "expr" : "a.b.c.i", - "members" : - [ - { - "locEnd" : - { - "column" : 11, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 75 - }, - "name" : "c", - "type" : "memberExpr::C" - }, - { - "locEnd" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 75 - }, - "name" : "b", - "type" : "memberExpr::B" - } - ], - "srcInfo" : - { - "column" : 7, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 75 - } - } - ], - "methodType" : "UserMethod", - "name" : "memberExpr::A::method(void)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::B", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 51 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::A::A", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 29, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 39 - }, - "structureType" : "TemplateInstatiationSpecialization", - "templateArguments" : - [ - "memberExpr::B" - ], - "templateParent" : "memberExpr::A" - }, - "memberExpr::B" : - { - "bases" : null, - "fields" : - { - "memberExpr::B::c" : - { - "id" : "memberExpr::B::c", - "name" : "memberExpr::B::c", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 33 - }, - "type" : "memberExpr::C" - }, - "memberExpr::B::pc" : - { - "id" : "memberExpr::B::pc", - "name" : "memberExpr::B::pc", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 34 - }, - "type" : "memberExpr::C" - } - }, - "friends" : null, - "id" : "memberExpr::B", - "methods" : - { - "memberExpr::B::B(const struct memberExpr::B &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::B::B(const struct memberExpr::B &) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::B::B(const struct memberExpr::B &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 32 - }, - "templateArguments" : null - }, - "memberExpr::B::B(struct memberExpr::B &&) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::B::B(struct memberExpr::B &&) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::B::B(struct memberExpr::B &&) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 32 - }, - "templateArguments" : null - }, - "memberExpr::B::B(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::B::B(void) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::B::B(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 32 - }, - "templateArguments" : null - }, - "memberExpr::B::~B(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::B::~B(void) noexcept", - "memberExprs" : null, - "methodType" : "Destructor_Trivial", - "name" : "memberExpr::B::~B(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 32 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::B", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 32 - }, - "structureType" : "Struct", - "templateArguments" : null - }, - "memberExpr::C" : - { - "bases" : null, - "fields" : - { - "memberExpr::C::x" : - { - "id" : "memberExpr::C::x", - "name" : "memberExpr::C::x", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 29 - }, - "type" : "memberExpr::X" - } - }, - "friends" : null, - "id" : "memberExpr::C", - "methods" : - { - "memberExpr::C::C(const struct memberExpr::C &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::C::C(const struct memberExpr::C &) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::C::C(const struct memberExpr::C &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "templateArguments" : null - }, - "memberExpr::C::C(struct memberExpr::C &&) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::C::C(struct memberExpr::C &&) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::C::C(struct memberExpr::C &&) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "templateArguments" : null - }, - "memberExpr::C::C(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::C::C(void) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::C::C(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "templateArguments" : null - }, - "memberExpr::C::operator=(const struct memberExpr::C &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::C::operator=(const struct memberExpr::C &) noexcept", - "memberExprs" : - [ - { - "expr" : "i", - "members" : - [ - { - "locEnd" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "name" : "x", - "type" : "memberExpr::X" - } - ], - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - } - } - ], - "methodType" : "OverloadedOperator_Trivial", - "name" : "memberExpr::C::operator=(const struct memberExpr::C &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "templateArguments" : null - }, - "memberExpr::C::operator=(struct memberExpr::C &&)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::C::operator=(struct memberExpr::C &&)", - "memberExprs" : null, - "methodType" : "OverloadedOperator_Trivial", - "name" : "memberExpr::C::operator=(struct memberExpr::C &&)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "templateArguments" : null - }, - "memberExpr::C::~C(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::C::~C(void) noexcept", - "memberExprs" : null, - "methodType" : "Destructor_Trivial", - "name" : "memberExpr::C::~C(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::C", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 27 - }, - "structureType" : "Struct", - "templateArguments" : null - }, - "memberExpr::K" : - { - "bases" : null, - "fields" : null, - "friends" : null, - "id" : "memberExpr::K", - "methods" : - { - "memberExpr::K::K(const struct memberExpr::K &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::K::K(const struct memberExpr::K &) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::K::K(const struct memberExpr::K &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 5 - }, - "templateArguments" : null - }, - "memberExpr::K::K(struct memberExpr::K &&)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::K::K(struct memberExpr::K &&)", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::K::K(struct memberExpr::K &&)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 5 - }, - "templateArguments" : null - }, - "memberExpr::K::K(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::K::K(void) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::K::K(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 5 - }, - "templateArguments" : null - }, - "memberExpr::K::~K(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::K::~K(void) noexcept", - "memberExprs" : null, - "methodType" : "Destructor_Trivial", - "name" : "memberExpr::K::~K(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 5 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::K", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 5 - }, - "structureType" : "Struct", - "templateArguments" : null - }, - "memberExpr::X" : - { - "bases" : null, - "fields" : null, - "friends" : null, - "id" : "memberExpr::X", - "methods" : - { - "memberExpr::X::X(const struct memberExpr::X &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::X(const struct memberExpr::X &) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::X::X(const struct memberExpr::X &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "templateArguments" : null - }, - "memberExpr::X::X(struct memberExpr::X &&) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::X(struct memberExpr::X &&) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::X::X(struct memberExpr::X &&) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "templateArguments" : null - }, - "memberExpr::X::X(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::X(void) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::X::X(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "templateArguments" : null - }, - "memberExpr::X::m1(int)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::m1(int)", - "memberExprs" : null, - "methodType" : "UserMethod", - "name" : "memberExpr::X::m1(int)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::Y", - "srcInfo" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 16 - }, - "templateArguments" : null - }, - "memberExpr::X::m2(void)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::m2(void)", - "memberExprs" : null, - "methodType" : "UserMethod", - "name" : "memberExpr::X::m2(void)", - "namespace" : "memberExpr::", - "returnType" : "memberExpr::Y", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 20 - }, - "templateArguments" : null - }, - "memberExpr::X::operator=(const struct memberExpr::X &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::operator=(const struct memberExpr::X &) noexcept", - "memberExprs" : null, - "methodType" : "OverloadedOperator_Trivial", - "name" : "memberExpr::X::operator=(const struct memberExpr::X &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "templateArguments" : null - }, - "memberExpr::X::operator=(struct memberExpr::X &&)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::operator=(struct memberExpr::X &&)", - "memberExprs" : null, - "methodType" : "OverloadedOperator_Trivial", - "name" : "memberExpr::X::operator=(struct memberExpr::X &&)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "templateArguments" : null - }, - "memberExpr::X::~X(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::X::~X(void) noexcept", - "memberExprs" : null, - "methodType" : "Destructor_Trivial", - "name" : "memberExpr::X::~X(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::X", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 14 - }, - "structureType" : "Struct", - "templateArguments" : null - }, - "memberExpr::Y" : - { - "bases" : null, - "fields" : - { - "memberExpr::Y::k" : - { - "id" : "memberExpr::Y::k", - "name" : "memberExpr::Y::k", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 5, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 8 - }, - "type" : "memberExpr::K" - } - }, - "friends" : null, - "id" : "memberExpr::Y", - "methods" : - { - "memberExpr::Y::Y(const struct memberExpr::Y &) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::Y::Y(const struct memberExpr::Y &) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::Y::Y(const struct memberExpr::Y &) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 7 - }, - "templateArguments" : null - }, - "memberExpr::Y::Y(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::Y::Y(void) noexcept", - "memberExprs" : null, - "methodType" : "Constructor_Trivial", - "name" : "memberExpr::Y::Y(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 7 - }, - "templateArguments" : null - }, - "memberExpr::Y::operator=(const struct memberExpr::Y &)" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::Y::operator=(const struct memberExpr::Y &)", - "memberExprs" : null, - "methodType" : "OverloadedOperator_UserDefined", - "name" : "memberExpr::Y::operator=(const struct memberExpr::Y &)", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 6, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 9 - }, - "templateArguments" : null - }, - "memberExpr::Y::~Y(void) noexcept" : - { - "arguments" : null, - "definitions" : null, - "id" : "memberExpr::Y::~Y(void) noexcept", - "memberExprs" : null, - "methodType" : "Destructor_Trivial", - "name" : "memberExpr::Y::~Y(void) noexcept", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 7 - }, - "templateArguments" : null - } - }, - "name" : "memberExpr::Y", - "namespace" : "memberExpr::", - "srcInfo" : - { - "column" : 9, - "fileName" : "C:\\Users\\Krystallia Savvaki\\Desktop\\Git\\Architecture-Mining\\Testfiles\\objects_used_on_methods.cpp", - "line" : 7 - }, - "structureType" : "Struct", - "templateArguments" : null - } - } -} diff --git a/GraphGenerator/Messages/CMakeLists.txt b/GraphGenerator/Messages/CMakeLists.txt new file mode 100644 index 0000000..b58cb43 --- /dev/null +++ b/GraphGenerator/Messages/CMakeLists.txt @@ -0,0 +1,11 @@ +set(FILES) +set(SUBDIRECTORIES) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/Messages/Detail/Messages.h b/GraphGenerator/Messages/Detail/Messages.h new file mode 100644 index 0000000..2ede8e0 --- /dev/null +++ b/GraphGenerator/Messages/Detail/Messages.h @@ -0,0 +1,15 @@ +#pragma once + +#include +#include + +namespace messages::detail { + + // Thread safe. + inline auto GetMessageQueue() -> auto& { + static auto service = boost::asio::io_service(); + static auto worker = boost::asio::make_work_guard(service); // prevent early exits. + return service; + } + +} \ No newline at end of file diff --git a/GraphGenerator/Messages/Messages.h b/GraphGenerator/Messages/Messages.h new file mode 100644 index 0000000..ecd43e0 --- /dev/null +++ b/GraphGenerator/Messages/Messages.h @@ -0,0 +1,25 @@ +// Simple message passing, useful across threads. +// Soultatos Stefanos 2022 + +#pragma once + +#include "Detail/Messages.h" + +#include +#include +#include + +namespace messages { + + // Thread safe. + template < typename Message > + inline void PostMessage(Message msg) { + using boost::asio::post; + static_assert(std::is_invocable_v< Message >); + post(detail::GetMessageQueue(), [token = std::move(msg)]() { token(); }); + } + + // Thread safe. + inline void PollMessage() { detail::GetMessageQueue().poll_one(); } + +} diff --git a/GraphGenerator/README.md b/GraphGenerator/README.md new file mode 100644 index 0000000..1721951 --- /dev/null +++ b/GraphGenerator/README.md @@ -0,0 +1,72 @@ +# An architecture miner of C++ compilation units + + +# Set-Up / Build + +GraphGenerator uses CMake as its build system on all supported platforms (tested on +ubuntu debian Pop!_OS version 22.04 LTS). +This guide will explain to you how to use CMake to build it from source, +under this OS. + + +## Table of Contents + +[Getting dependencies](#getting-dependencies) +[CMake optional variables](#cmake-optional-variables) +[Building](#building) + +## Getting dependencies + +* Clang +Follow the steps described at: https://github.com/llvm/llvm-project. +Make sure to configure the build process with: `-DLLVM_ENABLE_PROJECTS="clang"`. +(Tested with the 15.0.2 clang version). + +* Jsoncpp +`sudo apt-get install libjsoncpp-dev` +This will install the compatible JsonCpp library on your system. GraphGenerator should +now be able to link against the libjsoncpp target. + +* wxWidgets +For building this library, please see platform-specific documentation under `docs/` directory +at: https://github.com/wxWidgets/wxWidgets. +(Tested with the 3.1 w.x version). +GraphGenerator should now be able to link against the wxWidgets_LIBRARIES target. + + +## CMake optional variables + +Before building the application, some final CMake variables can optionally be +set. Namely, the: CLANG_INCLUDE_DIR, INCREMENTAL_GENERATION, GUI. + +**CLANG_INCLUDE_DIR** (`string`) +The directory path to the .h files for clang. +E.g: /usr/lib/llvm-15/lib/clang/15.0.2/. +If this variable is not configured appropriately, many minining attempts may result to compilation failures. + +**INCREMENTAL_GENERATION** (`bool`) +Controls wether to mine incrementally after cancel and re-run, (true by default). +When mining incrementally, GraphGenerator can pickup and continue previous mining sessions on launch. + +**GUI** (`bool`) +Controls wether to display a GUI progress bar, in order to monitor the mining session and cancel it if needed, +(true by default). + + +## Building + +Clone the repο: +`git clone https://github.com/SoultatosStefanos/Code-Smell-Detector` +You should create a build directory for GraphGenerator somewhere outside GraphGenerator's sources. +Then: +`cd build && cmake ..` +`make` +In order to build the application. + + + + + + + + diff --git a/GraphGenerator/SourceLoader/CMakeLists.txt b/GraphGenerator/SourceLoader/CMakeLists.txt new file mode 100644 index 0000000..1cc7ad4 --- /dev/null +++ b/GraphGenerator/SourceLoader/CMakeLists.txt @@ -0,0 +1,14 @@ +set(FILES + SourceLoader.cpp + SourceLoader.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/GraphGenerator/SourceLoader/SourceLoader.cpp b/GraphGenerator/SourceLoader/SourceLoader.cpp index 568d15a..bd6ae54 100644 --- a/GraphGenerator/SourceLoader/SourceLoader.cpp +++ b/GraphGenerator/SourceLoader/SourceLoader.cpp @@ -2,6 +2,8 @@ using namespace sourceLoader; +// FIXME + bool SourceLoader::IsSourceFile(const fs::path& p) { if (p.extension() == ".cpp" || p.extension() == ".h" || p.extension() == ".hh" || p.extension() == ".CPP" || p.extension() == ".H" || p.extension() == ".HH") diff --git a/GraphGenerator/SourceLoader/SourceLoader.h b/GraphGenerator/SourceLoader/SourceLoader.h index 12af2cc..0dca611 100644 --- a/GraphGenerator/SourceLoader/SourceLoader.h +++ b/GraphGenerator/SourceLoader/SourceLoader.h @@ -1,6 +1,7 @@ #pragma once #include #include +#include namespace fs = std::filesystem; diff --git a/GraphGenerator/Testfiles/.vscode/settings.json b/GraphGenerator/Testfiles/.vscode/settings.json deleted file mode 100644 index 3186594..0000000 --- a/GraphGenerator/Testfiles/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "files.associations": { - "iostream": "cpp", - "iosfwd": "cpp", - "istream": "cpp", - "vector": "cpp" - } -} \ No newline at end of file diff --git a/GraphGenerator/Testfiles/classes_simple.cpp b/GraphGenerator/Testfiles/classes_simple.cpp index 19b625f..164a4db 100644 --- a/GraphGenerator/Testfiles/classes_simple.cpp +++ b/GraphGenerator/Testfiles/classes_simple.cpp @@ -4,6 +4,18 @@ Inheritence */ namespace CS{ + class OO { + void Bar() { + int x; + } + }; + + class OOOO { + void Foo() { + int x; + } + }; + namespace CS_1{ class class_X; class class_B; diff --git a/GraphGenerator/Utilities/CMakeLists.txt b/GraphGenerator/Utilities/CMakeLists.txt new file mode 100644 index 0000000..756e144 --- /dev/null +++ b/GraphGenerator/Utilities/CMakeLists.txt @@ -0,0 +1,16 @@ +set(FILES + uobject_untyped.cpp + uobject_untyped.h + uvalue_untyped.cpp + uvalue_untyped.h +) +set(SUBDIRECTORIES ) + +foreach(VAR ${SUBDIRECTORIES}) + target_include_directories(${PROJECT_NAME} PUBLIC ${VAR}) + add_subdirectory(${VAR}) +endforeach() + +if(FILES) + target_sources(${PROJECT_NAME} PUBLIC ${FILES}) +endif() \ No newline at end of file diff --git a/Sample_Compilation_DB/compile_commands.json b/Sample_Compilation_DB/compile_commands.json index 70ef3a4..f5b100b 100644 --- a/Sample_Compilation_DB/compile_commands.json +++ b/Sample_Compilation_DB/compile_commands.json @@ -1,32 +1,31 @@ -[ - { - "directory": "/home/user/llvm/build", - "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", - "file": "file.cc" - }, - { - "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", - "command": "g++ classes_simple.cpp", - "file": "classes_simple.cpp" - }, - { - "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", - "command": "g++ fields.cpp", - "file": "fields.cpp" - }, - { - "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", - "command": "g++ friends.cpp", - "file": "friends.cpp" - }, - { - "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", - "command": "g++ member_classes.cpp", - "file": "member_classes.cpp" - }, - { - "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", - "command": "g++ methods.cpp", - "file": "methods.cpp" - } +[{ + "directory": "/home/user/llvm/build", + "command": "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" -c -o file.o file.cc", + "file": "file.cc" + }, + { + "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", + "command": "g++ classes_simple.cpp", + "file": "classes_simple.cpp" + }, + { + "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", + "command": "g++ fields.cpp", + "file": "fields.cpp" + }, + { + "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", + "command": "g++ friends.cpp", + "file": "friends.cpp" + }, + { + "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", + "command": "g++ member_classes.cpp", + "file": "member_classes.cpp" + }, + { + "directory": "C:/Users/Phoivos/source/repos/Architecture_Mining/Architecture_Mining/GraphGenerator/Testfiles", + "command": "g++ methods.cpp", + "file": "methods.cpp" + } ] \ No newline at end of file