From 652923049a8a36b1976064c24cbbb9fbe9c91a38 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 16 Mar 2023 17:06:39 +0100 Subject: [PATCH 01/49] Diagrams :: Add my first test diagram csharpservice::getFileDiagramTypes and getFileDiagrams got a test functionality, creating the diagram 'TEST DIAGRAM'. csharpfilediagram.cpp and .h got created in order to achieve this. getFileDiagramTypes and getFileDiagram got added to thrift. --- plugins/csharp/service/csharpservice.thrift | 6 + .../service/include/service/csharpservice.h | 15 + .../csharp/service/src/csharpfilediagram.cpp | 855 ++++++++++++++++++ .../csharp/service/src/csharpfilediagram.h | 408 +++++++++ plugins/csharp/service/src/csharpservice.cpp | 22 +- .../service/src_csharp/CSharpQueryHandler.cs | 28 + .../service/src_csharp/csharpservice.csproj | 1 + plugins/csharp/webgui/js/csharpDiagram.js | 2 +- 8 files changed, 1333 insertions(+), 4 deletions(-) create mode 100644 plugins/csharp/service/src/csharpfilediagram.cpp create mode 100644 plugins/csharp/service/src/csharpfilediagram.h diff --git a/plugins/csharp/service/csharpservice.thrift b/plugins/csharp/service/csharpservice.thrift index 4d223da5e..fcf5e50da 100644 --- a/plugins/csharp/service/csharpservice.thrift +++ b/plugins/csharp/service/csharpservice.thrift @@ -55,4 +55,10 @@ service CsharpService list getSyntaxHighlight( 1:common.FileRange range, 2:list content) + + map getFileDiagramTypes(1:common.FileId fileId) + throws (1:common.InvalidId ex) + + string getFileDiagram(1:common.FileId fileId, 2:i32 diagramId) + throws (1:common.InvalidId exId, 2:common.Timeout exLong) } \ No newline at end of file diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index 3660098c9..6c3968172 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -205,6 +205,21 @@ class CSharpQueryHandler : public CsharpServiceIf _thriftServerPort = port; } + void getFileDiagramTypes( + std::map& return_, + const core::FileId& fileId_) override + { + _service -> getFileDiagramTypes(return_, fileId_); + } + + void getFileDiagram( + std::string& return_, + const core::FileId& fileId_, + const std::int32_t diagramId_) override + { + _service -> getFileDiagram(return_, fileId_, diagramId_); + } + private: std::unique_ptr _service; static std::stringstream _thriftStream; diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp new file mode 100644 index 000000000..b5f571f40 --- /dev/null +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -0,0 +1,855 @@ +#include +#include +#include + +#include +#include +#include + +#include "csharpfilediagram.h" + + +namespace cc +{ +namespace service +{ +namespace language +{ + +//namespace language = cc::service::language; + +/*typedef odb::query IncludeQuery; +typedef odb::result IncludeResult; +typedef odb::query EdgeQuery; +typedef odb::result EdgeResult; +typedef odb::query TargetQuery; +typedef odb::result TargetResult; +typedef odb::query SourceQuery; +typedef odb::result SourceResult;*/ +typedef odb::query FileQuery; +typedef odb::result FileResult; + +CsharpFileDiagram::CsharpFileDiagram( + std::shared_ptr db_, + std::shared_ptr datadir_, + const cc::webserver::ServerContext& context_) + : _db(db_), + _transaction(db_), + _projectHandler(db_, datadir_, context_) +{ +} + +void CsharpFileDiagram::getComponentUsersDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + decorateNode(graph_, currentNode, centerNodeDecoration); + + std::set provides = util::bfsBuild(graph_, currentNode, + std::bind(&CsharpFileDiagram::getProvides, this, std::placeholders::_1, + std::placeholders::_2), {}, providesEdgeDecoration, 1); + + std::set usedHeaders = provides; + for (const util::Graph::Node& provide : provides) + { + std::set revusages = util::bfsBuild(graph_, provide, + std::bind(&CsharpFileDiagram::getRevUsages, this, std::placeholders::_1, + std::placeholders::_2), {}, revUsagesEdgeDecoration); + + for (const util::Graph::Node& revusage : revusages) + usedHeaders.insert(revusage); + } + + for (const util::Graph::Node& source : usedHeaders) + util::bfsBuild(graph_, source, std::bind(&CsharpFileDiagram::getRevContains, + this, std::placeholders::_1, std::placeholders::_2), + {}, revContainsEdgeDecoration); +} + +std::string CsharpFileDiagram::getComponentUsersDiagramLegend() +{ + util::LegendBuilder builder("Component Users Diagram"); + + builder.addNode("center file", centerNodeDecoration); + builder.addNode("directory", directoryNodeDecoration); + builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("source file", sourceFileNodeDecoration); + builder.addNode("header file", headerFileNodeDecoration); + builder.addNode("object file", objectFileNodeDecoration); + + builder.addEdge("provides", providesEdgeDecoration); + builder.addEdge("used by files", revUsagesEdgeDecoration); + builder.addEdge("contained by", revContainsEdgeDecoration); + + return builder.getOutput(); +} + +void CsharpFileDiagram::getIncludeDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + + util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getUsages, + this, std::placeholders::_1, std::placeholders::_2), + {}, usagesEdgeDecoration, 3); + + util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getRevUsages, + this, std::placeholders::_1, std::placeholders::_2), + {}, revUsagesEdgeDecoration, 3); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, + this, std::placeholders::_1, std::placeholders::_2), + {}, usagesEdgeDecoration, 3); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevProvides, + this, std::placeholders::_1, std::placeholders::_2), + {}, revUsagesEdgeDecoration, 3); +} + +std::string CsharpFileDiagram::getIncludeDependencyDiagramLegend() +{ + util::LegendBuilder builder("Include Dependency Diagram"); + + builder.addNode("center file", centerNodeDecoration); + builder.addNode("directory", directoryNodeDecoration); + builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("source file", sourceFileNodeDecoration); + builder.addNode("header file", headerFileNodeDecoration); + builder.addNode("object file", objectFileNodeDecoration); + + builder.addEdge("uses", usagesEdgeDecoration); + builder.addEdge("used by files", revUsagesEdgeDecoration); + + return builder.getOutput(); +} + +void CsharpFileDiagram::getExternalDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + decorateNode(graph_, currentNode, centerNodeDecoration); + + std::set subdirs = util::bfsBuild(graph_, currentNode, + std::bind(&CsharpFileDiagram::getSubDirs, this, std::placeholders::_1, + std::placeholders::_2), {}, subdirEdgeDecoration); + + subdirs.insert(currentNode); + + for (const util::Graph::Node& subdir : subdirs) + { + for (const util::Graph::Node& impl : getImplements(graph_, subdir)) + if (subdirs.find(impl) == subdirs.end()) + { + util::Graph::Edge edge = graph_.createEdge(subdir, impl); + decorateEdge(graph_, edge, implementsEdgeDecoration); + } + + for (const util::Graph::Node& dep : getDepends(graph_, subdir)) + if (subdirs.find(dep) == subdirs.end()) + { + util::Graph::Edge edge = graph_.createEdge(subdir, dep); + decorateEdge(graph_, edge, dependsEdgeDecoration); + } + } +} + +std::string CsharpFileDiagram::getExternalDependencyDiagramLegend() +{ + util::LegendBuilder builder("External Dependency Diagram"); + + builder.addNode("center file", centerNodeDecoration); + builder.addNode("directory", directoryNodeDecoration); + builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("source file", sourceFileNodeDecoration); + builder.addNode("header file", headerFileNodeDecoration); + builder.addNode("object file", objectFileNodeDecoration); + + builder.addEdge("sub directory", subdirEdgeDecoration); + builder.addEdge("implements", implementsEdgeDecoration); + builder.addEdge("depends on", dependsEdgeDecoration); + + return builder.getOutput(); +} + +void CsharpFileDiagram::getExternalUsersDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + decorateNode(graph_, currentNode, centerNodeDecoration); + + std::set subdirs = util::bfsBuild(graph_, currentNode, + std::bind(&CsharpFileDiagram::getSubDirs, this, std::placeholders::_1, + std::placeholders::_2), {}, subdirEdgeDecoration); + + for (const util::Graph::Node& subdir : subdirs) + { + util::bfsBuild(graph_, subdir,std::bind(&CsharpFileDiagram::getRevImplements, + this, std::placeholders::_1, std::placeholders::_2), + {}, revImplementsEdgeDecoration); + + util::bfsBuild(graph_, subdir,std::bind(&CsharpFileDiagram::getRevDepends, + this, std::placeholders::_1, std::placeholders::_2), + {}, revDependsEdgeDecoration); + } +} + +std::string CsharpFileDiagram::getExternalUsersDiagramLegend() +{ + util::LegendBuilder builder("External Users Diagram"); + + builder.addNode("center file", centerNodeDecoration); + builder.addNode("directory", directoryNodeDecoration); + builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("source file", sourceFileNodeDecoration); + builder.addNode("header file", headerFileNodeDecoration); + builder.addNode("object file", objectFileNodeDecoration); + + builder.addEdge("sub directory", subdirEdgeDecoration); + builder.addEdge("implemented by", revImplementsEdgeDecoration); + builder.addEdge("dependent on", revDependsEdgeDecoration); + + return builder.getOutput(); +} + +void CsharpFileDiagram::getInterfaceDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, + this, std::placeholders::_1, std::placeholders::_2), + {}, providesEdgeDecoration, 1); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getContains, + this, std::placeholders::_1, std::placeholders::_2), + {}, containsEdgeDecoration, 1); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getUsages, + this, std::placeholders::_1, std::placeholders::_2), + {}, usagesEdgeDecoration, 1); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevProvides, + this, std::placeholders::_1, std::placeholders::_2), + {}, revProvidesEdgeDecoration, 1); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevContains, + this, std::placeholders::_1, std::placeholders::_2), + {}, revContainsEdgeDecoration, 1); + + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevUsages, + this, std::placeholders::_1, std::placeholders::_2), + {}, revUsagesEdgeDecoration, 1); +} + +std::string CsharpFileDiagram::getInterfaceDiagramLegend() +{ + util::LegendBuilder builder("Interface Diagram"); + + builder.addNode("center file", centerNodeDecoration); + builder.addNode("directory", directoryNodeDecoration); + builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("source file", sourceFileNodeDecoration); + builder.addNode("header file", headerFileNodeDecoration); + builder.addNode("object file", objectFileNodeDecoration); + + builder.addEdge("provides", providesEdgeDecoration); + builder.addEdge("contains", containsEdgeDecoration); + builder.addEdge("uses", usagesEdgeDecoration); + builder.addEdge("provided by", revProvidesEdgeDecoration); + builder.addEdge("contained by", revContainsEdgeDecoration); + builder.addEdge("used by", revUsagesEdgeDecoration); + + return builder.getOutput(); +} + +void CsharpFileDiagram::getSubsystemDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + decorateNode(graph_, currentNode, centerNodeDecoration); + + std::set subdirs = util::bfsBuild(graph_, currentNode, + std::bind(&CsharpFileDiagram::getSubDirs, this, std::placeholders::_1, + std::placeholders::_2), {}, subdirEdgeDecoration); + + subdirs.insert(currentNode); + + for (const util::Graph::Node& subdir : subdirs) + { + for (const util::Graph::Node& impl : getImplements(graph_, subdir)) + if (subdirs.find(impl) != subdirs.end()) + { + util::Graph::Edge edge = graph_.createEdge(subdir, impl); + decorateEdge(graph_, edge, implementsEdgeDecoration); + } + else + graph_.delNode(impl); + + for (const util::Graph::Node& dep : getDepends(graph_, subdir)) + if (subdirs.find(dep) != subdirs.end()) + { + util::Graph::Edge edge = graph_.createEdge(subdir, dep); + decorateEdge(graph_, edge, dependsEdgeDecoration); + } + else + graph_.delNode(dep); + } +} + +std::string CsharpFileDiagram::getSubsystemDependencyDiagramLegend() +{ + util::LegendBuilder builder("Subsystem Dependency Diagram"); + + builder.addNode("center file", centerNodeDecoration); + builder.addNode("directory", directoryNodeDecoration); + builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("source file", sourceFileNodeDecoration); + builder.addNode("header file", headerFileNodeDecoration); + builder.addNode("object file", objectFileNodeDecoration); + + builder.addEdge("sub directory", subdirEdgeDecoration); + builder.addEdge("implements", implementsEdgeDecoration); + builder.addEdge("depends on", dependsEdgeDecoration); + + return builder.getOutput(); +} +/* +std::vector FileDiagram::getIncludedFiles( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector include; + + _transaction([&, this]{ + IncludeResult res = _db->query( + (reverse_ + ? IncludeQuery::included->id + : IncludeQuery::includer->id) == std::stoull(node_)); + + for (const auto& inclusion : res) + { + model::FileId fileId = reverse_ + ? inclusion.includer.object_id() + : inclusion.included.object_id(); + + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, std::to_string(fileId)); + include.push_back(addNode(graph_, fileInfo)); + } + }); + + return include; +} +*/ +std::vector CsharpFileDiagram::getIncludes( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getIncludedFiles(graph_, node_); +} + +std::vector CsharpFileDiagram::getRevIncludes( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getIncludedFiles(graph_, node_, true); +} +/* +std::vector FileDiagram::getSubDirs( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + std::vector usages; + + _transaction([&, this]{ + FileResult sub = _db->query( + FileQuery::parent == std::stoull(node_) && + FileQuery::type == model::File::DIRECTORY_TYPE); + + for (const model::File& subdir : sub) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, std::to_string(subdir.id)); + + usages.push_back(addNode(graph_, fileInfo)); + } + }); + + return usages; +} +*/ +std::vector CsharpFileDiagram::getImplements( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getImplementedFiles(graph_, node_); +} + +std::vector CsharpFileDiagram::getRevImplements( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getImplementedFiles(graph_, node_, true); +} +/* +std::vector FileDiagram::getImplementedFiles( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector implements; + _transaction([&, this] + { + auto contained = _db->query( + odb::query::parent == std::stoull(node_) && + odb::query::type != model::File::DIRECTORY_TYPE + ); + std::unordered_set used; + + for (const model::File &file : contained) + { + auto files = getProvidedFileIds(graph_, std::to_string(file.id), reverse_); + used.insert(files.begin(), files.end()); + } + for (const core::FileId& fileId : used) + { + auto file = _db->load(std::stoull(fileId)); + implements.push_back(std::to_string(file.get()->parent.object_id())); + } + std::sort(implements.begin(), implements.end()); + auto it = std::unique(implements.begin(), implements.end()); + implements.resize(it - implements.begin()); + implements.erase(std::remove_if(implements.begin(), implements.end(), + [&node_](const util::Graph::Node& n){ return node_ == n; }), + implements.end()); + }); + + std::vector annotated; + + for (const core::FileId& fileId : implements) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + annotated.push_back(addNode(graph_, fileInfo)); + } + return annotated; +} +*/ +std::vector CsharpFileDiagram::getDepends( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getDependFiles(graph_, node_); +} + +std::vector CsharpFileDiagram::getRevDepends( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getDependFiles(graph_, node_, true); +} +/* +std::vector FileDiagram::getDependFiles( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector depends; + + _transaction([&, this]{ + auto contained = _db->query( + odb::query::parent == std::stoull(node_) && + odb::query::type != model::File::DIRECTORY_TYPE + ); + + std::unordered_set used; + + for(const model::File& file : contained) + { + auto files = getUsedFileIds(graph_, std::to_string(file.id), reverse_); + used.insert(files.begin(), files.end()); + } + + for(const core::FileId& fileId : used) + { + auto files =_db->query( + odb::query::id == std::stoull(fileId) + ); + + for(const model::File& file : files) + { + depends.push_back(std::to_string(file.parent.object_id())); + } + } + + std::sort(depends.begin(), depends.end()); + auto it = std::unique(depends.begin(), depends.end()); + depends.resize(it - depends.begin()); + depends.erase(std::remove_if(depends.begin(), depends.end(), + [&node_](const util::Graph::Node& n){ return node_ == n; }), + depends.end()); + }); + + std::vector annotated; + + for (const core::FileId& fileId: depends) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + annotated.push_back(addNode(graph_, fileInfo)); + } + return annotated; +} +*/ +std::vector CsharpFileDiagram::getProvides( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getProvidedFiles(graph_, node_); +} + +std::vector CsharpFileDiagram::getRevProvides( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getProvidedFiles(graph_, node_, true); +} + +std::vector CsharpFileDiagram::getProvidedFiles( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector depends; + + std::vector fileIds = getProvidedFileIds(graph_, node_, reverse_); + + for (const core::FileId& fileId : fileIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + depends.push_back(addNode(graph_, fileInfo)); + } + + return depends; +} +/* +std::vector FileDiagram::getProvidedFileIds( + util::Graph&, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector depends; + + _transaction([&, this]{ + EdgeResult res = _db->query( + (reverse_ + ? EdgeQuery::to->id + : EdgeQuery::from->id) == std::stoull(node_) && + EdgeQuery::type == model::CppEdge::PROVIDE); + + for (const model::CppEdge& edge : res) + { + core::FileId fileId = reverse_ ? std::to_string(edge.from->id) : std::to_string(edge.to->id); + depends.push_back(fileId); + } + }); + + return depends; +} + +std::vector FileDiagram::getContains( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + std::vector contained; + + _transaction([&, this]{ + TargetResult targets = _db->query( + TargetQuery::file == std::stoull(node_)); + + for (const model::BuildTarget& target : targets) + for (const auto& source : target.action->sources) + { + model::FileId fileId = source.lock().load()->file->id; + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, std::to_string(fileId)); + contained.push_back(addNode(graph_, fileInfo)); + } + }); + + return contained; +} + +std::vector FileDiagram::getRevContains( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + std::vector contained; + std::set files; + + _transaction([&, this]{ + SourceResult sources = _db->query( + SourceQuery::file == std::stoull(node_)); + for (const model::BuildSource& source : sources) + for (const auto& target : source.action->targets) + { + model::FileId fileId = target.lock().load()->file->id; + + if (!files.insert(fileId).second) + continue; + + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, std::to_string(fileId)); + contained.push_back(addNode(graph_, fileInfo)); + } + }); + + return contained; +} +*/ +std::vector CsharpFileDiagram::getUsages( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getUsedFiles(graph_, node_); +} + +std::vector CsharpFileDiagram::getRevUsages( + util::Graph& graph_, + const util::Graph::Node& node_) +{ + return getUsedFiles(graph_, node_, true); +} + +std::vector CsharpFileDiagram::getUsedFiles( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector usages; + + std::vector fileIds = getUsedFileIds(graph_, node_, reverse_); + + for (const core::FileId& fileId: fileIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + usages.push_back(addNode(graph_, fileInfo)); + } + + return usages; +} + +/*std::vector FileDiagram::getUsedFileIds( + util::Graph&, + const util::Graph::Node& node_, + bool reverse_) +{ + std::vector usages; + + _transaction([&, this]{ + EdgeResult res = _db->query( + (reverse_ + ? EdgeQuery::to->id + : EdgeQuery::from->id) == std::stoull(node_) && + EdgeQuery::type == model::CppEdge::USE); + + for (const model::CppEdge& edge : res) + { + core::FileId fileId = reverse_ ? std::to_string(edge.from->id) : std::to_string(edge.to->id); + + usages.push_back(fileId); + } + }); + + return usages; +} +*/ +util::Graph::Node CsharpFileDiagram::addNode( + util::Graph& graph_, + const core::FileInfo& fileInfo_) +{ + util::Graph::Node node = graph_.getOrCreateNode(fileInfo_.id); + graph_.setNodeAttribute(node, "label", getLastNParts(fileInfo_.path, 3)); + + if (fileInfo_.type == model::File::DIRECTORY_TYPE) + { + decorateNode(graph_, node, directoryNodeDecoration); + } + else if (fileInfo_.type == model::File::BINARY_TYPE) + { + decorateNode(graph_, node, binaryFileNodeDecoration); + } + else if (fileInfo_.type == "CPP") + { + std::string ext = boost::filesystem::extension(fileInfo_.path); + std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); + + if (ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".c") + decorateNode(graph_, node, sourceFileNodeDecoration); + else if (ext == ".hpp" || ext == ".hxx" || ext == ".hh" || ext == ".h") + decorateNode(graph_, node, headerFileNodeDecoration); + else if (ext == ".o" || ext == ".so" || ext == ".dll") + decorateNode(graph_, node, objectFileNodeDecoration); + } + + return node; +} + +void CsharpFileDiagram::decorateNode( + util::Graph& graph_, + const util::Graph::Node& node_, + const Decoration& decoration_) const +{ + for (const auto& attr : decoration_) + graph_.setNodeAttribute(node_, attr.first, attr.second); +} + +void CsharpFileDiagram::decorateEdge( + util::Graph& graph_, + const util::Graph::Edge& edge_, + const Decoration& decoration_) const +{ + for (const auto& attr : decoration_) + graph_.setEdgeAttribute(edge_, attr.first, attr.second); +} + +std::string CsharpFileDiagram::getLastNParts(const std::string& path_, std::size_t n_) +{ + if (path_.empty() || n_ == 0) + return ""; + + std::size_t p; + for (p = path_.rfind('/'); + --n_ > 0 && p - 1 < path_.size(); + p = path_.rfind('/', p - 1)); + + return p > 0 && p < path_.size() ? "..." + path_.substr(p) : path_; +} + +const CsharpFileDiagram::Decoration CsharpFileDiagram::centerNodeDecoration = { + {"style", "filled"}, + {"fillcolor", "gold"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::sourceFileNodeDecoration = { + {"shape", "box"}, + {"style", "filled"}, + {"fillcolor", "#116db6"}, + {"fontcolor", "white"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::headerFileNodeDecoration = { + {"style", "filled"}, + {"fillcolor", "#ef4756"}, + {"fontcolor", "white"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::binaryFileNodeDecoration = { + {"shape", "box3d"}, + {"style", "filled"}, + {"fillcolor", "#f18a21"}, + {"fontcolor", "white"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::objectFileNodeDecoration = { + {"shape", "folder"}, + {"style", "filled"}, + {"fillcolor", "#6fc59e"}, + {"fontcolor", "white"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::directoryNodeDecoration = { + {"shape", "folder"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::usagesEdgeDecoration = { + {"label", "uses"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::revUsagesEdgeDecoration = { + {"label", "used by"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::providesEdgeDecoration = { + {"label", "provides"}, + {"color", "red"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::revProvidesEdgeDecoration = { + {"label", "provided by"}, + {"color", "red"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::containsEdgeDecoration = { + {"label", "contains"}, + {"color", "blue"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::revContainsEdgeDecoration = { + {"label", "contained by"}, + {"color", "blue"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::subdirEdgeDecoration = { + {"label", "subdir"}, + {"color", "green"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::implementsEdgeDecoration = { + {"label", "implements"}, + {"color", "red"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::revImplementsEdgeDecoration = { + {"label", "implemented by"}, + {"color", "red"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::dependsEdgeDecoration = { + {"label", "depends on"}, + {"color", "blue"} +}; + +const CsharpFileDiagram::Decoration CsharpFileDiagram::revDependsEdgeDecoration = { + {"label", "dependent on"}, + {"color", "blue"} +}; + +void CsharpFileDiagram::getTestDiagram( + util::Graph& graph_, + const core::FileId& fileId_) +{ + core::FileInfo fileInfo; + CsharpFileDiagram::_projectHandler.getFileInfo(fileInfo, fileId_); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + decorateNode(graph_, currentNode, centerNodeDecoration); +} + +} // language +} // service +} // cc \ No newline at end of file diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h new file mode 100644 index 000000000..a0aaec3b2 --- /dev/null +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -0,0 +1,408 @@ +#ifndef CC_SERVICE_LANGUAGE_CSHARPFILEDIAGRAM_H +#define CC_SERVICE_LANGUAGE_CSHARPFILEDIAGRAM_H + +//copied + +#include +#include +#include + +namespace cc +{ +namespace service +{ +namespace language +{ + +//namespace language = cc::service::language; + +class CsharpFileDiagram +{ +public: + CsharpFileDiagram( + std::shared_ptr db_, + std::shared_ptr datadir_, + const cc::webserver::ServerContext& context_); + + /** + * This diagram shows the module which directory depends on. The "depends on" + * diagram on module A traverses the subdirectories of module A and shows all + * directories that contain files that any of the source files in A includes. + */ + void getExternalDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates legend for the External dependency diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getExternalDependencyDiagramLegend(); + + /** + * This diagram shows directories (modules) that are users of the + * queried module. + */ + void getExternalUsersDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates legend for the External users diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getExternalUsersDiagramLegend(); + + /** + * This diagram shows of the `#include` file dependencies. + */ + void getIncludeDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates legend for the Include dependency diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getIncludeDependencyDiagramLegend(); + + /** + * Interface diagram shows the used and provided interfaces of a source code + * file and shows linking information. + */ + void getInterfaceDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates legend for the Interface diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getInterfaceDiagramLegend(); + + /** + * This diagram shows the directories relationship between the subdirectories + * of the queried module. This diagram is useful to understand the + * relationships of the subdirectories (submodules) of a module. + */ + void getSubsystemDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates legend for the Subsystem dependency diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getSubsystemDependencyDiagramLegend(); + + /** + * Component users diagram for source file S shows which source files depend + * on S through the interfaces S provides. + */ + void getComponentUsersDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates legend for the Component users diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getComponentUsersDiagramLegend(); + + void getTestDiagram( + util::Graph& graph_, + const core::FileId& fileId_); + +private: + typedef std::vector> Decoration; + + /** + * This function adds a node which represents a File node. The label of the + * node is the file name. + */ + util::Graph::Node addNode( + util::Graph& graph_, + const core::FileInfo& fileInfo_); + + /** + * This function decorates a graph node. + * @param graph_ A graph object. + * @param elem_ A graph node + * @param decoration_ A map which describes the style attributes. + */ + void decorateNode( + util::Graph& graph_, + const util::Graph::Node& node_, + const Decoration& decoration_) const; + + /** + * This function decorates a graph edge. + * @param graph_ A graph object. + * @param elem_ A graph edge + * @param decoration_ A map which describes the style attributes. + */ + void decorateEdge( + util::Graph& graph_, + const util::Graph::Edge& edge_, + const Decoration& decoration_) const; + + /** + * Returns the last `n` parts of the path with a '...' if the part size is + * larger than `n`. + * (E.g.: path = `/a/b/c/d` and n = `3` then the is result = .../b/c/d) + */ + std::string getLastNParts(const std::string& path_, std::size_t n_); + + /** + * This function creates graph nodes for each files which the given one + * includes. + * @see getIncludedFiles() + */ + std::vector getIncludes( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each files which includes the given + * file. + * @note This function is the revert version of the getIncludes function. + * @see getIncludedFiles() + */ + std::vector getRevIncludes( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function returns the graph nodes which the given file includes. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @param reverse_ If true then it creates graph nodes for each file which + * includes the given file. + * @return Created graph nodes. + */ + std::vector getIncludedFiles( + util::Graph& graph_, + const util::Graph::Node& fileNode_, + bool reverse_ = false); + + /** + * This function creates graph nodes for sub directories of the actual file + * node and returns the created graph nodes. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @return Subdirectory graph nodes. + */ + std::vector getSubDirs( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each files which files implements + * the given one. + * @see getImplementedFiles() + */ + std::vector getImplements( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each files which implements the given + * file. + * @note This function is the revert version of the getImplements function. + * @see getImplementedFiles() + */ + std::vector getRevImplements( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each files which implements the + * given file. + * @note `A` implements `B` if a function which is defined in `A` declared + * in `B`. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @param reverse_ If true then it creates graph nodes for each file which + * implements the given file. + * @return Created graph nodes. + */ + std::vector getImplementedFiles( + util::Graph& graph_, + const util::Graph::Node& fileNode_, + bool reverse_ = false); + + /** + * This function returns graph nodes which the given file depends on. + * @see getDependFiles() + */ + std::vector getDepends( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function returns graph nodes which depends from the given file. + * @note This function is the revert version of the getImplements function. + * @see getDependFiles() + */ + std::vector getRevDepends( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function returns graph nodes which the given file depends on. + * @note File `A` depends on file `B` if: + * - `A` has a value declaration which type is a record type which was + * declared in `B`. + * E.g.: In file A `T x;` is a value declaration and T is a record type + * which was declared in file `B` then `A` depends on `B`. + * - `A` has a function call which declaration is located in file `B`. + * E.g.: In file A `f()` is a function call which function was declared + * in file `B` then `A` depends on `B`. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @param reverse_ If true then it creates graph nodes for each file which + * depends the given file. + * @return Created graph nodes. + */ + std::vector getDependFiles( + util::Graph& graph_, + const util::Graph::Node& fileNode_, + bool reverse_ = false); + + /** + * This function creates graph nodes for each files which files provides + * the given one. + * @see getProvidedFiles() + */ + std::vector getProvides( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each files which provides the given + * file. + * @note This function is the revert version of the getProvides function. + * @see getProvidedFiles() + */ + std::vector getRevProvides( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each files which provides the + * given file. + * `A` provides `B` if a function which is defined in `A` , declared in `B` + * and `A` is not the same as `B`. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @param reverse_ If true then it creates graph nodes for each file which + * provides the given file. + * @return Created graph nodes. + */ + std::vector getProvidedFiles( + util::Graph& graph_, + const util::Graph::Node& fileNode_, + bool reverse_ = false); + + std::vector getProvidedFileIds( + util::Graph& graph_, + const util::Graph::Node& fileNode_, + bool reverse_ = false); + + /** + * This function creates graph nodes for each build sources which related to + * the given build target. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @return Created graph nodes. + */ + std::vector getContains( + util::Graph& graph_, + const util::Graph::Node& fileNode_); + + /** + * This function creates graph nodes for each build targets which related to + * the given build source. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @return Created graph nodes. + */ + std::vector getRevContains( + util::Graph& graph_, + const util::Graph::Node& node_); + + /** + * This function creates graph nodes for each files which files use the + * given one. + * @see getUsedFiles() + */ + std::vector getUsages( + util::Graph& graph_, + const util::Graph::Node& node_); + + /** + * This function creates graph nodes for each files which use the given file. + * @note This function is the revert version of the getUsages function. + * @see getUsedFiles() + */ + std::vector getRevUsages( + util::Graph& graph_, + const util::Graph::Node& node_); + + /** + * This function returns graph nodes which the given file depends on. + * @note File `A` use file `B` (A<>B) if: + * - `A` has a value declaration which type is a record type which was + * declared in `B`. + * E.g.: In file A `T x;` is a value declaration and T is a record type + * which was declared in file `B` then `A` use `B`. + * - `A` has a function call which declaration is located in file `B`. + * E.g.: In file A `f()` is a function call which function was declared + * in file `B` then `A` use `B`. + * @param graph_ A graph object. + * @param fileNode_ Graph file node object which represents a file object. + * @param reverse_ If true then it creates graph nodes for each file which + * use the given file. + * @return Created graph nodes. + */ + std::vector getUsedFiles( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_ = false); + + std::vector getUsedFileIds( + util::Graph& graph_, + const util::Graph::Node& node_, + bool reverse_); + + static const Decoration centerNodeDecoration; + static const Decoration sourceFileNodeDecoration; + static const Decoration headerFileNodeDecoration; + static const Decoration binaryFileNodeDecoration; + static const Decoration objectFileNodeDecoration; + static const Decoration directoryNodeDecoration; + + static const Decoration usagesEdgeDecoration; + static const Decoration revUsagesEdgeDecoration; + static const Decoration providesEdgeDecoration; + static const Decoration revProvidesEdgeDecoration; + static const Decoration containsEdgeDecoration; + static const Decoration revContainsEdgeDecoration; + static const Decoration subdirEdgeDecoration; + static const Decoration implementsEdgeDecoration; + static const Decoration revImplementsEdgeDecoration; + static const Decoration dependsEdgeDecoration; + static const Decoration revDependsEdgeDecoration; + + std::shared_ptr _db; + util::OdbTransaction _transaction; + //CppServiceHandler _cppHandler; + cc::service::csharp::CSharpQueryHandler _csharpQueryHandler; + core::ProjectServiceHandler _projectHandler; +}; + +} // language +} // service +} // cc + +#endif // CC_SERVICE_LANGUAGE_FILEDIAGRAM_H diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 7d44b417d..66422cd46 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -4,6 +4,8 @@ #include #include +#include "csharpfilediagram.h" + namespace cc { namespace service @@ -134,7 +136,7 @@ void CsharpServiceHandler::getDiagramTypes( const core::AstNodeId& astNodeId_) { LOG(info) << "getDiagramTypes"; - //csharpQueryHandler.getDiagramTypes(return_, astNodeId_); + //_csharpQueryHandler.getDiagramTypes(return_, astNodeId_); } void CsharpServiceHandler::getDiagram( @@ -143,7 +145,7 @@ void CsharpServiceHandler::getDiagram( const std::int32_t diagramId_) { LOG(info) << "getDiagram"; - //csharpQueryHandler.getDiagram(return_, astNodeId_, diagramId_); + //_csharpQueryHandler.getDiagram(return_, astNodeId_, diagramId_); } void CsharpServiceHandler::getDiagramLegend( @@ -158,6 +160,7 @@ void CsharpServiceHandler::getFileDiagramTypes( const core::FileId& fileId_) { LOG(info) << "getFileDiagramTypes"; + _csharpQueryHandler.getFileDiagramTypes(return_, fileId_); //most irtam } void CsharpServiceHandler::getFileDiagram( @@ -166,6 +169,19 @@ void CsharpServiceHandler::getFileDiagram( const int32_t diagramId_) { LOG(info) << "getFileDiagram"; + + CsharpFileDiagram diagram(_db,_datadir, _context); + util::Graph graph; + graph.setAttribute("rankdir", "LR"); + + switch (diagramId_){ + case 999: + diagram.getTestDiagram(graph, fileId_); + break; + } + + if (graph.nodeCount() != 0) + return_ = graph.output(util::Graph::SVG); } void CsharpServiceHandler::getFileDiagramLegend( @@ -288,7 +304,7 @@ void CsharpServiceHandler::getSyntaxHighlight( while (std::getline(s, line)) content.push_back(line); }); - csharpQueryHandler.getSyntaxHighlight(return_, range_, content); + _csharpQueryHandler.getSyntaxHighlight(return_, range_, content); */ } diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 0a422de3e..909d6707e 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -680,5 +680,33 @@ public async Task getDiagramAsync(string astNodeId, int diagramId, return await Task.FromResult(new List()); } + public async Task> getFileDiagramTypesAsync(string fileId, + CancellationToken cancellationToken = default(CancellationToken)) + { + return await Task.FromResult(new Dictionary(){ + {"TEST DIAGRAM", 999} + }); + } + + public async Task getFileDiagramAsync(string fileId, int diagramId, + CancellationToken cancellationToken = default(CancellationToken)) + { + /*switch (diagramId) + { + case 999: + string parent = dbContext.File + .Where(a => (a.id).ToString() == fileId) + .Select(a => a.parent) + .ToString(); + string parentInfo = dbContext.File + .Where(a => parent == a.id.ToString()) + .ToString(); + + return await Task.FromResult(parentInfo); + break; + } + */ + return await Task.FromResult("File Diagram"); + } } \ No newline at end of file diff --git a/plugins/csharp/service/src_csharp/csharpservice.csproj b/plugins/csharp/service/src_csharp/csharpservice.csproj index c40923804..b8525551d 100644 --- a/plugins/csharp/service/src_csharp/csharpservice.csproj +++ b/plugins/csharp/service/src_csharp/csharpservice.csproj @@ -12,6 +12,7 @@ + diff --git a/plugins/csharp/webgui/js/csharpDiagram.js b/plugins/csharp/webgui/js/csharpDiagram.js index 32b3c7caf..69915e9eb 100644 --- a/plugins/csharp/webgui/js/csharpDiagram.js +++ b/plugins/csharp/webgui/js/csharpDiagram.js @@ -87,7 +87,7 @@ function (topic, Menu, MenuItem, PopupMenuItem, model, viewHandler) { if (Object.keys(diagramTypes).length !== 0) return new PopupMenuItem({ - label : 'C++ Diagrams', + label : 'C# Diagrams', popup : submenu }); } From 0d6719673e5ad1d0a46c2dab8ccc98d929a302cd Mon Sep 17 00:00:00 2001 From: intjftw Date: Thu, 16 Mar 2023 17:45:52 +0100 Subject: [PATCH 02/49] Added new CPP files to CMake. --- plugins/csharp/service/CMakeLists.txt | 1 + plugins/csharp/service/src/csharpfilediagram.cpp | 3 +++ plugins/csharp/service/src/csharpservice.cpp | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/service/CMakeLists.txt b/plugins/csharp/service/CMakeLists.txt index cfc163255..d0e43b80a 100644 --- a/plugins/csharp/service/CMakeLists.txt +++ b/plugins/csharp/service/CMakeLists.txt @@ -39,6 +39,7 @@ add_subdirectory(src_csharp) add_library(csharpservice SHARED src/csharpservice.cpp + src/csharpfilediagram.cpp src/plugin.cpp) target_compile_options(csharpservice PUBLIC -Wno-unknown-pragmas) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index b5f571f40..9332f4e22 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -6,6 +6,9 @@ #include #include +#include +#include + #include "csharpfilediagram.h" diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 66422cd46..a97923e36 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -176,7 +176,7 @@ void CsharpServiceHandler::getFileDiagram( switch (diagramId_){ case 999: - diagram.getTestDiagram(graph, fileId_); + //diagram.getTestDiagram(graph, fileId_); break; } From d0301ea69231a93c967763fbf9b90ea3d687b8f1 Mon Sep 17 00:00:00 2001 From: intjftw Date: Thu, 16 Mar 2023 17:45:52 +0100 Subject: [PATCH 03/49] Added new CPP files to CMake. --- plugins/csharp/service/CMakeLists.txt | 1 + .../csharp/service/src/csharpfilediagram.cpp | 37 ++-- .../csharp/service/src/csharpfilediagram.h | 182 +++++++++--------- 3 files changed, 117 insertions(+), 103 deletions(-) diff --git a/plugins/csharp/service/CMakeLists.txt b/plugins/csharp/service/CMakeLists.txt index cfc163255..d0e43b80a 100644 --- a/plugins/csharp/service/CMakeLists.txt +++ b/plugins/csharp/service/CMakeLists.txt @@ -39,6 +39,7 @@ add_subdirectory(src_csharp) add_library(csharpservice SHARED src/csharpservice.cpp + src/csharpfilediagram.cpp src/plugin.cpp) target_compile_options(csharpservice PUBLIC -Wno-unknown-pragmas) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index b5f571f40..1f1f18bb6 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -6,6 +6,9 @@ #include #include +#include +#include + #include "csharpfilediagram.h" @@ -38,7 +41,7 @@ CsharpFileDiagram::CsharpFileDiagram( _projectHandler(db_, datadir_, context_) { } - +/* void CsharpFileDiagram::getComponentUsersDiagram( util::Graph& graph_, const core::FileId& fileId_) @@ -331,7 +334,7 @@ std::string CsharpFileDiagram::getSubsystemDependencyDiagramLegend() return builder.getOutput(); } -/* + std::vector FileDiagram::getIncludedFiles( util::Graph& graph_, const util::Graph::Node& node_, @@ -359,7 +362,7 @@ std::vector FileDiagram::getIncludedFiles( return include; } -*/ + std::vector CsharpFileDiagram::getIncludes( util::Graph& graph_, const util::Graph::Node& node_) @@ -373,7 +376,7 @@ std::vector CsharpFileDiagram::getRevIncludes( { return getIncludedFiles(graph_, node_, true); } -/* + std::vector FileDiagram::getSubDirs( util::Graph& graph_, const util::Graph::Node& node_) @@ -396,7 +399,7 @@ std::vector FileDiagram::getSubDirs( return usages; } -*/ + std::vector CsharpFileDiagram::getImplements( util::Graph& graph_, const util::Graph::Node& node_) @@ -410,7 +413,7 @@ std::vector CsharpFileDiagram::getRevImplements( { return getImplementedFiles(graph_, node_, true); } -/* + std::vector FileDiagram::getImplementedFiles( util::Graph& graph_, const util::Graph::Node& node_, @@ -454,7 +457,7 @@ std::vector FileDiagram::getImplementedFiles( } return annotated; } -*/ + std::vector CsharpFileDiagram::getDepends( util::Graph& graph_, const util::Graph::Node& node_) @@ -468,7 +471,7 @@ std::vector CsharpFileDiagram::getRevDepends( { return getDependFiles(graph_, node_, true); } -/* + std::vector FileDiagram::getDependFiles( util::Graph& graph_, const util::Graph::Node& node_, @@ -521,7 +524,7 @@ std::vector FileDiagram::getDependFiles( } return annotated; } -*/ + std::vector CsharpFileDiagram::getProvides( util::Graph& graph_, const util::Graph::Node& node_) @@ -555,7 +558,7 @@ std::vector CsharpFileDiagram::getProvidedFiles( return depends; } -/* + std::vector FileDiagram::getProvidedFileIds( util::Graph&, const util::Graph::Node& node_, @@ -629,7 +632,7 @@ std::vector FileDiagram::getRevContains( return contained; } -*/ + std::vector CsharpFileDiagram::getUsages( util::Graph& graph_, const util::Graph::Node& node_) @@ -847,7 +850,17 @@ void CsharpFileDiagram::getTestDiagram( core::FileInfo fileInfo; CsharpFileDiagram::_projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); - decorateNode(graph_, currentNode, centerNodeDecoration); + decorateNode(graph_, currentNode, sourceFileNodeDecoration); + + core::FileInfo parentInfo; + CsharpFileDiagram::_projectHandler.getFileInfo(parentInfo,fileInfo.parent); + util::Graph::Node nextNode = addNode(graph_, parentInfo); + decorateNode(graph_, nextNode, directoryNodeDecoration); + + util::Graph::Edge edge = graph_.createEdge(nextNode, currentNode); + decorateEdge(graph_, edge, containsEdgeDecoration); + + } } // language diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index a0aaec3b2..ac67f88d3 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -23,92 +23,92 @@ class CsharpFileDiagram std::shared_ptr db_, std::shared_ptr datadir_, const cc::webserver::ServerContext& context_); - + /** * This diagram shows the module which directory depends on. The "depends on" * diagram on module A traverses the subdirectories of module A and shows all * directories that contain files that any of the source files in A includes. */ - void getExternalDependencyDiagram( - util::Graph& graph_, - const core::FileId& fileId_); + //void getExternalDependencyDiagram( + // util::Graph& graph_, + // const core::FileId& fileId_); /** * This function creates legend for the External dependency diagram. * @return The generated legend as a string in SVG format. */ - std::string getExternalDependencyDiagramLegend(); + //std::string getExternalDependencyDiagramLegend(); /** * This diagram shows directories (modules) that are users of the * queried module. */ - void getExternalUsersDiagram( - util::Graph& graph_, - const core::FileId& fileId_); + //void getExternalUsersDiagram( + // util::Graph& graph_, + // const core::FileId& fileId_); /** * This function creates legend for the External users diagram. * @return The generated legend as a string in SVG format. */ - std::string getExternalUsersDiagramLegend(); + //std::string getExternalUsersDiagramLegend(); /** * This diagram shows of the `#include` file dependencies. */ - void getIncludeDependencyDiagram( - util::Graph& graph_, - const core::FileId& fileId_); + //void getIncludeDependencyDiagram( + // util::Graph& graph_, + // const core::FileId& fileId_); /** * This function creates legend for the Include dependency diagram. * @return The generated legend as a string in SVG format. */ - std::string getIncludeDependencyDiagramLegend(); + //std::string getIncludeDependencyDiagramLegend(); /** * Interface diagram shows the used and provided interfaces of a source code * file and shows linking information. */ - void getInterfaceDiagram( - util::Graph& graph_, - const core::FileId& fileId_); + //void getInterfaceDiagram( + // util::Graph& graph_, + // const core::FileId& fileId_); /** * This function creates legend for the Interface diagram. * @return The generated legend as a string in SVG format. */ - std::string getInterfaceDiagramLegend(); + //std::string getInterfaceDiagramLegend(); /** * This diagram shows the directories relationship between the subdirectories * of the queried module. This diagram is useful to understand the * relationships of the subdirectories (submodules) of a module. */ - void getSubsystemDependencyDiagram( - util::Graph& graph_, - const core::FileId& fileId_); + //void getSubsystemDependencyDiagram( + // util::Graph& graph_, + // const core::FileId& fileId_); /** * This function creates legend for the Subsystem dependency diagram. * @return The generated legend as a string in SVG format. */ - std::string getSubsystemDependencyDiagramLegend(); + //std::string getSubsystemDependencyDiagramLegend(); /** * Component users diagram for source file S shows which source files depend * on S through the interfaces S provides. */ - void getComponentUsersDiagram( - util::Graph& graph_, - const core::FileId& fileId_); + //void getComponentUsersDiagram( + // util::Graph& graph_, + // const core::FileId& fileId_); /** * This function creates legend for the Component users diagram. * @return The generated legend as a string in SVG format. */ - std::string getComponentUsersDiagramLegend(); - + //std::string getComponentUsersDiagramLegend(); + void getTestDiagram( util::Graph& graph_, const core::FileId& fileId_); @@ -158,9 +158,9 @@ class CsharpFileDiagram * includes. * @see getIncludedFiles() */ - std::vector getIncludes( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getIncludes( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which includes the given @@ -168,9 +168,9 @@ class CsharpFileDiagram * @note This function is the revert version of the getIncludes function. * @see getIncludedFiles() */ - std::vector getRevIncludes( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getRevIncludes( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function returns the graph nodes which the given file includes. @@ -180,11 +180,11 @@ class CsharpFileDiagram * includes the given file. * @return Created graph nodes. */ - std::vector getIncludedFiles( + /*std::vector getIncludedFiles( util::Graph& graph_, const util::Graph::Node& fileNode_, bool reverse_ = false); - + */ /** * This function creates graph nodes for sub directories of the actual file * node and returns the created graph nodes. @@ -192,18 +192,18 @@ class CsharpFileDiagram * @param fileNode_ Graph file node object which represents a file object. * @return Subdirectory graph nodes. */ - std::vector getSubDirs( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getSubDirs( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which files implements * the given one. * @see getImplementedFiles() */ - std::vector getImplements( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getImplements( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which implements the given @@ -211,9 +211,9 @@ class CsharpFileDiagram * @note This function is the revert version of the getImplements function. * @see getImplementedFiles() */ - std::vector getRevImplements( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getRevImplements( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which implements the @@ -226,27 +226,27 @@ class CsharpFileDiagram * implements the given file. * @return Created graph nodes. */ - std::vector getImplementedFiles( - util::Graph& graph_, - const util::Graph::Node& fileNode_, - bool reverse_ = false); + //std::vector getImplementedFiles( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_, + // bool reverse_ = false); /** * This function returns graph nodes which the given file depends on. * @see getDependFiles() */ - std::vector getDepends( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getDepends( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function returns graph nodes which depends from the given file. * @note This function is the revert version of the getImplements function. * @see getDependFiles() */ - std::vector getRevDepends( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getRevDepends( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function returns graph nodes which the given file depends on. @@ -264,19 +264,19 @@ class CsharpFileDiagram * depends the given file. * @return Created graph nodes. */ - std::vector getDependFiles( - util::Graph& graph_, - const util::Graph::Node& fileNode_, - bool reverse_ = false); + //std::vector getDependFiles( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_, + // bool reverse_ = false); /** * This function creates graph nodes for each files which files provides * the given one. * @see getProvidedFiles() */ - std::vector getProvides( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getProvides( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which provides the given @@ -284,9 +284,9 @@ class CsharpFileDiagram * @note This function is the revert version of the getProvides function. * @see getProvidedFiles() */ - std::vector getRevProvides( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getRevProvides( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which provides the @@ -299,15 +299,15 @@ class CsharpFileDiagram * provides the given file. * @return Created graph nodes. */ - std::vector getProvidedFiles( - util::Graph& graph_, - const util::Graph::Node& fileNode_, - bool reverse_ = false); + //std::vector getProvidedFiles( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_, + // bool reverse_ = false); - std::vector getProvidedFileIds( - util::Graph& graph_, - const util::Graph::Node& fileNode_, - bool reverse_ = false); + //std::vector getProvidedFileIds( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_, + // bool reverse_ = false); /** * This function creates graph nodes for each build sources which related to @@ -316,9 +316,9 @@ class CsharpFileDiagram * @param fileNode_ Graph file node object which represents a file object. * @return Created graph nodes. */ - std::vector getContains( - util::Graph& graph_, - const util::Graph::Node& fileNode_); + //std::vector getContains( + // util::Graph& graph_, + // const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each build targets which related to @@ -327,27 +327,27 @@ class CsharpFileDiagram * @param fileNode_ Graph file node object which represents a file object. * @return Created graph nodes. */ - std::vector getRevContains( - util::Graph& graph_, - const util::Graph::Node& node_); + //std::vector getRevContains( + // util::Graph& graph_, + // const util::Graph::Node& node_); /** * This function creates graph nodes for each files which files use the * given one. * @see getUsedFiles() */ - std::vector getUsages( - util::Graph& graph_, - const util::Graph::Node& node_); + //std::vector getUsages( + // util::Graph& graph_, + // const util::Graph::Node& node_); /** * This function creates graph nodes for each files which use the given file. * @note This function is the revert version of the getUsages function. * @see getUsedFiles() */ - std::vector getRevUsages( - util::Graph& graph_, - const util::Graph::Node& node_); + //std::vector getRevUsages( + // util::Graph& graph_, + // const util::Graph::Node& node_); /** * This function returns graph nodes which the given file depends on. @@ -365,15 +365,15 @@ class CsharpFileDiagram * use the given file. * @return Created graph nodes. */ - std::vector getUsedFiles( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_ = false); + //std::vector getUsedFiles( + // util::Graph& graph_, + // const util::Graph::Node& node_, + // bool reverse_ = false); - std::vector getUsedFileIds( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_); + //std::vector getUsedFileIds( + // util::Graph& graph_, + // const util::Graph::Node& node_, + // bool reverse_); static const Decoration centerNodeDecoration; static const Decoration sourceFileNodeDecoration; From 63b0acbd62738f2765d0b240caf72a27eb16ca55 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Tue, 21 Mar 2023 14:52:28 +0100 Subject: [PATCH 04/49] Diagrams :: Add depth into TEST DIAGRAM Previously data was only provided by csharpservice.cpp and no data was requested from the CsharpQueryHandler.cs. This commit requests the first AstValue associated with the path of the .cs file desired to create a diagram on. --- plugins/csharp/service/src/csharpfilediagram.cpp | 9 +++++++++ plugins/csharp/service/src/csharpfilediagram.h | 1 + plugins/csharp/service/src/csharpservice.cpp | 8 +++++++- .../service/src_csharp/CSharpQueryHandler.cs | 15 ++++++++++----- 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 1f1f18bb6..6090548f2 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -844,6 +844,7 @@ const CsharpFileDiagram::Decoration CsharpFileDiagram::revDependsEdgeDecoration }; void CsharpFileDiagram::getTestDiagram( + std::string firstAstNodeValue, util::Graph& graph_, const core::FileId& fileId_) { @@ -857,9 +858,17 @@ void CsharpFileDiagram::getTestDiagram( util::Graph::Node nextNode = addNode(graph_, parentInfo); decorateNode(graph_, nextNode, directoryNodeDecoration); + util::Graph::Node FirstAstValueToFileNode = graph_.createNode(); + graph_.setNodeAttribute(FirstAstValueToFileNode, "label", firstAstNodeValue); + decorateNode(graph_, FirstAstValueToFileNode, centerNodeDecoration); + util::Graph::Edge edge = graph_.createEdge(nextNode, currentNode); decorateEdge(graph_, edge, containsEdgeDecoration); + util::Graph::Edge edgeToValue = graph_.createEdge(currentNode, FirstAstValueToFileNode); + decorateEdge(graph_, edgeToValue, containsEdgeDecoration); + + } diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index ac67f88d3..64685edc2 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -110,6 +110,7 @@ class CsharpFileDiagram //std::string getComponentUsersDiagramLegend(); void getTestDiagram( + std::string firstAstNodeValue, util::Graph& graph_, const core::FileId& fileId_); diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index a97923e36..64e195bdb 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -176,7 +176,13 @@ void CsharpServiceHandler::getFileDiagram( switch (diagramId_){ case 999: - //diagram.getTestDiagram(graph, fileId_); + model::FilePtr file= _transaction([&, this](){ + return _db->query_one( + FileQuery::id == std::stoull(fileId_)); + }); + std::string data; + _csharpQueryHandler.getFileDiagram(data, file->path, diagramId_); + diagram.getTestDiagram(data, graph, fileId_); break; } diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 909d6707e..78d91600b 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -691,21 +691,26 @@ public async Task> getFileDiagramTypesAsync(string fileI public async Task getFileDiagramAsync(string fileId, int diagramId, CancellationToken cancellationToken = default(CancellationToken)) { - /*switch (diagramId) + switch (diagramId) { case 999: - string parent = dbContext.File + string astnodevalues = dbContext.CsharpAstNodes + .Where(a => a.Path == fileId) + .Select(a => a.AstValue) + .First() + .ToString(); + /*string parent = dbContext. .Where(a => (a.id).ToString() == fileId) .Select(a => a.parent) .ToString(); string parentInfo = dbContext.File .Where(a => parent == a.id.ToString()) .ToString(); - - return await Task.FromResult(parentInfo); + */ + return await Task.FromResult(astnodevalues); break; } - */ + return await Task.FromResult("File Diagram"); } From a5d9bafe91b493c49613263f92c67763bd1128a6 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Wed, 22 Mar 2023 19:09:58 +0100 Subject: [PATCH 05/49] Database :: Add CsharpEdge.cs This commit adds CsharpEdge.cs to create a table named CsharpEdge. --- plugins/csharp/model/CsharpDbContext.cs | 3 +- plugins/csharp/model/CsharpEdge.cs | 42 +++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 plugins/csharp/model/CsharpEdge.cs diff --git a/plugins/csharp/model/CsharpDbContext.cs b/plugins/csharp/model/CsharpDbContext.cs index eaef779d1..e07872144 100644 --- a/plugins/csharp/model/CsharpDbContext.cs +++ b/plugins/csharp/model/CsharpDbContext.cs @@ -16,8 +16,7 @@ public CsharpDbContext(DbContextOptions options) : base(options) { } public DbSet CsharpEnums { get; set; } public DbSet CsharpEnumMembers { get; set; } public DbSet CsharpEtcEntitys { get; set; } - - + public DbSet CsharpEdge { get; set; } } } diff --git a/plugins/csharp/model/CsharpEdge.cs b/plugins/csharp/model/CsharpEdge.cs new file mode 100644 index 000000000..924e71541 --- /dev/null +++ b/plugins/csharp/model/CsharpEdge.cs @@ -0,0 +1,42 @@ +using System.ComponentModel.DataAnnotations.Schema; +using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; + +namespace CSharpParser.model +{ + class CsharpEdge + { + enum Type + { + PROVIDE, + IMPLEMENT, + USE, + DEPEND + } + + public ulong Id { get; set; } + public ulong From { get; set; } + public ulong To { get; set; } + public Type Type { get; set; } + + public string typeToString(CsharpEdge::Type type_) + { + switch (type_) + { + case CsharpEdge.Type.PROVIDE: return "Provide"; + case CsharpEdge.Type.IMPLEMENT: return "Implement"; + case CsharpEdge.Type.USE: return "Use"; + case CsharpEdge.Type.DEPEND: return "Depend"; + } + + return string.Empty; + } + + public ulong createIdentifier(CsharpEdge edge_) + { + return (edge_.From.ToString() + + edge_.To.ToString() + + typeToString(edge_.Type)); + } + } +} \ No newline at end of file From 0ab3a2cb38452adcc01311d2e9c58470b358f56b Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 23 Mar 2023 12:46:26 +0100 Subject: [PATCH 06/49] Database :: Configure new table CsharpEdge More work needed for the table to actually appear --- .../20220518134047_Initial.Designer.cs | 21 +++++++++ .../migrations/20220518134047_Initial.cs | 18 +++++++ .../CsharpDbContextModelSnapshot.cs | 21 +++++++++ plugins/csharp/model/CsharpEdge.cs | 47 ++++++++++++------- 4 files changed, 89 insertions(+), 18 deletions(-) diff --git a/plugins/csharp/migrations/20220518134047_Initial.Designer.cs b/plugins/csharp/migrations/20220518134047_Initial.Designer.cs index 0a7707b34..d39a132b3 100644 --- a/plugins/csharp/migrations/20220518134047_Initial.Designer.cs +++ b/plugins/csharp/migrations/20220518134047_Initial.Designer.cs @@ -539,6 +539,27 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) { b.Navigation("CsharpEnumMembers"); }); + + modelBuilder.Entity("CSharpParser.model.CsharpEdge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("From") + .HasColumnType("bigint"); + + b.Property("To") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("CsharpEdge"); + }); #pragma warning restore 612, 618 } } diff --git a/plugins/csharp/migrations/20220518134047_Initial.cs b/plugins/csharp/migrations/20220518134047_Initial.cs index e643a7a6a..c48794aef 100644 --- a/plugins/csharp/migrations/20220518134047_Initial.cs +++ b/plugins/csharp/migrations/20220518134047_Initial.cs @@ -309,6 +309,21 @@ protected override void Up(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Restrict); }); + migrationBuilder.CreateTable( + name: "CsharpEdge", + columns: table => new + { + Id = table.Column(type: "bigint", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + From = table.Column(type: "bigint", nullable: false), + To = table.Column(type: "bigint", nullable: false), + Type = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CsharpEdge", x => x.Id); + }); + migrationBuilder.CreateIndex( name: "IX_CsharpClasses_AstNodeId", table: "CsharpClasses", @@ -438,6 +453,9 @@ protected override void Down(MigrationBuilder migrationBuilder) migrationBuilder.DropTable( name: "CsharpAstNodes"); + + migrationBuilder.DropTable( + name: "CsharpEdge"); } } } diff --git a/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs b/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs index 20ebbc516..809155a89 100644 --- a/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs +++ b/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs @@ -537,6 +537,27 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Navigation("CsharpEnumMembers"); }); + + modelBuilder.Entity("CSharpParser.model.CsharpEdge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("From") + .HasColumnType("bigint"); + + b.Property("To") + .HasColumnType("bigint"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("CsharpEdge"); + }); #pragma warning restore 612, 618 } } diff --git a/plugins/csharp/model/CsharpEdge.cs b/plugins/csharp/model/CsharpEdge.cs index 924e71541..7ed346798 100644 --- a/plugins/csharp/model/CsharpEdge.cs +++ b/plugins/csharp/model/CsharpEdge.cs @@ -1,32 +1,31 @@ -using System.ComponentModel.DataAnnotations.Schema; +using System; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; namespace CSharpParser.model { + enum EdgeType + { + PROVIDE, + IMPLEMENT, + USE, + DEPEND + } class CsharpEdge { - enum Type - { - PROVIDE, - IMPLEMENT, - USE, - DEPEND - } - public ulong Id { get; set; } public ulong From { get; set; } public ulong To { get; set; } - public Type Type { get; set; } + public EdgeType Type { get; set; } - public string typeToString(CsharpEdge::Type type_) + public string typeToString(EdgeType type_) { switch (type_) { - case CsharpEdge.Type.PROVIDE: return "Provide"; - case CsharpEdge.Type.IMPLEMENT: return "Implement"; - case CsharpEdge.Type.USE: return "Use"; - case CsharpEdge.Type.DEPEND: return "Depend"; + case EdgeType.PROVIDE: return "Provide"; + case EdgeType.IMPLEMENT: return "Implement"; + case EdgeType.USE: return "Use"; + case EdgeType.DEPEND: return "Depend"; } return string.Empty; @@ -34,9 +33,21 @@ public string typeToString(CsharpEdge::Type type_) public ulong createIdentifier(CsharpEdge edge_) { - return (edge_.From.ToString() + - edge_.To.ToString() + - typeToString(edge_.Type)); + return fnvHash($"{edge_.From}{edge_.To}{typeToString(edge_.Type)}"); } + + private ulong fnvHash(string data_) + { + ulong hash = 16695981039346656037; + + int len = data_.Length; + for (int i = 0; i < len; ++i) + { + hash ^= data_[i]; + hash *= 1699511628211; + } + + return hash; + } } } \ No newline at end of file From 22998f9589b06c04bb4650d13900f33f6a3bf83e Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Fri, 24 Mar 2023 11:44:25 +0100 Subject: [PATCH 07/49] Database :: Fix CsharpEdge table v1 The aim is to make this table appear --- .../20220518134047_Initial.Designer.cs | 20 ------------------- .../migrations/20220518134047_Initial.cs | 9 ++++----- .../CsharpDbContextModelSnapshot.cs | 20 ------------------- plugins/csharp/model/CsharpEdge.cs | 6 +++--- 4 files changed, 7 insertions(+), 48 deletions(-) diff --git a/plugins/csharp/migrations/20220518134047_Initial.Designer.cs b/plugins/csharp/migrations/20220518134047_Initial.Designer.cs index d39a132b3..66a8a89a8 100644 --- a/plugins/csharp/migrations/20220518134047_Initial.Designer.cs +++ b/plugins/csharp/migrations/20220518134047_Initial.Designer.cs @@ -540,26 +540,6 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder) b.Navigation("CsharpEnumMembers"); }); - modelBuilder.Entity("CSharpParser.model.CsharpEdge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("From") - .HasColumnType("bigint"); - - b.Property("To") - .HasColumnType("bigint"); - - b.Property("Type") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("CsharpEdge"); - }); #pragma warning restore 612, 618 } } diff --git a/plugins/csharp/migrations/20220518134047_Initial.cs b/plugins/csharp/migrations/20220518134047_Initial.cs index c48794aef..d7e41dbad 100644 --- a/plugins/csharp/migrations/20220518134047_Initial.cs +++ b/plugins/csharp/migrations/20220518134047_Initial.cs @@ -313,15 +313,14 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "CsharpEdge", columns: table => new { - Id = table.Column(type: "bigint", nullable: false) - .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), - From = table.Column(type: "bigint", nullable: false), - To = table.Column(type: "bigint", nullable: false), + EdgeId = table.Column(type: "numeric(20,0)", nullable: false), + From = table.Column(type: "numeric(20,0)", nullable: false), + To = table.Column(type: "numeric(20,0)", nullable: false), Type = table.Column(type: "integer", nullable: false) }, constraints: table => { - table.PrimaryKey("PK_CsharpEdge", x => x.Id); + table.PrimaryKey("PK_CsharpEdge", x => x.EdgeId); }); migrationBuilder.CreateIndex( diff --git a/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs b/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs index 809155a89..dbb78b69e 100644 --- a/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs +++ b/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs @@ -538,26 +538,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Navigation("CsharpEnumMembers"); }); - modelBuilder.Entity("CSharpParser.model.CsharpEdge", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); - - b.Property("From") - .HasColumnType("bigint"); - - b.Property("To") - .HasColumnType("bigint"); - - b.Property("Type") - .HasColumnType("integer"); - - b.HasKey("Id"); - - b.ToTable("CsharpEdge"); - }); #pragma warning restore 612, 618 } } diff --git a/plugins/csharp/model/CsharpEdge.cs b/plugins/csharp/model/CsharpEdge.cs index 7ed346798..f481552cf 100644 --- a/plugins/csharp/model/CsharpEdge.cs +++ b/plugins/csharp/model/CsharpEdge.cs @@ -13,7 +13,7 @@ enum EdgeType } class CsharpEdge { - public ulong Id { get; set; } + public ulong EdgeId { get; set; } public ulong From { get; set; } public ulong To { get; set; } public EdgeType Type { get; set; } @@ -38,13 +38,13 @@ public ulong createIdentifier(CsharpEdge edge_) private ulong fnvHash(string data_) { - ulong hash = 16695981039346656037; + ulong hash = 14695981039346656037; int len = data_.Length; for (int i = 0; i < len; ++i) { hash ^= data_[i]; - hash *= 1699511628211; + hash *= 1099511628211; } return hash; From 0da34c21331a78d426d6818315d879be9c742688 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 25 Mar 2023 12:22:25 +0100 Subject: [PATCH 08/49] Database :: Fix CharpEdge table v2 --- .../csharp/migrations/20220518134047_Initial.cs | 17 ----------------- plugins/csharp/model/CsharpDbContext.cs | 2 +- plugins/csharp/model/CsharpEdge.cs | 2 +- plugins/csharp/parser/src_csharp/Program.cs | 2 +- 4 files changed, 3 insertions(+), 20 deletions(-) diff --git a/plugins/csharp/migrations/20220518134047_Initial.cs b/plugins/csharp/migrations/20220518134047_Initial.cs index d7e41dbad..e643a7a6a 100644 --- a/plugins/csharp/migrations/20220518134047_Initial.cs +++ b/plugins/csharp/migrations/20220518134047_Initial.cs @@ -309,20 +309,6 @@ protected override void Up(MigrationBuilder migrationBuilder) onDelete: ReferentialAction.Restrict); }); - migrationBuilder.CreateTable( - name: "CsharpEdge", - columns: table => new - { - EdgeId = table.Column(type: "numeric(20,0)", nullable: false), - From = table.Column(type: "numeric(20,0)", nullable: false), - To = table.Column(type: "numeric(20,0)", nullable: false), - Type = table.Column(type: "integer", nullable: false) - }, - constraints: table => - { - table.PrimaryKey("PK_CsharpEdge", x => x.EdgeId); - }); - migrationBuilder.CreateIndex( name: "IX_CsharpClasses_AstNodeId", table: "CsharpClasses", @@ -452,9 +438,6 @@ protected override void Down(MigrationBuilder migrationBuilder) migrationBuilder.DropTable( name: "CsharpAstNodes"); - - migrationBuilder.DropTable( - name: "CsharpEdge"); } } } diff --git a/plugins/csharp/model/CsharpDbContext.cs b/plugins/csharp/model/CsharpDbContext.cs index e07872144..dbf8a97b2 100644 --- a/plugins/csharp/model/CsharpDbContext.cs +++ b/plugins/csharp/model/CsharpDbContext.cs @@ -16,7 +16,7 @@ public CsharpDbContext(DbContextOptions options) : base(options) { } public DbSet CsharpEnums { get; set; } public DbSet CsharpEnumMembers { get; set; } public DbSet CsharpEtcEntitys { get; set; } - public DbSet CsharpEdge { get; set; } + public DbSet CsharpEdges { get; set; } } } diff --git a/plugins/csharp/model/CsharpEdge.cs b/plugins/csharp/model/CsharpEdge.cs index f481552cf..4e06464f1 100644 --- a/plugins/csharp/model/CsharpEdge.cs +++ b/plugins/csharp/model/CsharpEdge.cs @@ -13,7 +13,7 @@ enum EdgeType } class CsharpEdge { - public ulong EdgeId { get; set; } + public ulong Id { get; set; } public ulong From { get; set; } public ulong To { get; set; } public EdgeType Type { get; set; } diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index cf86e0854..553f0ae3b 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -14,7 +14,7 @@ namespace CSharpParser { class Program { - //private readonly CsharpDbContext _context; + private readonly CsharpDbContext _context; private static string _rootDir = ""; private static string _buildDir = ""; private static string _buildDirBase = ""; From 50dd2d89908b8a0a682b34db41548c7e461b245b Mon Sep 17 00:00:00 2001 From: intjftw Date: Sun, 26 Mar 2023 03:01:32 +0200 Subject: [PATCH 09/49] Added new CPP files to CMake. --- .../CsharpDbContextModelSnapshot.cs | 70 +++++++++++++------ plugins/csharp/model/CsharpDbContext.cs | 17 ++++- 2 files changed, 66 insertions(+), 21 deletions(-) diff --git a/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs b/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs index dbb78b69e..c44b56ddd 100644 --- a/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs +++ b/plugins/csharp/migrations/CsharpDbContextModelSnapshot.cs @@ -6,6 +6,8 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; +#nullable disable + namespace CSharpParser.Migrations { [DbContext(typeof(CsharpDbContext))] @@ -15,9 +17,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Relational:MaxIdentifierLength", 63) - .HasAnnotation("ProductVersion", "5.0.10") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasAnnotation("ProductVersion", "6.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); modelBuilder.Entity("CSharpParser.model.CsharpAstNode", b => { @@ -67,8 +70,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -105,12 +109,33 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CsharpClasses"); }); + modelBuilder.Entity("CSharpParser.model.CsharpEdge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("From") + .HasColumnType("numeric(20,0)"); + + b.Property("To") + .HasColumnType("numeric(20,0)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("CsharpEdges"); + }); + modelBuilder.Entity("CSharpParser.model.CsharpEnum", b => { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -148,8 +173,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -190,8 +216,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -236,8 +263,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -279,8 +307,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -313,8 +342,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -352,8 +382,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Property("Id") .ValueGeneratedOnAdd() - .HasColumnType("bigint") - .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); b.Property("AstNodeId") .HasColumnType("numeric(20,0)"); @@ -537,7 +568,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) { b.Navigation("CsharpEnumMembers"); }); - #pragma warning restore 612, 618 } } diff --git a/plugins/csharp/model/CsharpDbContext.cs b/plugins/csharp/model/CsharpDbContext.cs index dbf8a97b2..b32032498 100644 --- a/plugins/csharp/model/CsharpDbContext.cs +++ b/plugins/csharp/model/CsharpDbContext.cs @@ -5,7 +5,22 @@ namespace CSharpParser.model { class CsharpDbContext : DbContext { - public CsharpDbContext(DbContextOptions options) : base(options) { } + private readonly bool isMigration = false; + public CsharpDbContext() + { + isMigration = true; + } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + if (isMigration) + { + optionsBuilder.UseNpgsql(@"Server=localhost;Port=5432;Database=migrations;User Id=compass;Password=compass"); + base.OnConfiguring(optionsBuilder); + } + } + + public CsharpDbContext(DbContextOptions options) : base(options) { } public DbSet CsharpAstNodes { get; set; } public DbSet CsharpNamespaces { get; set; } From 2876e488bbfbb84f264d399e7b75c1136b7ab2c1 Mon Sep 17 00:00:00 2001 From: intjftw Date: Mon, 27 Mar 2023 15:14:26 +0200 Subject: [PATCH 10/49] Adding new migrations with CsharpEdge table. --- ...326005354_CsharpEdge_Migration.Designer.cs | 576 ++++++++++++++++++ .../20230326005354_CsharpEdge_Migration.cs | 32 + 2 files changed, 608 insertions(+) create mode 100644 plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.Designer.cs create mode 100644 plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.cs diff --git a/plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.Designer.cs b/plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.Designer.cs new file mode 100644 index 000000000..24af907df --- /dev/null +++ b/plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.Designer.cs @@ -0,0 +1,576 @@ +// +using System; +using CSharpParser.model; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace CSharpParser.Migrations +{ + [DbContext(typeof(CsharpDbContext))] + [Migration("20230326005354_CsharpEdge_Migration")] + partial class CsharpEdge_Migration + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.5") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("CSharpParser.model.CsharpAstNode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Accessibility") + .HasColumnType("integer"); + + b.Property("AstSymbolType") + .HasColumnType("integer"); + + b.Property("AstType") + .HasColumnType("integer"); + + b.Property("AstValue") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("Location_range_end_column") + .HasColumnType("bigint"); + + b.Property("Location_range_end_line") + .HasColumnType("bigint"); + + b.Property("Location_range_start_column") + .HasColumnType("bigint"); + + b.Property("Location_range_start_line") + .HasColumnType("bigint"); + + b.Property("Path") + .HasColumnType("text"); + + b.Property("RawKind") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("CsharpAstNodes"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpClass", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("ClassType") + .HasColumnType("integer"); + + b.Property("CsharpNamespaceId") + .HasColumnType("bigint"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("CsharpNamespaceId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpClasses"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEdge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("From") + .HasColumnType("numeric(20,0)"); + + b.Property("To") + .HasColumnType("numeric(20,0)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.ToTable("CsharpEdges"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEnum", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("CsharpNamespaceId") + .HasColumnType("bigint"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("CsharpNamespaceId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpEnums"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEnumMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("CsharpEnumId") + .HasColumnType("bigint"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("EqualsValue") + .HasColumnType("integer"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("CsharpEnumId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpEnumMembers"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEtcEntity", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("DeclaratorNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("EtcEntityType") + .HasColumnType("integer"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.Property("QualifiedType") + .HasColumnType("text"); + + b.Property("TypeHash") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpEtcEntitys"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpMethod", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("MethodType") + .HasColumnType("integer"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.Property("QualifiedType") + .HasColumnType("text"); + + b.Property("TypeHash") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpMethods"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpNamespace", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpNamespaces"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpStruct", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("CsharpNamespaceId") + .HasColumnType("bigint"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("CsharpNamespaceId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpStructs"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpVariable", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AstNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("DocumentationCommentXML") + .HasColumnType("text"); + + b.Property("EntityHash") + .HasColumnType("bigint"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("ParentNodeId") + .HasColumnType("numeric(20,0)"); + + b.Property("QualifiedName") + .HasColumnType("text"); + + b.Property("QualifiedType") + .HasColumnType("text"); + + b.Property("TypeHash") + .HasColumnType("bigint"); + + b.Property("VariableType") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("AstNodeId"); + + b.HasIndex("ParentNodeId"); + + b.ToTable("CsharpVariables"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpClass", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpNamespace", "CsharpNamespace") + .WithMany() + .HasForeignKey("CsharpNamespaceId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("CsharpNamespace"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEnum", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpNamespace", "CsharpNamespace") + .WithMany() + .HasForeignKey("CsharpNamespaceId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("CsharpNamespace"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEnumMember", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpEnum", null) + .WithMany("CsharpEnumMembers") + .HasForeignKey("CsharpEnumId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEtcEntity", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpMethod", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpNamespace", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpStruct", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpNamespace", "CsharpNamespace") + .WithMany() + .HasForeignKey("CsharpNamespaceId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("CsharpNamespace"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpVariable", b => + { + b.HasOne("CSharpParser.model.CsharpAstNode", "AstNode") + .WithMany() + .HasForeignKey("AstNodeId"); + + b.HasOne("CSharpParser.model.CsharpAstNode", "ParentNode") + .WithMany() + .HasForeignKey("ParentNodeId"); + + b.Navigation("AstNode"); + + b.Navigation("ParentNode"); + }); + + modelBuilder.Entity("CSharpParser.model.CsharpEnum", b => + { + b.Navigation("CsharpEnumMembers"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.cs b/plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.cs new file mode 100644 index 000000000..99351bd2a --- /dev/null +++ b/plugins/csharp/migrations/20230326005354_CsharpEdge_Migration.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace CSharpParser.Migrations +{ + public partial class CsharpEdge_Migration : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "CsharpEdges", + columns: table => new + { + Id = table.Column(type: "numeric(20,0)", nullable: false), + From = table.Column(type: "numeric(20,0)", nullable: false), + To = table.Column(type: "numeric(20,0)", nullable: false), + Type = table.Column(type: "integer", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CsharpEdges", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "CsharpEdges"); + } + } +} From 6103b2e38c3106ef9882b50e01967098e57f93a7 Mon Sep 17 00:00:00 2001 From: intjftw Date: Mon, 27 Mar 2023 17:15:22 +0200 Subject: [PATCH 11/49] Eliminating migrations at database creation. --- plugins/csharp/parser/src/csharpparser.cpp | 1 + plugins/csharp/parser/src_csharp/Program.cs | 13 ++++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/parser/src/csharpparser.cpp b/plugins/csharp/parser/src/csharpparser.cpp index 44dfee381..ac8ba45fe 100644 --- a/plugins/csharp/parser/src/csharpparser.cpp +++ b/plugins/csharp/parser/src/csharpparser.cpp @@ -83,6 +83,7 @@ bool CsharpParser::parseProjectBuildPath(const std::vector& paths_) std::string line; std::stringstream log_str(log.get()); + LOG(warning) << log_str.str(); int countFull = 0, countPart = 0; while(std::getline(log_str, line, '\n')) diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index 553f0ae3b..17700cbc3 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -9,6 +9,8 @@ using System.Collections.Generic; using System.Threading.Tasks; using CSharpParser.model; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage; namespace CSharpParser { @@ -70,7 +72,16 @@ static int Main(string[] args) .Options; CsharpDbContext _context = new CsharpDbContext(options); - _context.Database.Migrate(); + //_context.Database.Migrate(); + try + { + _context.CsharpAstNodes.Count(); + } + catch + { + RelationalDatabaseCreator creator = _context.Database.GetService() as RelationalDatabaseCreator; + creator.CreateTables(); + } IEnumerable allFiles = GetSourceFilesFromDir(_rootDir, ".cs"); IEnumerable assemblies = GetSourceFilesFromDir(_buildDir, ".dll"); From 5367409e4c1ed5007cbadc36971cf47ba9e72e19 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 1 Apr 2023 17:46:37 +0200 Subject: [PATCH 12/49] Database :: Gather data for CsharpEdges table This commit creates the RelationCollector class which is derived from CsharpSyntaxWalker in order to populate the CsharpEdges table in the future. --- plugins/csharp/model/CsharpEdge.cs | 19 --- .../parser/src_csharp/RelationCollector.cs | 119 ++++++++++++++++++ 2 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 plugins/csharp/parser/src_csharp/RelationCollector.cs diff --git a/plugins/csharp/model/CsharpEdge.cs b/plugins/csharp/model/CsharpEdge.cs index 4e06464f1..d0576b448 100644 --- a/plugins/csharp/model/CsharpEdge.cs +++ b/plugins/csharp/model/CsharpEdge.cs @@ -30,24 +30,5 @@ public string typeToString(EdgeType type_) return string.Empty; } - - public ulong createIdentifier(CsharpEdge edge_) - { - return fnvHash($"{edge_.From}{edge_.To}{typeToString(edge_.Type)}"); - } - - private ulong fnvHash(string data_) - { - ulong hash = 14695981039346656037; - - int len = data_.Length; - for (int i = 0; i < len; ++i) - { - hash ^= data_[i]; - hash *= 1099511628211; - } - - return hash; - } } } \ No newline at end of file diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs new file mode 100644 index 000000000..c5d513b6d --- /dev/null +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using static System.Console; +using Microsoft.CodeAnalysis.CSharp; +using Microsoft.CodeAnalysis.CSharp.Syntax; +using CSharpParser.model; +using Microsoft.CodeAnalysis; + +namespace CSharpParser +{ + partial class RelationCollector : CSharpSyntaxWalker + { + private readonly CsharpDbContext DbContext; + private readonly SemanticModel Model; + private readonly SyntaxTree Tree; + + public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree) + { + this.DbContext = context; + this.Model = model; + this.Tree = tree; + } + + public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) + { + if (node.Initializer != null) + { + var symbol = Model.GetDeclaredSymbol(node); + var references = symbol.FindReferences(Model.Compilation); + + foreach (var reference in references) + { + var referenceNode = reference.Definition.DeclaringSyntaxReferences[0].GetSyntax(); + if (referenceNode != node) + { + var referenceSymbol = Model.GetSymbolInfo(referenceNode).Symbol; + + var declaringNode = node.Parent.Parent; // The parent of the variable declarator is the variable declaration syntax, whose parent is the member declaration syntax. + var declaringFile = declaringNode.SyntaxTree.FilePath; + + var referenceFile = referenceNode.SyntaxTree.FilePath; + + WriteLine($"Value declaringFile: {declarinFile}; referenceFile: {referenceFile}"); + + CsharpEdge csharpEdge = new CsharpEdge + { + Id = null, + From = fvnHash(declaringFile), + To = fvnHash(referenceFile), + EdgeType = EdgeType.USE + }; + csharpEdge.Id = createIdentifier(csharpEdge); + DbContext.CsharpEdges.Add(csharpEdge); + } + } + } + + base.VisitVariableDeclarator(node); + } + + public override void VisitInvocationExpression(InvocationExpressionSyntax node) + { + var symbol = Model.GetSymbolInfo(node).Symbol; + + if (symbol != null && symbol.Kind == SymbolKind.Method) + { + var methodSymbol = (IMethodSymbol)symbol; + + var containingType = methodSymbol.ContainingType; + if (containingType != null && containingType.Name != "") + { + var declaringFile = node.SyntaxTree.FilePath; + + string referenceFile = null; + if (containingType.Locations.Length > 0) + { + referenceFile = containingType.Locations[0].SourceTree.FilePath; + } + WriteLine($"Method declaringFile: {declaringFile}; referenceFile: {referenceFile}"); + + if (referenceFile != null) + { + CsharpEdge csharpEdge = new CsharpEdge + { + Id = null, + From = fvnHash(declaringFile), + To = fvnHash(referenceFile), + EdgeType = EdgeType.USE + }; + csharpEdge.Id = createIdentifier(csharpEdge); + DbContext.CsharpEdges.Add(csharpEdge); + } + } + } + + base.VisitInvocationExpression(node); + } + + private ulong createIdentifier(CsharpEdge edge_) + { + return fnvHash($"{edge_.From}{edge_.To}{typeToString(edge_.Type)}"); + } + + private ulong fnvHash(string data_) + { + ulong hash = 14695981039346656037; + + int len = data_.Length; + for (int i = 0; i < len; ++i) + { + hash ^= data_[i]; + hash *= 1099511628211; + } + + return hash; + } + } +} \ No newline at end of file From fcf9a2761bc0ed4224fb2957fcae34d3d52d324b Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 2 Apr 2023 00:14:45 +0200 Subject: [PATCH 13/49] Database :: Edit on RelationCollector More work added in RelationCollector.cs and Program.cs in order to collect data into CsharpEdges table --- plugins/csharp/model/CsharpEdge.cs | 13 -- plugins/csharp/parser/src_csharp/Program.cs | 64 +++++++++ .../parser/src_csharp/RelationCollector.cs | 126 +++++++++++++----- 3 files changed, 155 insertions(+), 48 deletions(-) diff --git a/plugins/csharp/model/CsharpEdge.cs b/plugins/csharp/model/CsharpEdge.cs index d0576b448..e60a7dd6f 100644 --- a/plugins/csharp/model/CsharpEdge.cs +++ b/plugins/csharp/model/CsharpEdge.cs @@ -17,18 +17,5 @@ class CsharpEdge public ulong From { get; set; } public ulong To { get; set; } public EdgeType Type { get; set; } - - public string typeToString(EdgeType type_) - { - switch (type_) - { - case EdgeType.PROVIDE: return "Provide"; - case EdgeType.IMPLEMENT: return "Implement"; - case EdgeType.USE: return "Use"; - case EdgeType.DEPEND: return "Depend"; - } - - return string.Empty; - } } } \ No newline at end of file diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index 17700cbc3..c652c99fc 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -112,6 +112,9 @@ static int Main(string[] args) var runtask = ParalellRun(csharpConnectionString, threadNum, trees, compilation); int ret = runtask.Result; + + var collecttask = ParalellCollect(csharpConnectionString, threadNum, trees, compilation); + int res = collecttask.Result; return 0; } @@ -176,6 +179,67 @@ private static async Task ParseTree(CsharpDbContext context, return await ParingTask; } + // + + private static async Task ParalellCollect(string csharpConnectionString, int threadNum, + List trees, CSharpCompilation compilation) + { + var options = new DbContextOptionsBuilder() + .UseNpgsql(csharpConnectionString) + .Options; + CsharpDbContext dbContext = new CsharpDbContext(options); + + var contextList = new List(); + contextList.Add(dbContext); + for (int i = 1; i < threadNum; i++) + { + CsharpDbContext dbContextInstance = new CsharpDbContext(options); + contextList.Add(dbContextInstance); + } + + var CollectingTasks = new List>(); + int maxThread = threadNum < trees.Count() ? threadNum : trees.Count(); + for (int i = 0; i < maxThread; i++) + { + CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i)); + } + + int nextTreeIndex = maxThread; + while (CollectingTasks.Count > 0) + { + var finshedTask = await Task.WhenAny(CollectingTasks); + int nextContextIndex = await finshedTask; + + CollectingTasks.Remove(finshedTask); + if (nextTreeIndex < trees.Count) + { + CollectingTasks.Add(CollectRelation(contextList[nextContextIndex], + trees[nextTreeIndex],compilation,nextContextIndex)); + ++nextTreeIndex; + } + } + + foreach (var ctx in contextList) + { + ctx.SaveChanges(); + } + + return 0; + } + + private static async Task CollectRelation(CsharpDbContext context, + SyntaxTree tree, CSharpCompilation compilation, int index) + { + var CollectingTask = Task.Run(() => + { + SemanticModel model = compilation.GetSemanticModel(tree); + var visitor = new RelationCollector(context, model, tree); + visitor.Visit(tree.GetCompilationUnitRoot()); + return index; + }); + return await CollectingTask; + } + public static IEnumerable GetSourceFilesFromDir(string root, string extension) { IEnumerable allFiles = new string[]{}; diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index c5d513b6d..63556296a 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -4,8 +4,10 @@ using static System.Console; using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; +using Microsoft.CodeAnalysis.FindSymbols; using CSharpParser.model; using Microsoft.CodeAnalysis; +using System.Threading.Tasks; namespace CSharpParser { @@ -19,7 +21,8 @@ public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTre { this.DbContext = context; this.Model = model; - this.Tree = tree; + this.Tree = tree; + //this.solution = Solution ??? } public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) @@ -27,7 +30,10 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) if (node.Initializer != null) { var symbol = Model.GetDeclaredSymbol(node); - var references = symbol.FindReferences(Model.Compilation); + var references = symbol.FindReferences(/*Model.Compilation*/); + //var solution = _semanticModel.Compilation.SyntaxTrees.First().Options.SyntaxTree.GetRoot().SyntaxTree.Options + // .Project.Solution; + //var references = await SymbolFinder.FindReferencesAsync(symbol, solution); foreach (var reference in references) { @@ -41,15 +47,12 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) var referenceFile = referenceNode.SyntaxTree.FilePath; - WriteLine($"Value declaringFile: {declarinFile}; referenceFile: {referenceFile}"); + WriteLine($"Value declaringFile: {declaringFile}; referenceFile: {referenceFile}"); - CsharpEdge csharpEdge = new CsharpEdge - { - Id = null, - From = fvnHash(declaringFile), - To = fvnHash(referenceFile), - EdgeType = EdgeType.USE - }; + CsharpEdge csharpEdge = new CsharpEdge(); + csharpEdge.From = fnvHash(declaringFile); + csharpEdge.To = fnvHash(referenceFile); + csharpEdge.Type = EdgeType.USE; csharpEdge.Id = createIdentifier(csharpEdge); DbContext.CsharpEdges.Add(csharpEdge); } @@ -58,44 +61,84 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) base.VisitVariableDeclarator(node); } + - public override void VisitInvocationExpression(InvocationExpressionSyntax node) - { - var symbol = Model.GetSymbolInfo(node).Symbol; + /* + public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) + { + var symbol = Model.GetDeclaredSymbol(node); + + var solution = + + ProcessReferencesAsync(node, symbol, solution).Wait(); - if (symbol != null && symbol.Kind == SymbolKind.Method) + base.VisitVariableDeclarator(node); + } + + private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol symbol, Solution solution) { - var methodSymbol = (IMethodSymbol)symbol; + var references = await SymbolFinder.FindReferencesAsync(symbol, solution); - var containingType = methodSymbol.ContainingType; - if (containingType != null && containingType.Name != "") + foreach (var reference in references) { - var declaringFile = node.SyntaxTree.FilePath; - - string referenceFile = null; - if (containingType.Locations.Length > 0) + var referenceNode = reference.Definition.DeclaringSyntaxReferences[0].GetSyntax(); + if (referenceNode != node) { - referenceFile = containingType.Locations[0].SourceTree.FilePath; - } - WriteLine($"Method declaringFile: {declaringFile}; referenceFile: {referenceFile}"); + var referenceSymbol = Model.GetSymbolInfo(referenceNode).Symbol; - if (referenceFile != null) - { - CsharpEdge csharpEdge = new CsharpEdge - { - Id = null, - From = fvnHash(declaringFile), - To = fvnHash(referenceFile), - EdgeType = EdgeType.USE - }; + var declaringNode = node.Parent.Parent; // The parent of the variable declarator is the variable declaration syntax, whose parent is the member declaration syntax. + var declaringFile = declaringNode.SyntaxTree.FilePath; + + var referenceFile = referenceNode.SyntaxTree.FilePath; + + WriteLine($"Value declaringFile: {declaringFile}; referenceFile: {referenceFile}"); + + CsharpEdge csharpEdge = new CsharpEdge(); + csharpEdge.From = fnvHash(declaringFile); + csharpEdge.To = fnvHash(referenceFile); + csharpEdge.Type = EdgeType.USE; csharpEdge.Id = createIdentifier(csharpEdge); DbContext.CsharpEdges.Add(csharpEdge); } } } + */ - base.VisitInvocationExpression(node); - } + + public override void VisitInvocationExpression(InvocationExpressionSyntax node) + { + var symbol = Model.GetSymbolInfo(node).Symbol; + + if (symbol != null && symbol.Kind == SymbolKind.Method) + { + var methodSymbol = (IMethodSymbol)symbol; + + var containingType = methodSymbol.ContainingType; + if (containingType != null && containingType.Name != "") + { + var declaringFile = node.SyntaxTree.FilePath; + + string referenceFile = null; + if (containingType.Locations.Length > 0) + { + referenceFile = containingType.Locations[0].SourceTree.FilePath; + } + WriteLine($"Method declaringFile: {declaringFile}; referenceFile: {referenceFile}"); + + if (referenceFile != null) + { + CsharpEdge csharpEdge = new CsharpEdge(); + csharpEdge.From = fnvHash(declaringFile); + csharpEdge.To = fnvHash(referenceFile); + csharpEdge.Type = EdgeType.USE; + csharpEdge.Id = createIdentifier(csharpEdge); + DbContext.CsharpEdges.Add(csharpEdge); + } + } + } + + base.VisitInvocationExpression(node); + } private ulong createIdentifier(CsharpEdge edge_) { @@ -114,6 +157,19 @@ private ulong fnvHash(string data_) } return hash; + } + + private string typeToString(EdgeType type_) + { + switch (type_) + { + case EdgeType.PROVIDE: return "Provide"; + case EdgeType.IMPLEMENT: return "Implement"; + case EdgeType.USE: return "Use"; + case EdgeType.DEPEND: return "Depend"; + } + + return string.Empty; } } } \ No newline at end of file From eafe0d26cf2c00c1e6c22803593e94ca9795a6bd Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Mon, 3 Apr 2023 17:16:21 +0200 Subject: [PATCH 14/49] Database :: Fix RelationCollector This commit fixes code related errors when parsing using the newly created RelationCollector --- plugins/csharp/parser/src_csharp/Program.cs | 16 ++++++++----- .../parser/src_csharp/RelationCollector.cs | 24 +++++++++---------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index c652c99fc..144ec70af 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -90,12 +90,16 @@ static int Main(string[] args) assemblies_base = GetSourceFilesFromDir(_buildDirBase, ".dll"); List trees = new List(); + var workspace = new AdhocWorkspace(); + var project = workspace.AddProject("MyProject", LanguageNames.CSharp); foreach (string file in allFiles) { string programText = File.ReadAllText(file); SyntaxTree tree = CSharpSyntaxTree.ParseText(programText, null, file); trees.Add(tree); + var document = workspace.AddDocument(project.Id, file, Microsoft.CodeAnalysis.Text.SourceText.From(File.ReadAllText(file))); } + var solution = workspace.CurrentSolution; CSharpCompilation compilation = CSharpCompilation.Create("CSharpCompilation") .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) @@ -113,7 +117,7 @@ static int Main(string[] args) var runtask = ParalellRun(csharpConnectionString, threadNum, trees, compilation); int ret = runtask.Result; - var collecttask = ParalellCollect(csharpConnectionString, threadNum, trees, compilation); + var collecttask = ParalellCollect(csharpConnectionString, threadNum, trees, compilation, solution); int res = collecttask.Result; return 0; @@ -182,7 +186,7 @@ private static async Task ParseTree(CsharpDbContext context, // private static async Task ParalellCollect(string csharpConnectionString, int threadNum, - List trees, CSharpCompilation compilation) + List trees, CSharpCompilation compilation, Solution solution) { var options = new DbContextOptionsBuilder() .UseNpgsql(csharpConnectionString) @@ -201,7 +205,7 @@ private static async Task ParalellCollect(string csharpConnectionString, in int maxThread = threadNum < trees.Count() ? threadNum : trees.Count(); for (int i = 0; i < maxThread; i++) { - CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i)); + CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i,solution)); } int nextTreeIndex = maxThread; @@ -214,7 +218,7 @@ private static async Task ParalellCollect(string csharpConnectionString, in if (nextTreeIndex < trees.Count) { CollectingTasks.Add(CollectRelation(contextList[nextContextIndex], - trees[nextTreeIndex],compilation,nextContextIndex)); + trees[nextTreeIndex],compilation,nextContextIndex,solution)); ++nextTreeIndex; } } @@ -228,12 +232,12 @@ private static async Task ParalellCollect(string csharpConnectionString, in } private static async Task CollectRelation(CsharpDbContext context, - SyntaxTree tree, CSharpCompilation compilation, int index) + SyntaxTree tree, CSharpCompilation compilation, int index, Solution solution) { var CollectingTask = Task.Run(() => { SemanticModel model = compilation.GetSemanticModel(tree); - var visitor = new RelationCollector(context, model, tree); + var visitor = new RelationCollector(context, model, tree, solution); visitor.Visit(tree.GetCompilationUnitRoot()); return index; }); diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index 63556296a..9a5554fe7 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -16,21 +16,23 @@ partial class RelationCollector : CSharpSyntaxWalker private readonly CsharpDbContext DbContext; private readonly SemanticModel Model; private readonly SyntaxTree Tree; + private readonly Solution Solution; - public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree) + public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree, Solution solution) { this.DbContext = context; this.Model = model; this.Tree = tree; - //this.solution = Solution ??? + this.Solution = solution; } + /* public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { if (node.Initializer != null) { var symbol = Model.GetDeclaredSymbol(node); - var references = symbol.FindReferences(/*Model.Compilation*/); + var references = symbol.FindReferences(Model.Compilation); //var solution = _semanticModel.Compilation.SyntaxTrees.First().Options.SyntaxTree.GetRoot().SyntaxTree.Options // .Project.Solution; //var references = await SymbolFinder.FindReferencesAsync(symbol, solution); @@ -62,22 +64,20 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) base.VisitVariableDeclarator(node); } - - /* + */ + public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { var symbol = Model.GetDeclaredSymbol(node); - var solution = - - ProcessReferencesAsync(node, symbol, solution).Wait(); + ProcessReferencesAsync(node, symbol).Wait(); base.VisitVariableDeclarator(node); } - private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol symbol, Solution solution) + private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol symbol) { - var references = await SymbolFinder.FindReferencesAsync(symbol, solution); + var references = await SymbolFinder.FindReferencesAsync(symbol, Solution); foreach (var reference in references) { @@ -102,7 +102,7 @@ private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol } } } - */ + public override void VisitInvocationExpression(InvocationExpressionSyntax node) @@ -119,7 +119,7 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node) var declaringFile = node.SyntaxTree.FilePath; string referenceFile = null; - if (containingType.Locations.Length > 0) + if (containingType.Locations.Length > 0 && containingType.Locations[0].SourceTree != null) { referenceFile = containingType.Locations[0].SourceTree.FilePath; } From 0b2813a225bd0c3ceeb8870dfab083d3808ba7aa Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Wed, 12 Apr 2023 12:33:29 +0200 Subject: [PATCH 15/49] Database :: Add not-null conditions to RelationCollector This commit adds conditions to check for null files. --- plugins/csharp/parser/src_csharp/Program.cs | 5 ++-- .../parser/src_csharp/RelationCollector.cs | 28 ++++++++++++------- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index 144ec70af..984c221f8 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -115,10 +115,11 @@ static int Main(string[] args) } var runtask = ParalellRun(csharpConnectionString, threadNum, trees, compilation); - int ret = runtask.Result; - var collecttask = ParalellCollect(csharpConnectionString, threadNum, trees, compilation, solution); + + int ret = runtask.Result; int res = collecttask.Result; + return 0; } diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index 9a5554fe7..40d540c13 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -91,14 +91,19 @@ private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol var referenceFile = referenceNode.SyntaxTree.FilePath; - WriteLine($"Value declaringFile: {declaringFile}; referenceFile: {referenceFile}"); - - CsharpEdge csharpEdge = new CsharpEdge(); - csharpEdge.From = fnvHash(declaringFile); - csharpEdge.To = fnvHash(referenceFile); - csharpEdge.Type = EdgeType.USE; - csharpEdge.Id = createIdentifier(csharpEdge); - DbContext.CsharpEdges.Add(csharpEdge); + if (referenceFile != null && + declaringFile != null && + referenceFile != declaringFile) + { + WriteLine($"Value declaringFile: {declaringFile}; referenceFile: {referenceFile}"); + + CsharpEdge csharpEdge = new CsharpEdge(); + csharpEdge.From = fnvHash(declaringFile); + csharpEdge.To = fnvHash(referenceFile); + csharpEdge.Type = EdgeType.USE; + csharpEdge.Id = createIdentifier(csharpEdge); + DbContext.CsharpEdges.Add(csharpEdge); + } } } } @@ -123,10 +128,13 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node) { referenceFile = containingType.Locations[0].SourceTree.FilePath; } - WriteLine($"Method declaringFile: {declaringFile}; referenceFile: {referenceFile}"); - if (referenceFile != null) + if (referenceFile != null && + declaringFile != null && + referenceFile != declaringFile) { + WriteLine($"Method declaringFile: {declaringFile}; referenceFile: {referenceFile}"); + CsharpEdge csharpEdge = new CsharpEdge(); csharpEdge.From = fnvHash(declaringFile); csharpEdge.To = fnvHash(referenceFile); From 180702aea70544cfa72ef5e35aa9d138532810dd Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 13 Apr 2023 13:41:43 +0200 Subject: [PATCH 16/49] Database :: Fill CsharpEdges table This commit fixes the RelationCollector class and makes changes to the Program.cs. We add a ConcurrentDictionary in order to gather data into it with the relationcollector. After data is collected, the contents of this ConcurrentDictionary is transferred to the DbContext and the changes are saved. RelationCollector needs further work on the VisitValueDeclarator and VisitInvocationExpression functions. --- plugins/csharp/parser/src_csharp/Program.cs | 30 +++++-- .../parser/src_csharp/RelationCollector.cs | 90 ++++++++++++------- 2 files changed, 78 insertions(+), 42 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index 984c221f8..1f7389e93 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -11,6 +11,7 @@ using CSharpParser.model; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage; +using System.Collections.Concurrent; namespace CSharpParser { @@ -203,10 +204,11 @@ private static async Task ParalellCollect(string csharpConnectionString, in } var CollectingTasks = new List>(); + ConcurrentDictionary edges = new ConcurrentDictionary(); int maxThread = threadNum < trees.Count() ? threadNum : trees.Count(); for (int i = 0; i < maxThread; i++) { - CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i,solution)); + CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i,edges,solution)); } int nextTreeIndex = maxThread; @@ -219,27 +221,39 @@ private static async Task ParalellCollect(string csharpConnectionString, in if (nextTreeIndex < trees.Count) { CollectingTasks.Add(CollectRelation(contextList[nextContextIndex], - trees[nextTreeIndex],compilation,nextContextIndex,solution)); + trees[nextTreeIndex],compilation,nextContextIndex, edges, solution)); ++nextTreeIndex; } } - foreach (var ctx in contextList) + foreach (var edge in edges) { - ctx.SaveChanges(); - } + //var duplicate = dbContext.CsharpEdges. + // Where(a => a.Id == edge.Key). + // FirstOrDefault(); + //if (duplicate == null) + dbContext.CsharpEdges.Add(edge.Value); + } + + dbContext.SaveChanges(); + + //foreach (var ctx in contextList) + //{ + // ctx.SaveChanges(); + //} return 0; } private static async Task CollectRelation(CsharpDbContext context, - SyntaxTree tree, CSharpCompilation compilation, int index, Solution solution) + SyntaxTree tree, CSharpCompilation compilation, int index, ConcurrentDictionary edges, + Solution solution) { var CollectingTask = Task.Run(() => { SemanticModel model = compilation.GetSemanticModel(tree); - var visitor = new RelationCollector(context, model, tree, solution); - visitor.Visit(tree.GetCompilationUnitRoot()); + var visitor = new RelationCollector(context, model, tree, edges, solution); + visitor.Visit(tree.GetCompilationUnitRoot()); return index; }); return await CollectingTask; diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index 40d540c13..0c4c63867 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -8,6 +8,7 @@ using CSharpParser.model; using Microsoft.CodeAnalysis; using System.Threading.Tasks; +using System.Collections.Concurrent; namespace CSharpParser { @@ -17,55 +18,75 @@ partial class RelationCollector : CSharpSyntaxWalker private readonly SemanticModel Model; private readonly SyntaxTree Tree; private readonly Solution Solution; + private readonly ConcurrentDictionary Edges; - public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree, Solution solution) + public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree, ConcurrentDictionary edges, Solution solution) { this.DbContext = context; this.Model = model; this.Tree = tree; + this.Edges = edges; this.Solution = solution; } - /* + //test + public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { - if (node.Initializer != null) - { - var symbol = Model.GetDeclaredSymbol(node); - var references = symbol.FindReferences(Model.Compilation); - //var solution = _semanticModel.Compilation.SyntaxTrees.First().Options.SyntaxTree.GetRoot().SyntaxTree.Options - // .Project.Solution; - //var references = await SymbolFinder.FindReferencesAsync(symbol, solution); + if (node.Initializer == null) return; - foreach (var reference in references) - { - var referenceNode = reference.Definition.DeclaringSyntaxReferences[0].GetSyntax(); - if (referenceNode != node) - { - var referenceSymbol = Model.GetSymbolInfo(referenceNode).Symbol; + var symbol = Model.GetSymbolInfo(node.Initializer.Value).Symbol; + if (symbol == null || symbol.ContainingAssembly.Identity != Model.Compilation.Assembly.Identity) return; - var declaringNode = node.Parent.Parent; // The parent of the variable declarator is the variable declaration syntax, whose parent is the member declaration syntax. - var declaringFile = declaringNode.SyntaxTree.FilePath; + var symbolLocation = symbol.Locations.FirstOrDefault(loc => loc.IsInSource); + if (symbolLocation == null) return; - var referenceFile = referenceNode.SyntaxTree.FilePath; + var symbolFilePath = symbolLocation.SourceTree?.FilePath; + var usageFilePath = node.SyntaxTree.FilePath; + if (symbolFilePath == null || + usageFilePath == null || + symbolFilePath == usageFilePath) return; - WriteLine($"Value declaringFile: {declaringFile}; referenceFile: {referenceFile}"); - CsharpEdge csharpEdge = new CsharpEdge(); - csharpEdge.From = fnvHash(declaringFile); - csharpEdge.To = fnvHash(referenceFile); - csharpEdge.Type = EdgeType.USE; - csharpEdge.Id = createIdentifier(csharpEdge); - DbContext.CsharpEdges.Add(csharpEdge); - } - } - } + WriteLine($"Value usagePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); + + CsharpEdge csharpEdge = new CsharpEdge(); + csharpEdge.From = fnvHash(usageFilePath); + csharpEdge.To = fnvHash(symbolFilePath); + csharpEdge.Type = EdgeType.USE; + csharpEdge.Id = createIdentifier(csharpEdge); + + Edges.TryAdd(csharpEdge.Id,csharpEdge); base.VisitVariableDeclarator(node); } - - */ - + + public override void VisitInvocationExpression(InvocationExpressionSyntax node) + { + var methodSymbol = Model.GetSymbolInfo(node).Symbol as IMethodSymbol; + if (methodSymbol == null || methodSymbol.ContainingAssembly.Identity != Model.Compilation.Assembly.Identity) return; + + var symbolFilePath = methodSymbol.Locations.FirstOrDefault(loc => loc.IsInSource)?.SourceTree?.FilePath; + var usageFilePath = node.SyntaxTree.FilePath; + if (symbolFilePath == null || + usageFilePath == null || + symbolFilePath == usageFilePath) return; + + WriteLine($"Value usageFilePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); + + CsharpEdge csharpEdge = new CsharpEdge(); + csharpEdge.From = fnvHash(usageFilePath); + csharpEdge.To = fnvHash(symbolFilePath); + csharpEdge.Type = EdgeType.USE; + csharpEdge.Id = createIdentifier(csharpEdge); + + Edges.TryAdd(csharpEdge.Id,csharpEdge); + + base.VisitInvocationExpression(node); + } + + + /* public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { var symbol = Model.GetDeclaredSymbol(node); @@ -107,9 +128,9 @@ private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol } } } - - + */ + /* public override void VisitInvocationExpression(InvocationExpressionSyntax node) { var symbol = Model.GetSymbolInfo(node).Symbol; @@ -140,13 +161,14 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node) csharpEdge.To = fnvHash(referenceFile); csharpEdge.Type = EdgeType.USE; csharpEdge.Id = createIdentifier(csharpEdge); - DbContext.CsharpEdges.Add(csharpEdge); + //DbContext.CsharpEdges.Add(csharpEdge); } } } base.VisitInvocationExpression(node); } + */ private ulong createIdentifier(CsharpEdge edge_) { From a657fda79e51a067390b8c893fd4cba450cd1e39 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Mon, 17 Apr 2023 21:36:54 +0200 Subject: [PATCH 17/49] Diagrams :: Data required for FileUsage diagram fetched In this commmit i gather the data required, to build the file usages diagram, into a string, using the following format $"{uses}:{revUses}". This will be converted and used. --- .../parser/src_csharp/RelationCollector.cs | 5 ++- .../service/include/service/csharpservice.h | 45 +++++++++++++++++++ .../csharp/service/src/csharpfilediagram.cpp | 16 ++++--- plugins/csharp/service/src/csharpservice.cpp | 34 +++++++++++--- .../service/src_csharp/CSharpQueryHandler.cs | 44 +++++++++++------- 5 files changed, 114 insertions(+), 30 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index 0c4c63867..4c2476ec6 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -48,7 +48,7 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) symbolFilePath == usageFilePath) return; - WriteLine($"Value usagePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); + WriteLine($"Value usageFilePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); CsharpEdge csharpEdge = new CsharpEdge(); csharpEdge.From = fnvHash(usageFilePath); @@ -64,7 +64,8 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) public override void VisitInvocationExpression(InvocationExpressionSyntax node) { var methodSymbol = Model.GetSymbolInfo(node).Symbol as IMethodSymbol; - if (methodSymbol == null || methodSymbol.ContainingAssembly.Identity != Model.Compilation.Assembly.Identity) return; + if (methodSymbol == null || + methodSymbol.ContainingAssembly.Identity != Model.Compilation.Assembly.Identity) return; var symbolFilePath = methodSymbol.Locations.FirstOrDefault(loc => loc.IsInSource)?.SourceTree?.FilePath; var usageFilePath = node.SyntaxTree.FilePath; diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index 6c3968172..d39c6b9e5 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -338,6 +338,51 @@ class CsharpServiceHandler : virtual public LanguageServiceIf const core::FileRange& range_) override; private: + +enum DiagramType + { + FILE_USAGES, + FUNCTION_CALL, /*!< In the function call diagram the nodes are functions and + the edges are the function calls between them. The diagram also displays + some dynamic information such as virtual function calls. */ + + DETAILED_CLASS, /*!< This is a classical UML class diagram for the selected + class and its direct children and parents. The nodes contain the methods + and member variables with their visibility. */ + + CLASS_OVERVIEW, /*!< This is a class diagram which contains all classes + which inherit from the current one, and all parents from which the + current one inherits. The methods and member variables are node included + in the nodes, but the type of the member variables are indicated as + aggregation relationship. */ + + CLASS_COLLABORATION, /*!< This returns a class collaboration diagram + which shows the individual class members and their inheritance + hierarchy. */ + + COMPONENT_USERS, /*!< Component users diagram for source file S shows which + source files depend on S through the interfaces S provides. */ + + EXTERNAL_DEPENDENCY, /*!< This diagram shows the module which directory + depends on. The "depends on" diagram on module A traverses the + subdirectories of module A and shows all directories that contain files + that any of the source files in A includes. */ + + EXTERNAL_USERS, /*!< This diagram shows directories (modules) that are + users of the queried module. */ + + INCLUDE_DEPENDENCY, /*!< This diagram shows of the `#include` file + dependencies. */ + + INTERFACE, /*!< Interface diagram shows the used and provided interfaces of + a source code file and shows linking information. */ + + SUBSYSTEM_DEPENDENCY, /*!< This diagram shows the directories relationship + between the subdirectories of the queried module. This diagram is useful + to understand the relationships of the subdirectories (submodules) + of a module. */ + }; + std::shared_ptr _db; util::OdbTransaction _transaction; diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 6090548f2..cf281ff6e 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -89,7 +89,8 @@ std::string CsharpFileDiagram::getComponentUsersDiagramLegend() return builder.getOutput(); } - +*/ +/* void CsharpFileDiagram::getIncludeDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_) @@ -97,7 +98,8 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); - +*/ + /* util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getUsages, this, std::placeholders::_1, std::placeholders::_2), {}, usagesEdgeDecoration, 3); @@ -105,16 +107,16 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getRevUsages, this, std::placeholders::_1, std::placeholders::_2), {}, revUsagesEdgeDecoration, 3); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, + */ + /* util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, this, std::placeholders::_1, std::placeholders::_2), {}, usagesEdgeDecoration, 3); util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevProvides, this, std::placeholders::_1, std::placeholders::_2), {}, revUsagesEdgeDecoration, 3); -} - +}*/ +/* std::string CsharpFileDiagram::getIncludeDependencyDiagramLegend() { util::LegendBuilder builder("Include Dependency Diagram"); @@ -654,7 +656,7 @@ std::vector CsharpFileDiagram::getUsedFiles( { std::vector usages; - std::vector fileIds = getUsedFileIds(graph_, node_, reverse_); + // std::vector fileIds = getUsedFileIds(graph_, node_, reverse_); for (const core::FileId& fileId: fileIds) { diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 64e195bdb..df0b19275 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -160,7 +160,26 @@ void CsharpServiceHandler::getFileDiagramTypes( const core::FileId& fileId_) { LOG(info) << "getFileDiagramTypes"; - _csharpQueryHandler.getFileDiagramTypes(return_, fileId_); //most irtam + //_csharpQueryHandler.getFileDiagramTypes(return_, fileId_); //most irtam + + model::FilePtr file = _transaction([&, this](){ + return _db->query_one( + FileQuery::id == std::stoull(fileId_)); + }); + + if (file) + { + if (file->type == model::File::DIRECTORY_TYPE) + { + //return_["Internal architecture of this module"] = SUBSYSTEM_DEPENDENCY; + //return_["This module depends on"] = EXTERNAL_DEPENDENCY; + //return_["Users of this module"] = EXTERNAL_USERS; + } + else if (file->type == "CS") + { + return_["File usage diagram"] = FILE_USAGES; + } + } } void CsharpServiceHandler::getFileDiagram( @@ -175,14 +194,17 @@ void CsharpServiceHandler::getFileDiagram( graph.setAttribute("rankdir", "LR"); switch (diagramId_){ - case 999: - model::FilePtr file= _transaction([&, this](){ + case 0: //FILE_USAGES + /* model::FilePtr file= _transaction([&, this](){ return _db->query_one( FileQuery::id == std::stoull(fileId_)); - }); + }); */ std::string data; - _csharpQueryHandler.getFileDiagram(data, file->path, diagramId_); - diagram.getTestDiagram(data, graph, fileId_); + //Gather data related to FILE_USAGES diagram + //Format $"{uses}:{revUses}" + _csharpQueryHandler.getFileDiagram(data, fileId_, diagramId_); + LOG(info) << "FILE USAGES data: " << data; + //diagram.getIncludeDependencyDiagram() break; } diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 78d91600b..6ddd4b56f 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -693,21 +693,35 @@ public async Task getFileDiagramAsync(string fileId, int diagramId, { switch (diagramId) { - case 999: - string astnodevalues = dbContext.CsharpAstNodes - .Where(a => a.Path == fileId) - .Select(a => a.AstValue) - .First() - .ToString(); - /*string parent = dbContext. - .Where(a => (a.id).ToString() == fileId) - .Select(a => a.parent) - .ToString(); - string parentInfo = dbContext.File - .Where(a => parent == a.id.ToString()) - .ToString(); - */ - return await Task.FromResult(astnodevalues); + case 0: //FILE_USAGES + //Gather files(IDs) which our file uses + var uses = dbContext.CsharpEdges + .Where(a => a.From.ToString() == fileId && + a.Type == EdgeType.USE) + .Select(a => a.To) + .ToList(); + + //Gather files(IDs) which use our file + var revUses = dbContext.CsharpEdges + .Where(a => a.To.ToString() == fileId && + a.Type == EdgeType.USE) + .Select(a => a.From) + .ToList(); + + //Store files(IDs) into string, uses and usedBys separated by ":" + string data = ""; + foreach(var use in uses) + { + data += $" {use.ToString()}"; + } + data += ":"; + foreach(var revUse in revUses) + { + data += $"{revUse.ToString()} "; + } + data.Trim(); + + return await Task.FromResult(data); break; } From deb1d6e7d4bf34f1aafe6ad7d750212b5079042a Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Wed, 19 Apr 2023 14:27:17 +0200 Subject: [PATCH 18/49] Diagrams :: Data conversion from string to vector The data we gather from the Csharp component in order to build the diagram needs to be converted in order to be useful. This means converting from a string which contains both the uses and the revuses to two vector instances to later pass on to the diagram generator functions. --- plugins/csharp/service/src/csharpservice.cpp | 26 ++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index df0b19275..933583019 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -4,6 +4,10 @@ #include #include +#include +#include +#include + #include "csharpfilediagram.h" namespace cc @@ -203,7 +207,29 @@ void CsharpServiceHandler::getFileDiagram( //Gather data related to FILE_USAGES diagram //Format $"{uses}:{revUses}" _csharpQueryHandler.getFileDiagram(data, fileId_, diagramId_); + boost::trim(data); LOG(info) << "FILE USAGES data: " << data; + + //Convert data into FileId vectors + std::string delimiter = ":"; + std::string uses = data.substr(0,data.find(delimiter)); + std::string revUses = data.substr(data.find(delimiter) + 1, std::string::npos); + + std::vector useIds; + boost::split(useIds, uses, boost::is_any_of(" "), boost::token_compress_on); + + std::vector revUseIds; + boost::split(revUseIds, revUses, boost::is_any_of(" "), boost::token_compress_on); + + for (auto &it : useIds) + { + LOG(info) << "USE_IDs: " << it ; + } + for (auto &it : revUseIds) + { + LOG(info) << "REVUSE_IDs: " << it ; + } + //LOG(info) << "USE_IDs: " << useIds[0] ;//<< " REVUSE_IDs: " << revUseIds[0]; //diagram.getIncludeDependencyDiagram() break; } From 078d5b059a5fa6980d81aa795932858cbcfa8cea Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Wed, 19 Apr 2023 23:06:49 +0200 Subject: [PATCH 19/49] Diagrams :: Provisional "File usage" diagram With this commit the first version of the file usage diagram shows, the first level of usages and revusages show. --- .../csharp/service/src/csharpfilediagram.cpp | 70 +++++++++++++++++-- .../csharp/service/src/csharpfilediagram.h | 12 +++- plugins/csharp/service/src/csharpservice.cpp | 4 +- 3 files changed, 74 insertions(+), 12 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index cf281ff6e..1b6efa243 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -90,23 +90,61 @@ std::string CsharpFileDiagram::getComponentUsersDiagramLegend() return builder.getOutput(); } */ -/* + void CsharpFileDiagram::getIncludeDependencyDiagram( util::Graph& graph_, - const core::FileId& fileId_) + const core::FileId& fileId_, + const std::vector& useIds, + const std::vector& revUseIds) { core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); -*/ + + //create nodes for use cases + std::vector usages; + for (const core::FileId& fileId: useIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + usages.push_back(addNode(graph_, fileInfo)); + LOG(info) << "FILEID TO NODE:" << fileId; + } + for (const util::Graph::Node& use: usages) + { + decorateNode(graph_, use, sourceFileNodeDecoration); + util::Graph::Edge useEdge = graph_.createEdge(currentNode, use); + decorateEdge(graph_, useEdge, usagesEdgeDecoration); + } + + //create nodes for revUse cases + std::vector revUsages; + for (const core::FileId& fileId: revUseIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + revUsages.push_back(addNode(graph_, fileInfo)); + LOG(info) << "FILEID TO NODE:" << fileId; + } + for (const util::Graph::Node& revUse: revUsages) + { + decorateNode(graph_, revUse, sourceFileNodeDecoration); + util::Graph::Edge revUseEdge = graph_.createEdge(currentNode, revUse); + decorateEdge(graph_, revUseEdge, revUsagesEdgeDecoration); + } + /* - util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getUsages, + util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getNodesFromIds, this, std::placeholders::_1, std::placeholders::_2), {}, usagesEdgeDecoration, 3); + LOG(info) << "<>"; - util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getRevUsages, + util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getNodesFromIds, this, std::placeholders::_1, std::placeholders::_2), {}, revUsagesEdgeDecoration, 3); + LOG(info) << "<>"; */ /* util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, this, std::placeholders::_1, std::placeholders::_2), @@ -114,8 +152,8 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevProvides, this, std::placeholders::_1, std::placeholders::_2), - {}, revUsagesEdgeDecoration, 3); -}*/ + {}, revUsagesEdgeDecoration, 3);*/ +} /* std::string CsharpFileDiagram::getIncludeDependencyDiagramLegend() { @@ -694,6 +732,24 @@ std::vector CsharpFileDiagram::getUsedFiles( return usages; } */ + +std::vector CsharpFileDiagram::getNodesFromIds( + util::Graph& graph, + const std::vector& fileIds) +{ + std::vector usages; + + for (const core::FileId& fileId: fileIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + + usages.push_back(addNode(graph, fileInfo)); + } + + return usages; +} + util::Graph::Node CsharpFileDiagram::addNode( util::Graph& graph_, const core::FileInfo& fileInfo_) diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index 64685edc2..2917e2b50 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -56,9 +56,11 @@ class CsharpFileDiagram /** * This diagram shows of the `#include` file dependencies. */ - //void getIncludeDependencyDiagram( - // util::Graph& graph_, - // const core::FileId& fileId_); + void getIncludeDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_, + const std::vector& useIds, + const std::vector& revUseIds); /** * This function creates legend for the Include dependency diagram. @@ -117,6 +119,10 @@ class CsharpFileDiagram private: typedef std::vector> Decoration; + std::vector getNodesFromIds( + util::Graph& graph, + const std::vector& fileIds); + /** * This function adds a node which represents a File node. The label of the * node is the file name. diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 933583019..4ce9a6d30 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -229,8 +229,8 @@ void CsharpServiceHandler::getFileDiagram( { LOG(info) << "REVUSE_IDs: " << it ; } - //LOG(info) << "USE_IDs: " << useIds[0] ;//<< " REVUSE_IDs: " << revUseIds[0]; - //diagram.getIncludeDependencyDiagram() + + diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); break; } From 21d5ce3560c98489ea554b8f770d1cff6cccc0ca Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 22 Apr 2023 16:22:09 +0200 Subject: [PATCH 20/49] Diagrams :: Fix diagrams now showing in some instances The diagram didnt show in cases where either it didnt have uses or revuses, this commit fixes this issue. --- .../csharp/service/src/csharpfilediagram.cpp | 54 ++++++++++--------- plugins/csharp/service/src/csharpservice.cpp | 8 +++ 2 files changed, 38 insertions(+), 24 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 1b6efa243..242a0f97a 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -102,37 +102,43 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( util::Graph::Node currentNode = addNode(graph_, fileInfo); //create nodes for use cases - std::vector usages; - for (const core::FileId& fileId: useIds) + if (!useIds.empty()) { - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId); + std::vector usages; + for (const core::FileId& fileId: useIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); - usages.push_back(addNode(graph_, fileInfo)); - LOG(info) << "FILEID TO NODE:" << fileId; - } - for (const util::Graph::Node& use: usages) - { - decorateNode(graph_, use, sourceFileNodeDecoration); - util::Graph::Edge useEdge = graph_.createEdge(currentNode, use); - decorateEdge(graph_, useEdge, usagesEdgeDecoration); + usages.push_back(addNode(graph_, fileInfo)); + LOG(info) << "FILEID TO NODE:" << fileId; + } + for (const util::Graph::Node& use: usages) + { + decorateNode(graph_, use, sourceFileNodeDecoration); + util::Graph::Edge useEdge = graph_.createEdge(currentNode, use); + decorateEdge(graph_, useEdge, usagesEdgeDecoration); + } } //create nodes for revUse cases - std::vector revUsages; - for (const core::FileId& fileId: revUseIds) + if (!revUseIds.empty()) { - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId); + std::vector revUsages; + for (const core::FileId& fileId: revUseIds) + { + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); - revUsages.push_back(addNode(graph_, fileInfo)); - LOG(info) << "FILEID TO NODE:" << fileId; - } - for (const util::Graph::Node& revUse: revUsages) - { - decorateNode(graph_, revUse, sourceFileNodeDecoration); - util::Graph::Edge revUseEdge = graph_.createEdge(currentNode, revUse); - decorateEdge(graph_, revUseEdge, revUsagesEdgeDecoration); + revUsages.push_back(addNode(graph_, fileInfo)); + LOG(info) << "FILEID TO NODE:" << fileId; + } + for (const util::Graph::Node& revUse: revUsages) + { + decorateNode(graph_, revUse, sourceFileNodeDecoration); + util::Graph::Edge revUseEdge = graph_.createEdge(currentNode, revUse); + decorateEdge(graph_, revUseEdge, revUsagesEdgeDecoration); + } } /* diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 4ce9a6d30..981d4968b 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -217,9 +217,17 @@ void CsharpServiceHandler::getFileDiagram( std::vector useIds; boost::split(useIds, uses, boost::is_any_of(" "), boost::token_compress_on); + if (useIds.size() == 1 && useIds[0].empty()) { + useIds.clear(); + } + LOG(info) << "useIds size: " << useIds.size(); std::vector revUseIds; boost::split(revUseIds, revUses, boost::is_any_of(" "), boost::token_compress_on); + if (revUseIds.size() == 1 && revUseIds[0].empty()) { + revUseIds.clear(); + } + LOG(info) << "revUseIds size: " << revUseIds.size(); for (auto &it : useIds) { From 1c980e24119b14baf7833be9847f34884544d666 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 23 Apr 2023 19:32:26 +0200 Subject: [PATCH 21/49] Diagrams :: Extend "File Usage Diagram" With this commit the file usage diagram is extended with further information, meaning more children are added to the diagram. This was achieved by using a BFS in the c# component to gather the data into a dictionary and passed along to the diagram building function. --- plugins/csharp/service/csharpservice.thrift | 3 + .../service/include/service/csharpservice.h | 14 + .../csharp/service/src/csharpfilediagram.cpp | 102 +++++--- .../csharp/service/src/csharpfilediagram.h | 4 +- plugins/csharp/service/src/csharpservice.cpp | 87 ++++--- .../service/src_csharp/CSharpQueryHandler.cs | 244 ++++++++++++++++-- 6 files changed, 356 insertions(+), 98 deletions(-) diff --git a/plugins/csharp/service/csharpservice.thrift b/plugins/csharp/service/csharpservice.thrift index fcf5e50da..d8b424572 100644 --- a/plugins/csharp/service/csharpservice.thrift +++ b/plugins/csharp/service/csharpservice.thrift @@ -61,4 +61,7 @@ service CsharpService string getFileDiagram(1:common.FileId fileId, 2:i32 diagramId) throws (1:common.InvalidId exId, 2:common.Timeout exLong) + + map> getFileUsages(1:common.FileId fileId, 2:bool reverse) + throws (1:common.InvalidId exId, 2:common.Timeout exLong) } \ No newline at end of file diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index d39c6b9e5..e0ee9b7cc 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -220,6 +220,14 @@ class CSharpQueryHandler : public CsharpServiceIf _service -> getFileDiagram(return_, fileId_, diagramId_); } + void getFileUsages( + std::map>& return_, + const core::FileId& fileId_, + const bool reverse_) override + { + _service -> getFileUsages(return_, fileId_, reverse_); + } + private: std::unique_ptr _service; static std::stringstream _thriftStream; @@ -337,6 +345,12 @@ class CsharpServiceHandler : virtual public LanguageServiceIf std::vector& return_, const core::FileRange& range_) override; + // void getFileUsages( + // std::map>& return_, + // const core::FileId& fileId_, + // const bool reverse_) override; + + private: enum DiagramType diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 242a0f97a..0c61acef6 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -94,50 +94,94 @@ std::string CsharpFileDiagram::getComponentUsersDiagramLegend() void CsharpFileDiagram::getIncludeDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_, - const std::vector& useIds, - const std::vector& revUseIds) + const std::map>& useIds, + const std::map>& revUseIds) { core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); + // //create nodes for use cases + // if (!useIds.empty()) + // { + // std::vector usages; + // for (const core::FileId& fileId: useIds) + // { + // core::FileInfo fileInfo; + // _projectHandler.getFileInfo(fileInfo, fileId); + + // usages.push_back(addNode(graph_, fileInfo)); + // LOG(info) << "FILEID TO NODE:" << fileId; + // } + // for (const util::Graph::Node& use: usages) + // { + // decorateNode(graph_, use, sourceFileNodeDecoration); + // util::Graph::Edge useEdge = graph_.createEdge(currentNode, use); + // decorateEdge(graph_, useEdge, usagesEdgeDecoration); + // } + // } + + // //create nodes for revUse cases + // if (!revUseIds.empty()) + // { + // std::vector revUsages; + // for (const core::FileId& fileId: revUseIds) + // { + // core::FileInfo fileInfo; + // _projectHandler.getFileInfo(fileInfo, fileId); + + // revUsages.push_back(addNode(graph_, fileInfo)); + // LOG(info) << "FILEID TO NODE:" << fileId; + // } + // for (const util::Graph::Node& revUse: revUsages) + // { + // decorateNode(graph_, revUse, sourceFileNodeDecoration); + // util::Graph::Edge revUseEdge = graph_.createEdge(currentNode, revUse); + // decorateEdge(graph_, revUseEdge, revUsagesEdgeDecoration); + // } + // } + //create nodes for use cases - if (!useIds.empty()) + for (const auto& entry : useIds) { - std::vector usages; - for (const core::FileId& fileId: useIds) + core::FileId fileId = entry.first; + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + + for (const auto& value : entry.second) { + core::FileId fileId = value; core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId); + util::Graph::Node toNode = addNode(graph_, fileInfo); - usages.push_back(addNode(graph_, fileInfo)); - LOG(info) << "FILEID TO NODE:" << fileId; - } - for (const util::Graph::Node& use: usages) - { - decorateNode(graph_, use, sourceFileNodeDecoration); - util::Graph::Edge useEdge = graph_.createEdge(currentNode, use); + util::Graph::Edge useEdge = graph_.createEdge(currentNode, toNode); decorateEdge(graph_, useEdge, usagesEdgeDecoration); + } } - //create nodes for revUse cases - if (!revUseIds.empty()) + //create nodes for revuse cases + for (const auto& entry : revUseIds) { - std::vector revUsages; - for (const core::FileId& fileId: revUseIds) + core::FileId fileId = entry.first; + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId); + util::Graph::Node currentNode = addNode(graph_, fileInfo); + decorateNode(graph_, currentNode, sourceFileNodeDecoration); + + for (const auto& value : entry.second) { + core::FileId fileId = value; core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId); + util::Graph::Node toNode = addNode(graph_, fileInfo); + + decorateNode(graph_, toNode, sourceFileNodeDecoration); + util::Graph::Edge useEdge = graph_.createEdge(currentNode, toNode); + decorateEdge(graph_, useEdge, revUsagesEdgeDecoration); - revUsages.push_back(addNode(graph_, fileInfo)); - LOG(info) << "FILEID TO NODE:" << fileId; - } - for (const util::Graph::Node& revUse: revUsages) - { - decorateNode(graph_, revUse, sourceFileNodeDecoration); - util::Graph::Edge revUseEdge = graph_.createEdge(currentNode, revUse); - decorateEdge(graph_, revUseEdge, revUsagesEdgeDecoration); } } @@ -771,17 +815,11 @@ util::Graph::Node CsharpFileDiagram::addNode( { decorateNode(graph_, node, binaryFileNodeDecoration); } - else if (fileInfo_.type == "CPP") + else if (fileInfo_.type == "CS") { std::string ext = boost::filesystem::extension(fileInfo_.path); std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower); - - if (ext == ".cpp" || ext == ".cxx" || ext == ".cc" || ext == ".c") - decorateNode(graph_, node, sourceFileNodeDecoration); - else if (ext == ".hpp" || ext == ".hxx" || ext == ".hh" || ext == ".h") - decorateNode(graph_, node, headerFileNodeDecoration); - else if (ext == ".o" || ext == ".so" || ext == ".dll") - decorateNode(graph_, node, objectFileNodeDecoration); + decorateNode(graph_, node, sourceFileNodeDecoration); } return node; diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index 2917e2b50..3cdb644c4 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -59,8 +59,8 @@ class CsharpFileDiagram void getIncludeDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_, - const std::vector& useIds, - const std::vector& revUseIds); + const std::map>& useIds, + const std::map>& revUseIds); /** * This function creates legend for the Include dependency diagram. diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 981d4968b..cde9d5232 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -199,46 +199,57 @@ void CsharpServiceHandler::getFileDiagram( switch (diagramId_){ case 0: //FILE_USAGES - /* model::FilePtr file= _transaction([&, this](){ - return _db->query_one( - FileQuery::id == std::stoull(fileId_)); - }); */ - std::string data; - //Gather data related to FILE_USAGES diagram - //Format $"{uses}:{revUses}" - _csharpQueryHandler.getFileDiagram(data, fileId_, diagramId_); - boost::trim(data); - LOG(info) << "FILE USAGES data: " << data; - - //Convert data into FileId vectors - std::string delimiter = ":"; - std::string uses = data.substr(0,data.find(delimiter)); - std::string revUses = data.substr(data.find(delimiter) + 1, std::string::npos); - - std::vector useIds; - boost::split(useIds, uses, boost::is_any_of(" "), boost::token_compress_on); - if (useIds.size() == 1 && useIds[0].empty()) { - useIds.clear(); - } - LOG(info) << "useIds size: " << useIds.size(); - - std::vector revUseIds; - boost::split(revUseIds, revUses, boost::is_any_of(" "), boost::token_compress_on); - if (revUseIds.size() == 1 && revUseIds[0].empty()) { - revUseIds.clear(); - } - LOG(info) << "revUseIds size: " << revUseIds.size(); - - for (auto &it : useIds) - { - LOG(info) << "USE_IDs: " << it ; - } - for (auto &it : revUseIds) - { - LOG(info) << "REVUSE_IDs: " << it ; - } + // std::string data; + // //Gather data related to FILE_USAGES diagram + // //Format $"{uses}:{revUses}" + // _csharpQueryHandler.getFileDiagram(data, fileId_, diagramId_); + // boost::trim(data); + // LOG(info) << "FILE USAGES data: " << data; + + // //Convert data into FileId vectors + // std::string delimiter = ":"; + // std::string uses = data.substr(0,data.find(delimiter)); + // std::string revUses = data.substr(data.find(delimiter) + 1, std::string::npos); + + // std::vector useIds; + // boost::split(useIds, uses, boost::is_any_of(" "), boost::token_compress_on); + // if (useIds.size() == 1 && useIds[0].empty()) { + // useIds.clear(); + // } + // LOG(info) << "useIds size: " << useIds.size(); + + // std::vector revUseIds; + // boost::split(revUseIds, revUses, boost::is_any_of(" "), boost::token_compress_on); + // if (revUseIds.size() == 1 && revUseIds[0].empty()) { + // revUseIds.clear(); + // } + // LOG(info) << "revUseIds size: " << revUseIds.size(); + + // for (auto &it : useIds) + // { + // LOG(info) << "USE_IDs: " << it ; + // } + // for (auto &it : revUseIds) + // { + // LOG(info) << "REVUSE_IDs: " << it ; + // } + // diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); + + std::map> useIds; + _csharpQueryHandler.getFileUsages(useIds,fileId_,false); + // for (const auto& entry : data){ + // LOG(info) << "Key: " << entry.first; + // LOG(info) << "Value:"; + // for (const auto& value : entry.second){ + // LOG(info) << value; + // } + // } + std::map> revUseIds; + _csharpQueryHandler.getFileUsages(revUseIds,fileId_,true); + diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); + break; } diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 6ddd4b56f..c086df8e5 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -695,37 +695,229 @@ public async Task getFileDiagramAsync(string fileId, int diagramId, { case 0: //FILE_USAGES //Gather files(IDs) which our file uses - var uses = dbContext.CsharpEdges - .Where(a => a.From.ToString() == fileId && - a.Type == EdgeType.USE) - .Select(a => a.To) - .ToList(); + // var uses = dbContext.CsharpEdges + // .Where(a => a.From.ToString() == fileId && + // a.Type == EdgeType.USE) + // .Select(a => a.To) + // .ToList(); - //Gather files(IDs) which use our file - var revUses = dbContext.CsharpEdges - .Where(a => a.To.ToString() == fileId && - a.Type == EdgeType.USE) - .Select(a => a.From) - .ToList(); - - //Store files(IDs) into string, uses and usedBys separated by ":" - string data = ""; - foreach(var use in uses) - { - data += $" {use.ToString()}"; - } - data += ":"; - foreach(var revUse in revUses) - { - data += $"{revUse.ToString()} "; - } - data.Trim(); - - return await Task.FromResult(data); + // //Gather files(IDs) which use our file + // var revUses = dbContext.CsharpEdges + // .Where(a => a.To.ToString() == fileId && + // a.Type == EdgeType.USE) + // .Select(a => a.From) + // .ToList(); + + // //Store files(IDs) into string, uses and usedBys separated by ":" + // string data = ""; + // foreach(var use in uses) + // { + // data += $" {use.ToString()}"; + // } + // data += ":"; + // foreach(var revUse in revUses) + // { + // data += $"{revUse.ToString()} "; + // } + // data.Trim(); + + // var table = dbContext.CsharpEdges + // .Where(a => a.Type == EdgeType.USE) + // .ToList(); + // var edges = new Dictionary>(); + // foreach (var row in table) + // { + // string from = row.From.ToString(); + // string to = row.To.ToString(); + // EdgeType type = row.Type; + + // if (!edges.ContainsKey(from)) + // { + // edges[from] = new List<(string, string)>(); + // } + // edges[from].Add((from,to)); + + // if (!edges.ContainsKey(to)) + // { + // edges[to] = new List<(string,string)>(); + // } + // edges[to].Add((from, to)); + // } + // foreach (var entry in edges) + // { + // var id = entry.Key; + // var fileEdges = entry.Value; + // Console.WriteLine($"File ID: {id}"); + // Console.WriteLine("Edges:"); + + // foreach(var edge in fileEdges) + // { + // Console.WriteLine($"From: {edge.Item1}, To: {edge.Item2}"); + // } + + // Console.WriteLine(); + // } + + // var reachableFilesDict = new Dictionary>(); + // foreach (var file in edges.Keys) + // { + // var reachableFiles = new List(); + // TraverseGraph(file, edges, reachableFiles, new HashSet()); + // reachableFilesDict[file] = reachableFiles; + // } + // foreach (var entry in reachableFilesDict) + // { + // var file = entry.Key; + // var filesReachable = entry.Value; + // Console.WriteLine($"File ID: {file}"); + // Console.WriteLine("Reachable Files:"); + + // foreach(var fileR in filesReachable) + // { + // Console.WriteLine($"{fileR}"); + // } + + // Console.WriteLine(); + // } + + return await Task.FromResult(""); break; } return await Task.FromResult("File Diagram"); } + public async Task>> getFileUsagesAsync(string fileId, bool reverse = false, + CancellationToken cancellationToken = default(CancellationToken)) + { + if (!reverse) + { + return await Task.FromResult(BFSBuild(fileId,getFileUsageIds,3)); + } + else + { + return await Task.FromResult(BFSBuild(fileId,getFileRevUsageIds,3)); + } + } + + private List getFileUsageIds(string fileId) + { + //Gather files(IDs) which our file uses + return dbContext.CsharpEdges + .Where(a => a.From.ToString() == fileId && + a.Type == EdgeType.USE) + .Select(a => a.To.ToString()) + .ToList(); + } + + private List getFileRevUsageIds(string fileId) + { + //Gather files(IDs) which use our file + return dbContext.CsharpEdges + .Where(a => a.To.ToString() == fileId && + a.Type == EdgeType.USE) + .Select(a => a.From.ToString()) + .ToList(); + } + + public static Dictionary> BFSBuild( + string startFile, + Func> relations, + int level = -1) + { + var visitedFiles = new Dictionary>(); + visitedFiles[startFile] = new List(); + + if (level < -1) + { + return visitedFiles; + } + + int currentLevel = 0; + Queue queue = new Queue(); + queue.Enqueue(startFile); + + bool walkLevel = true; + while (queue.Count > 0 && walkLevel) + { + string currentFile = queue.Dequeue(); + + foreach (string to in relations(currentFile)) + { + if (!visitedFiles.ContainsKey(to)) + { + visitedFiles[to] = new List(); + queue.Enqueue(to); + } + + visitedFiles[currentFile].Add(to); + } + + currentLevel++; + if (level != -1) + { + walkLevel = currentLevel != level; + } + } + + //LOG USED FILES + // foreach(var entry in visitedFiles) + // { + // Console.WriteLine("Key: ", entry.Key); + // Console.WriteLine("Values:"); + // foreach (string value in entry.Value) + // { + // Console.WriteLine(value); + // } + // } + return visitedFiles; + } + + + + // public static HashSet> BFSBuild( + // string startFile, + // Func> relations, + // int level = -1) + // { + // var visitedFiles = new HashSet>(); + // visitedFiles.Add(Tuple.Create("", startFile)); + + // if (level < -1) + // { + // return visitedFiles; + // } + + // int currentLevel = 0; + // Queue queue = new Queue(); + // queue.Enqueue(startFile); + + // bool walkLevel = true; + // while (queue.Count > 0 && walkLevel) + // { + // string currentFile = queue.Dequeue(); + + // foreach (string to in relations(currentFile)) + // { + // var tuple = Tuple.Create(currentFile, to); + // if (!visitedFiles.Contains(tuple)) + // { + // queue.Enqueue(to); + // visitedFiles.Add(tuple); + // } + // } + + // currentLevel++; + // if (level != -1) + // { + // walkLevel = currentLevel != level; + // } + // } + + // System.Console.WriteLine(visitedFiles); + // return visitedFiles; + // } + + + } \ No newline at end of file From 24c6e21fce0fcec843495f729dc8b10d1d9d6b74 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Mon, 24 Apr 2023 16:25:29 +0200 Subject: [PATCH 22/49] Diagrams :: File usage diagram now shows every use and revuse This commit enables that every possible edge is shown from a single file, not just until depth 3 is reached like before. --- plugins/csharp/service/src/csharpservice.cpp | 9 ++++----- plugins/csharp/service/src_csharp/CSharpQueryHandler.cs | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index cde9d5232..a762820bc 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -175,13 +175,12 @@ void CsharpServiceHandler::getFileDiagramTypes( { if (file->type == model::File::DIRECTORY_TYPE) { - //return_["Internal architecture of this module"] = SUBSYSTEM_DEPENDENCY; - //return_["This module depends on"] = EXTERNAL_DEPENDENCY; - //return_["Users of this module"] = EXTERNAL_USERS; + return_["Internal architecture of this module"] = SUBSYSTEM_DEPENDENCY; + return_["Users of this module"] = EXTERNAL_USERS; } else if (file->type == "CS") { - return_["File usage diagram"] = FILE_USAGES; + return_["File usage"] = FILE_USAGES; } } } @@ -198,7 +197,7 @@ void CsharpServiceHandler::getFileDiagram( graph.setAttribute("rankdir", "LR"); switch (diagramId_){ - case 0: //FILE_USAGES + case FILE_USAGES: //FILE_USAGES // std::string data; // //Gather data related to FILE_USAGES diagram // //Format $"{uses}:{revUses}" diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index c086df8e5..d07ab290c 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -792,11 +792,11 @@ public async Task>> getFileUsagesAsync(string fi { if (!reverse) { - return await Task.FromResult(BFSBuild(fileId,getFileUsageIds,3)); + return await Task.FromResult(BFSBuild(fileId,getFileUsageIds)); } else { - return await Task.FromResult(BFSBuild(fileId,getFileRevUsageIds,3)); + return await Task.FromResult(BFSBuild(fileId,getFileRevUsageIds)); } } From c3b1a0cc5f5646e78a5999062b2a8fd5eeafb545 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Mon, 24 Apr 2023 21:47:32 +0200 Subject: [PATCH 23/49] Diagrams :: Add internal structure diagram This commit adds the internal structure diagram aka the subsystem directory diagram. --- .../csharp/service/src/csharpfilediagram.cpp | 31 +++---------------- .../csharp/service/src/csharpfilediagram.h | 12 +++---- plugins/csharp/service/src/csharpservice.cpp | 7 +++++ 3 files changed, 18 insertions(+), 32 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 0c61acef6..7a1752134 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -369,7 +369,7 @@ std::string CsharpFileDiagram::getInterfaceDiagramLegend() return builder.getOutput(); } - +*/ void CsharpFileDiagram::getSubsystemDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_) @@ -384,29 +384,8 @@ void CsharpFileDiagram::getSubsystemDependencyDiagram( std::placeholders::_2), {}, subdirEdgeDecoration); subdirs.insert(currentNode); - - for (const util::Graph::Node& subdir : subdirs) - { - for (const util::Graph::Node& impl : getImplements(graph_, subdir)) - if (subdirs.find(impl) != subdirs.end()) - { - util::Graph::Edge edge = graph_.createEdge(subdir, impl); - decorateEdge(graph_, edge, implementsEdgeDecoration); - } - else - graph_.delNode(impl); - - for (const util::Graph::Node& dep : getDepends(graph_, subdir)) - if (subdirs.find(dep) != subdirs.end()) - { - util::Graph::Edge edge = graph_.createEdge(subdir, dep); - decorateEdge(graph_, edge, dependsEdgeDecoration); - } - else - graph_.delNode(dep); - } } - +/* std::string CsharpFileDiagram::getSubsystemDependencyDiagramLegend() { util::LegendBuilder builder("Subsystem Dependency Diagram"); @@ -466,8 +445,8 @@ std::vector CsharpFileDiagram::getRevIncludes( { return getIncludedFiles(graph_, node_, true); } - -std::vector FileDiagram::getSubDirs( +*/ +std::vector CsharpFileDiagram::getSubDirs( util::Graph& graph_, const util::Graph::Node& node_) { @@ -489,7 +468,7 @@ std::vector FileDiagram::getSubDirs( return usages; } - +/* std::vector CsharpFileDiagram::getImplements( util::Graph& graph_, const util::Graph::Node& node_) diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index 3cdb644c4..c73a250e2 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -87,9 +87,9 @@ class CsharpFileDiagram * of the queried module. This diagram is useful to understand the * relationships of the subdirectories (submodules) of a module. */ - //void getSubsystemDependencyDiagram( - // util::Graph& graph_, - // const core::FileId& fileId_); + void getSubsystemDependencyDiagram( + util::Graph& graph_, + const core::FileId& fileId_); /** * This function creates legend for the Subsystem dependency diagram. @@ -199,9 +199,9 @@ class CsharpFileDiagram * @param fileNode_ Graph file node object which represents a file object. * @return Subdirectory graph nodes. */ - //std::vector getSubDirs( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); + std::vector getSubDirs( + util::Graph& graph_, + const util::Graph::Node& fileNode_); /** * This function creates graph nodes for each files which files implements diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index a762820bc..6969be5ac 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -198,6 +198,7 @@ void CsharpServiceHandler::getFileDiagram( switch (diagramId_){ case FILE_USAGES: //FILE_USAGES + { // std::string data; // //Gather data related to FILE_USAGES diagram // //Format $"{uses}:{revUses}" @@ -250,6 +251,12 @@ void CsharpServiceHandler::getFileDiagram( diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); break; + } + case SUBSYSTEM_DEPENDENCY: + { + diagram.getSubsystemDependencyDiagram(graph,fileId_); + break; + } } if (graph.nodeCount() != 0) From 2be6eb5c38e7abda05d63210f31db8a5cfeb81c4 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Tue, 25 Apr 2023 14:19:13 +0200 Subject: [PATCH 24/49] Diagrams :: Gather data for External Users diagram Data gather in csharpservice.cpp --- plugins/csharp/service/src/csharpservice.cpp | 43 +++++++++++++++++++- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 6969be5ac..e4b68e6bd 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -17,6 +17,10 @@ namespace service namespace language { typedef odb::query FileQuery; +typedef odb::result FileResult; +typedef std::map> Usages; +//typedef std::map>>> DirectoryUsages; +typedef std::map> DirectoryUsages; namespace fs = boost::filesystem; namespace bp = boost::process; namespace pt = boost::property_tree; @@ -236,7 +240,7 @@ void CsharpServiceHandler::getFileDiagram( // diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); - std::map> useIds; + Usages useIds; _csharpQueryHandler.getFileUsages(useIds,fileId_,false); // for (const auto& entry : data){ // LOG(info) << "Key: " << entry.first; @@ -245,7 +249,7 @@ void CsharpServiceHandler::getFileDiagram( // LOG(info) << value; // } // } - std::map> revUseIds; + Usages revUseIds; _csharpQueryHandler.getFileUsages(revUseIds,fileId_,true); diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); @@ -257,6 +261,41 @@ void CsharpServiceHandler::getFileDiagram( diagram.getSubsystemDependencyDiagram(graph,fileId_); break; } + case EXTERNAL_USERS: + { + DirectoryUsages dirRevUsages; + + FileResult sub =_transaction([&, this]{ + return _db->query( + FileQuery::parent == std::stoull(fileId_) && + FileQuery::type == model::File::DIRECTORY_TYPE); + }); + //iterate on subddirectories and add a BFS to each CS file + //under the subdir + FileResult css; + for (const model::File& subdir : sub) + { + css = _transaction([&, this]{ + return _db->query( + FileQuery::parent == subdir.id && + FileQuery::type == "CS"); + }); + + std::vector revs; + Usages rev; + for (const model::File& cs : css) + { + std::string id = std::to_string(cs.id); + LOG(info) << "Converted CS ID: " << id; + _csharpQueryHandler.getFileUsages(rev,id,true); + revs.push_back(rev); + rev.clear(); + } + dirRevUsages[std::to_string(subdir.id)] = revs; + revs.clear(); + } + break; + } } if (graph.nodeCount() != 0) From 7b2b79b748e74de86d0dc214aa929fb6db3ea803 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Tue, 25 Apr 2023 16:15:05 +0200 Subject: [PATCH 25/49] Diagrams :: Remove some commented lines --- plugins/csharp/service/src/csharpservice.cpp | 43 ++------------------ 1 file changed, 3 insertions(+), 40 deletions(-) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index e4b68e6bd..eedfff9d1 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -203,43 +203,6 @@ void CsharpServiceHandler::getFileDiagram( switch (diagramId_){ case FILE_USAGES: //FILE_USAGES { - // std::string data; - // //Gather data related to FILE_USAGES diagram - // //Format $"{uses}:{revUses}" - // _csharpQueryHandler.getFileDiagram(data, fileId_, diagramId_); - // boost::trim(data); - // LOG(info) << "FILE USAGES data: " << data; - - // //Convert data into FileId vectors - // std::string delimiter = ":"; - // std::string uses = data.substr(0,data.find(delimiter)); - // std::string revUses = data.substr(data.find(delimiter) + 1, std::string::npos); - - // std::vector useIds; - // boost::split(useIds, uses, boost::is_any_of(" "), boost::token_compress_on); - // if (useIds.size() == 1 && useIds[0].empty()) { - // useIds.clear(); - // } - // LOG(info) << "useIds size: " << useIds.size(); - - // std::vector revUseIds; - // boost::split(revUseIds, revUses, boost::is_any_of(" "), boost::token_compress_on); - // if (revUseIds.size() == 1 && revUseIds[0].empty()) { - // revUseIds.clear(); - // } - // LOG(info) << "revUseIds size: " << revUseIds.size(); - - // for (auto &it : useIds) - // { - // LOG(info) << "USE_IDs: " << it ; - // } - // for (auto &it : revUseIds) - // { - // LOG(info) << "REVUSE_IDs: " << it ; - // } - - // diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); - Usages useIds; _csharpQueryHandler.getFileUsages(useIds,fileId_,false); // for (const auto& entry : data){ @@ -264,7 +227,6 @@ void CsharpServiceHandler::getFileDiagram( case EXTERNAL_USERS: { DirectoryUsages dirRevUsages; - FileResult sub =_transaction([&, this]{ return _db->query( FileQuery::parent == std::stoull(fileId_) && @@ -272,7 +234,10 @@ void CsharpServiceHandler::getFileDiagram( }); //iterate on subddirectories and add a BFS to each CS file //under the subdir + FileResult css; + std::vector revs; + Usages rev; for (const model::File& subdir : sub) { css = _transaction([&, this]{ @@ -281,8 +246,6 @@ void CsharpServiceHandler::getFileDiagram( FileQuery::type == "CS"); }); - std::vector revs; - Usages rev; for (const model::File& cs : css) { std::string id = std::to_string(cs.id); From 2b3fba5dc4a98b0d07a9231e86e517bc40bc2064 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Tue, 25 Apr 2023 19:42:02 +0200 Subject: [PATCH 26/49] Diagrams :: LOGs added to EXTERNAL_USERS case --- plugins/csharp/service/src/csharpservice.cpp | 59 ++++++++++++++++++-- 1 file changed, 54 insertions(+), 5 deletions(-) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index eedfff9d1..836ff823c 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -197,8 +197,11 @@ void CsharpServiceHandler::getFileDiagram( LOG(info) << "getFileDiagram"; CsharpFileDiagram diagram(_db,_datadir, _context); + LOG(info) << "1"; util::Graph graph; + LOG(info) << "2"; graph.setAttribute("rankdir", "LR"); + LOG(info) << "3"; switch (diagramId_){ case FILE_USAGES: //FILE_USAGES @@ -226,26 +229,70 @@ void CsharpServiceHandler::getFileDiagram( } case EXTERNAL_USERS: { + LOG(info) << "4"; DirectoryUsages dirRevUsages; - FileResult sub =_transaction([&, this]{ + LOG(info) << "5"; + + model::FilePtr directory = _transaction([&,this]{ + return _db->query_one( + FileQuery::id == std::stoull(fileId_) + ); + }); + LOG(info) << "6"; + FileResult directories = _transaction([&,this]{ return _db->query( - FileQuery::parent == std::stoull(fileId_) && FileQuery::type == model::File::DIRECTORY_TYPE); }); - //iterate on subddirectories and add a BFS to each CS file - //under the subdir + LOG(info) << "7"; + std::vector sub; + LOG(info) << "71"; + if (!directories.empty()) + { + if (directory) + { + for (const auto& dir : directories) + { + LOG(info) << "72"; + if (dir.path.find(directory->path) != std::string::npos) + { + LOG(info) << "73"; + sub.push_back(dir); + LOG(info) << "74"; + } + LOG(info) << "75"; + } + } + else + { + LOG(info) << "DIRECTORY ERROR"; + } + } + else + { + LOG(info) << "DIRECTORIES EMPTY"; + } + LOG(info) << "8"; + // FileResult sub =_transaction([&, this]{ + // return _db->query( + // FileQuery::parent == std::stoull(fileId_) && + // FileQuery::type == model::File::DIRECTORY_TYPE); + //}); + // iterate on subddirectories and add a BFS to each CS file + // under the subdir FileResult css; std::vector revs; Usages rev; + LOG(info) << "9"; for (const model::File& subdir : sub) { + LOG(info) << "10"; css = _transaction([&, this]{ return _db->query( FileQuery::parent == subdir.id && FileQuery::type == "CS"); }); - + LOG(info) << "11"; for (const model::File& cs : css) { std::string id = std::to_string(cs.id); @@ -254,9 +301,11 @@ void CsharpServiceHandler::getFileDiagram( revs.push_back(rev); rev.clear(); } + LOG(info) << "12"; dirRevUsages[std::to_string(subdir.id)] = revs; revs.clear(); } + LOG(info) << "13"; break; } } From 654f536cc2c675292dd7f25ca88da4d90e0eb98a Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Tue, 25 Apr 2023 23:24:04 +0200 Subject: [PATCH 27/49] Diagrams :: Segmentation fault fix on EXTERNAL USERS --- plugins/csharp/service/src/csharpservice.cpp | 84 +++++++++++--------- 1 file changed, 47 insertions(+), 37 deletions(-) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 836ff823c..232ef8dcd 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -238,39 +238,47 @@ void CsharpServiceHandler::getFileDiagram( FileQuery::id == std::stoull(fileId_) ); }); - LOG(info) << "6"; - FileResult directories = _transaction([&,this]{ - return _db->query( - FileQuery::type == model::File::DIRECTORY_TYPE); + LOG(info) << "6" << directory->path; + // FileResult directories = _transaction([&,this]{ + // return _db->query( + // FileQuery::type == model::File::DIRECTORY_TYPE); + // }); + + std::vector directories; + util::OdbTransaction {_db} ([&]() { + FileResult res = _db->query( + FileQuery::type == model::File::DIRECTORY_TYPE); + for (auto fp : res) + directories.push_back(std::make_shared(std::move(fp))); }); LOG(info) << "7"; - std::vector sub; - LOG(info) << "71"; - if (!directories.empty()) - { - if (directory) - { + std::vector sub; + // + // + // + // + // for (const auto& dir : directories) - { - LOG(info) << "72"; - if (dir.path.find(directory->path) != std::string::npos) - { - LOG(info) << "73"; - sub.push_back(dir); - LOG(info) << "74"; - } - LOG(info) << "75"; + { + LOG(info) << "71"; + // if (dir.path.find(directory->path) != std::string::npos) + // { + // LOG(info) << "72"; + // sub.push_back(dir); + // LOG(info) << "73"; + // } + // LOG(info) << "74"; } - } - else - { - LOG(info) << "DIRECTORY ERROR"; - } - } - else - { - LOG(info) << "DIRECTORIES EMPTY"; - } + // + // + // + // + // + // + // + // + // + // LOG(info) << "8"; // FileResult sub =_transaction([&, this]{ // return _db->query( @@ -280,29 +288,31 @@ void CsharpServiceHandler::getFileDiagram( // iterate on subddirectories and add a BFS to each CS file // under the subdir - FileResult css; + std::vector css; std::vector revs; Usages rev; LOG(info) << "9"; - for (const model::File& subdir : sub) + for (const model::FilePtr& subdir : sub) { LOG(info) << "10"; - css = _transaction([&, this]{ - return _db->query( - FileQuery::parent == subdir.id && + util::OdbTransaction {_db} ([&](){ + FileResult res = _db->query( + FileQuery::parent == subdir->id && FileQuery::type == "CS"); + for (auto fp : res) + css.push_back(std::make_shared(std::move(fp))); }); LOG(info) << "11"; - for (const model::File& cs : css) + for (const model::FilePtr& cs : css) { - std::string id = std::to_string(cs.id); + std::string id = std::to_string(cs->id); LOG(info) << "Converted CS ID: " << id; _csharpQueryHandler.getFileUsages(rev,id,true); revs.push_back(rev); rev.clear(); } LOG(info) << "12"; - dirRevUsages[std::to_string(subdir.id)] = revs; + dirRevUsages[std::to_string(subdir->id)] = revs; revs.clear(); } LOG(info) << "13"; From 1c5968b068925d61b78d0a6a7d9b7a9e4ab749a7 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Wed, 26 Apr 2023 19:06:12 +0200 Subject: [PATCH 28/49] Diagrams :: External Users diagram added With this commit the external users diagram can be visualized. It can be called upon a directory and it will show the directories sub directories and every external directory which uses one of our directory --- .../csharp/service/src/csharpfilediagram.cpp | 140 ++++++++---------- .../csharp/service/src/csharpfilediagram.h | 13 +- plugins/csharp/service/src/csharpservice.cpp | 77 ++++------ 3 files changed, 95 insertions(+), 135 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 7a1752134..f67e937e5 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -31,6 +31,8 @@ typedef odb::query SourceQuery; typedef odb::result SourceResult;*/ typedef odb::query FileQuery; typedef odb::result FileResult; +typedef std::map> Usages; +typedef std::map> DirectoryUsages; CsharpFileDiagram::CsharpFileDiagram( std::shared_ptr db_, @@ -94,55 +96,16 @@ std::string CsharpFileDiagram::getComponentUsersDiagramLegend() void CsharpFileDiagram::getIncludeDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_, - const std::map>& useIds, - const std::map>& revUseIds) + const Usages& useIds_, + const Usages& revUseIds_) { core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); - - // //create nodes for use cases - // if (!useIds.empty()) - // { - // std::vector usages; - // for (const core::FileId& fileId: useIds) - // { - // core::FileInfo fileInfo; - // _projectHandler.getFileInfo(fileInfo, fileId); - - // usages.push_back(addNode(graph_, fileInfo)); - // LOG(info) << "FILEID TO NODE:" << fileId; - // } - // for (const util::Graph::Node& use: usages) - // { - // decorateNode(graph_, use, sourceFileNodeDecoration); - // util::Graph::Edge useEdge = graph_.createEdge(currentNode, use); - // decorateEdge(graph_, useEdge, usagesEdgeDecoration); - // } - // } - - // //create nodes for revUse cases - // if (!revUseIds.empty()) - // { - // std::vector revUsages; - // for (const core::FileId& fileId: revUseIds) - // { - // core::FileInfo fileInfo; - // _projectHandler.getFileInfo(fileInfo, fileId); - - // revUsages.push_back(addNode(graph_, fileInfo)); - // LOG(info) << "FILEID TO NODE:" << fileId; - // } - // for (const util::Graph::Node& revUse: revUsages) - // { - // decorateNode(graph_, revUse, sourceFileNodeDecoration); - // util::Graph::Edge revUseEdge = graph_.createEdge(currentNode, revUse); - // decorateEdge(graph_, revUseEdge, revUsagesEdgeDecoration); - // } - // } + decorateNode(graph_, currentNode, centerNodeDecoration); //create nodes for use cases - for (const auto& entry : useIds) + for (const auto& entry : useIds_) { core::FileId fileId = entry.first; core::FileInfo fileInfo; @@ -163,13 +126,12 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( } //create nodes for revuse cases - for (const auto& entry : revUseIds) + for (const auto& entry : revUseIds_) { core::FileId fileId = entry.first; core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId); util::Graph::Node currentNode = addNode(graph_, fileInfo); - decorateNode(graph_, currentNode, sourceFileNodeDecoration); for (const auto& value : entry.second) { @@ -178,31 +140,11 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( _projectHandler.getFileInfo(fileInfo, fileId); util::Graph::Node toNode = addNode(graph_, fileInfo); - decorateNode(graph_, toNode, sourceFileNodeDecoration); util::Graph::Edge useEdge = graph_.createEdge(currentNode, toNode); decorateEdge(graph_, useEdge, revUsagesEdgeDecoration); } } - - /* - util::bfsBuild(graph_, currentNode,std::bind(&CsharpFileDiagram::getNodesFromIds, - this, std::placeholders::_1, std::placeholders::_2), - {}, usagesEdgeDecoration, 3); - LOG(info) << "<>"; - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getNodesFromIds, - this, std::placeholders::_1, std::placeholders::_2), - {}, revUsagesEdgeDecoration, 3); - LOG(info) << "<>"; - */ - /* util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, - this, std::placeholders::_1, std::placeholders::_2), - {}, usagesEdgeDecoration, 3); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevProvides, - this, std::placeholders::_1, std::placeholders::_2), - {}, revUsagesEdgeDecoration, 3);*/ } /* std::string CsharpFileDiagram::getIncludeDependencyDiagramLegend() @@ -272,32 +214,70 @@ std::string CsharpFileDiagram::getExternalDependencyDiagramLegend() return builder.getOutput(); } - +*/ void CsharpFileDiagram::getExternalUsersDiagram( util::Graph& graph_, - const core::FileId& fileId_) + const core::FileId& fileId_, + const DirectoryUsages& dirRevUsages_) { core::FileInfo fileInfo; _projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); decorateNode(graph_, currentNode, centerNodeDecoration); + + //to get the directory tree + getSubsystemDependencyDiagram(graph_,fileId_); - std::set subdirs = util::bfsBuild(graph_, currentNode, - std::bind(&CsharpFileDiagram::getSubDirs, this, std::placeholders::_1, - std::placeholders::_2), {}, subdirEdgeDecoration); - - for (const util::Graph::Node& subdir : subdirs) + //util::Graph::Node lastNode; + for (const auto& map : dirRevUsages_) { - util::bfsBuild(graph_, subdir,std::bind(&CsharpFileDiagram::getRevImplements, - this, std::placeholders::_1, std::placeholders::_2), - {}, revImplementsEdgeDecoration); - - util::bfsBuild(graph_, subdir,std::bind(&CsharpFileDiagram::getRevDepends, - this, std::placeholders::_1, std::placeholders::_2), - {}, revDependsEdgeDecoration); + core::FileId fileId = map.first; + core::FileInfo fInfo; + _projectHandler.getFileInfo(fInfo, fileId); + util::Graph::Node dirNode = addNode(graph_, fInfo); + // if (!lastNode.empty()) + // { + // if (!graph_.hasEdge(lastNode,dirNode)) + // { + // util::Graph::Edge subDirEdge = graph_.createEdge(lastNode,dirNode); + // decorateEdge(graph_, subDirEdge, subdirEdgeDecoration); + // } + // } + LOG(info) << "C# DIRECTORY: " << fInfo.path; + + for (const auto& innerMap : map.second) + { + for (const auto& revUseIds : innerMap) + { + for (const auto& revUseId : revUseIds.second) + { + core::FileInfo info; + LOG(info) << "C# FILES: " << info.path; + + _projectHandler.getFileInfo(info, revUseId); + if (info.path.find(fileInfo.path + '/') == std::string::npos) + { + core::FileInfo externalDirInfo; + _projectHandler.getFileInfo(externalDirInfo, info.parent); + LOG(info) << "C# EXTERNAL DIRECTORY: " << externalDirInfo.path; + util::Graph::Node externalDirNode = addNode(graph_,externalDirInfo); + + if (!graph_.hasEdge(dirNode,externalDirNode)) + { + util::Graph::Edge edge = graph_.createEdge(dirNode,externalDirNode); + decorateEdge(graph_, edge, revUsagesEdgeDecoration); + } + } + } + } + } + //lastNode = dirNode; } -} + + +} +/* std::string CsharpFileDiagram::getExternalUsersDiagramLegend() { util::LegendBuilder builder("External Users Diagram"); diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index c73a250e2..e113a68b3 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -15,6 +15,8 @@ namespace language { //namespace language = cc::service::language; +typedef std::map> Usages; +typedef std::map> DirectoryUsages; class CsharpFileDiagram { @@ -43,9 +45,10 @@ class CsharpFileDiagram * This diagram shows directories (modules) that are users of the * queried module. */ - //void getExternalUsersDiagram( - // util::Graph& graph_, - // const core::FileId& fileId_); + void getExternalUsersDiagram( + util::Graph& graph_, + const core::FileId& fileId_, + const DirectoryUsages& dirRevUsages_); /** * This function creates legend for the External users diagram. @@ -59,8 +62,8 @@ class CsharpFileDiagram void getIncludeDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_, - const std::map>& useIds, - const std::map>& revUseIds); + const Usages& useIds_, + const Usages& revUseIds_); /** * This function creates legend for the Include dependency diagram. diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 232ef8dcd..c5325e794 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -19,7 +19,6 @@ namespace language typedef odb::query FileQuery; typedef odb::result FileResult; typedef std::map> Usages; -//typedef std::map>>> DirectoryUsages; typedef std::map> DirectoryUsages; namespace fs = boost::filesystem; namespace bp = boost::process; @@ -229,21 +228,17 @@ void CsharpServiceHandler::getFileDiagram( } case EXTERNAL_USERS: { - LOG(info) << "4"; DirectoryUsages dirRevUsages; - LOG(info) << "5"; + //This is the main directory to which the diagram is called upon. model::FilePtr directory = _transaction([&,this]{ return _db->query_one( FileQuery::id == std::stoull(fileId_) ); }); - LOG(info) << "6" << directory->path; - // FileResult directories = _transaction([&,this]{ - // return _db->query( - // FileQuery::type == model::File::DIRECTORY_TYPE); - // }); + LOG(info) << "MAIN DIR PATH" << directory->path; + //This will contain all the directories from the project std::vector directories; util::OdbTransaction {_db} ([&]() { FileResult res = _db->query( @@ -251,50 +246,33 @@ void CsharpServiceHandler::getFileDiagram( for (auto fp : res) directories.push_back(std::make_shared(std::move(fp))); }); - LOG(info) << "7"; - std::vector sub; - // - // - // - // - // - for (const auto& dir : directories) - { - LOG(info) << "71"; - // if (dir.path.find(directory->path) != std::string::npos) - // { - // LOG(info) << "72"; - // sub.push_back(dir); - // LOG(info) << "73"; - // } - // LOG(info) << "74"; - } - // - // - // - // - // - // - // - // - // - // - LOG(info) << "8"; - // FileResult sub =_transaction([&, this]{ - // return _db->query( - // FileQuery::parent == std::stoull(fileId_) && - // FileQuery::type == model::File::DIRECTORY_TYPE); - //}); - // iterate on subddirectories and add a BFS to each CS file - // under the subdir - + + //Sub will contain all the directories which are subdirectories + //of main directory, including the main directory. + //Checking is done with the paths. + std::vector sub; + sub.push_back(directory); + for (const auto& dir : directories) + { + if (dir->path.find(directory->path + '/') != std::string::npos) + sub.push_back(dir); + } + + //LOGGING: check fetched directories + for (const auto& s : sub) + { + LOG(info) << s->path; + } + + // Iterate on subddirectories and add a BFS to each CS file + // under the subdir. + // Gather for each subdir every BFS for every CS file into + // dirRevUsages. std::vector css; std::vector revs; Usages rev; - LOG(info) << "9"; for (const model::FilePtr& subdir : sub) { - LOG(info) << "10"; util::OdbTransaction {_db} ([&](){ FileResult res = _db->query( FileQuery::parent == subdir->id && @@ -302,7 +280,6 @@ void CsharpServiceHandler::getFileDiagram( for (auto fp : res) css.push_back(std::make_shared(std::move(fp))); }); - LOG(info) << "11"; for (const model::FilePtr& cs : css) { std::string id = std::to_string(cs->id); @@ -311,11 +288,11 @@ void CsharpServiceHandler::getFileDiagram( revs.push_back(rev); rev.clear(); } - LOG(info) << "12"; dirRevUsages[std::to_string(subdir->id)] = revs; revs.clear(); + css.clear(); } - LOG(info) << "13"; + diagram.getExternalUsersDiagram(graph,fileId_,dirRevUsages); break; } } From e6c7a1ab429474de2b568af2a1e867378950f5e5 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 27 Apr 2023 22:55:14 +0200 Subject: [PATCH 29/49] Files :: Add new files, csharpdiagrams.cpp, .h --- plugins/csharp/service/CMakeLists.txt | 1 + plugins/csharp/service/src/csharpdiagram.cpp | 583 ++++++++++++++++++ plugins/csharp/service/src/csharpdiagram.h | 168 +++++ .../csharp/service/src/csharpfilediagram.h | 2 +- .../service/src_csharp/CSharpQueryHandler.cs | 144 +---- 5 files changed, 755 insertions(+), 143 deletions(-) create mode 100644 plugins/csharp/service/src/csharpdiagram.cpp create mode 100644 plugins/csharp/service/src/csharpdiagram.h diff --git a/plugins/csharp/service/CMakeLists.txt b/plugins/csharp/service/CMakeLists.txt index d0e43b80a..b3e7763cf 100644 --- a/plugins/csharp/service/CMakeLists.txt +++ b/plugins/csharp/service/CMakeLists.txt @@ -39,6 +39,7 @@ add_subdirectory(src_csharp) add_library(csharpservice SHARED src/csharpservice.cpp + src/csharpdiagram.cpp src/csharpfilediagram.cpp src/plugin.cpp) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp new file mode 100644 index 000000000..ec193ed16 --- /dev/null +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -0,0 +1,583 @@ +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "csharpdiagram.h" + +namespace +{ + +/** + * This function checks if the given container contains a specified value. + * @param v_ A container to inspect. + * @param val_ Value which will be searched. + * @return True if the container contains the value. + */ +template +bool contains(const Cont& c_, const typename Cont::value_type& val_) +{ + return std::find(c_.begin(), c_.end(), val_) != c_.end(); +} + +/** + * This function wraps the content to a HTML tag and adds attributes to it. + */ +std::string graphHtmlTag( + const std::string& tag_, + const std::string& content_, + const std::string& attr_ = "") +{ + return std::string("<") + .append(tag_) + .append(" ") + .append(attr_) + .append(">") + .append(content_) + .append(""); +} + +} + +namespace cc +{ +namespace service +{ +namespace language +{ + +CsharpDiagram::CsharpDiagram( + std::shared_ptr db_, + std::shared_ptr datadir_, + const cc::webserver::ServerContext& context_) + : _db(db_), + _transaction(db_), + _projectHandler(db_, datadir_, context_) +{ +} + +void CsharpDiagram::getClassCollaborationDiagram( + util::Graph& graph_, + const core::AstNodeId& astNodeId_) +{ + std::map visitedNodes; + std::map visitedEdges; + std::vector relatedNodes; + std::vector nodes; + +// graph_.setAttribute("rankdir", "BT"); + +// //--- Center node ---// + +// _cppHandler.getReferences( +// nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); + +// if (nodes.empty()) +// return; + +// AstNodeInfo nodeInfo = nodes.front(); + +// util::Graph::Node centerNode = addNode(graph_, nodeInfo); +// decorateNode(graph_, centerNode, centerClassNodeDecoration); +// visitedNodes[nodeInfo.id] = centerNode; +// relatedNodes.push_back(nodeInfo); + +// nodes.clear(); + +// //--- Types from which the queried type inherits ---// + +// _cppHandler.getReferences(nodes, nodeInfo.id, +// CppServiceHandler::INHERIT_FROM, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// util::Graph::Node inheritNode = addNode(graph_, node); +// graph_.setNodeAttribute(inheritNode, "label", +// node.astNodeValue, true); +// decorateNode(graph_, inheritNode, classNodeDecoration); + +// util::Graph::Edge edge = graph_.createEdge(centerNode, inheritNode); +// decorateEdge(graph_, edge, inheritClassEdgeDecoration); + +// visitedNodes[node.id] = inheritNode; +// relatedNodes.push_back(node); +// } + +// nodes.clear(); + +// //--- Types by which the queried type is inherited ---// + +// _cppHandler.getReferences(nodes, nodeInfo.id, +// CppServiceHandler::INHERIT_BY, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// util::Graph::Node inheritNode = addNode(graph_, node); +// graph_.setNodeAttribute(inheritNode, "label", +// node.astNodeValue, true); +// decorateNode(graph_, inheritNode, classNodeDecoration); + +// util::Graph::Edge edge = graph_.createEdge(inheritNode, centerNode); +// decorateEdge(graph_, edge, inheritClassEdgeDecoration); + +// visitedNodes[node.id] = inheritNode; +// relatedNodes.push_back(node); +// } + +// //--- Get related types for the current and related types ---// + +// for (const AstNodeInfo& relatedNode : relatedNodes) +// { +// std::vector dataMembers; +// _cppHandler.getReferences(dataMembers, relatedNode.id, +// CppServiceHandler::DATA_MEMBER, {}); + +// for (const AstNodeInfo& node : dataMembers) +// { +// std::vector types; +// _cppHandler.getReferences(types, node.id, CppServiceHandler::TYPE, {}); + +// if (types.empty()) +// continue; + +// AstNodeInfo typeInfo = types.front(); + +// util::Graph::Node typeNode; +// auto it = visitedNodes.find(typeInfo.id); +// if (it == visitedNodes.end()) +// { +// typeNode = addNode(graph_, typeInfo); +// decorateNode(graph_, typeNode, classNodeDecoration); +// visitedNodes.insert(it, std::make_pair(typeInfo.id, typeNode)); +// } +// else +// typeNode = it->second; + +// GraphNodePair graphEdge(visitedNodes[relatedNode.id], typeNode); +// auto edgeIt = visitedEdges.find(graphEdge); +// if (edgeIt == visitedEdges.end()) +// { +// util::Graph::Edge edge = +// graph_.createEdge(visitedNodes[relatedNode.id], typeNode); +// decorateEdge(graph_, edge, usedClassEdgeDecoration); +// graph_.setEdgeAttribute(edge, "label", node.astNodeValue); +// visitedEdges.insert(edgeIt, std::make_pair(graphEdge, edge)); +// } +// else +// { +// std::string oldLabel = graph_.getEdgeAttribute(edgeIt->second, "label"); +// graph_.setEdgeAttribute(edgeIt->second, "label", +// oldLabel + ", " + node.astNodeValue); +// } +// } +// } +} + +void CsharpDiagram::getFunctionCallDiagram( + util::Graph& graph_, + const core::AstNodeId& astNodeId_) +{ + std::map visitedNodes; + std::vector nodes; + +// graph_.setAttribute("rankdir", "LR"); + +// //--- Center node ---// + +// _cppHandler.getReferences( +// nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); + +// if (nodes.empty()) +// return; + +// util::Graph::Node centerNode = addNode(graph_, nodes.front()); +// decorateNode(graph_, centerNode, centerNodeDecoration); +// visitedNodes[astNodeId_] = centerNode; + +// //--- Callees ---// + +// nodes.clear(); +// _cppHandler.getReferences(nodes, astNodeId_, CppServiceHandler::CALLEE, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// util::Graph::Node calleeNode; + +// auto it = visitedNodes.find(node.id); +// if (it == visitedNodes.end()) +// { +// calleeNode = addNode(graph_, node); +// decorateNode(graph_, calleeNode, calleeNodeDecoration); +// visitedNodes.insert(it, std::make_pair(node.id, calleeNode)); +// } +// else +// calleeNode = it->second; + +// if (!graph_.hasEdge(centerNode, calleeNode)) +// { +// util::Graph::Edge edge = graph_.createEdge(centerNode, calleeNode); +// decorateEdge(graph_, edge, calleeEdgeDecoration); +// } +// } + +// //--- Callers ---// + +// nodes.clear(); +// _cppHandler.getReferences(nodes, astNodeId_, CppServiceHandler::CALLER, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// util::Graph::Node callerNode; + +// auto it = visitedNodes.find(node.id); +// if (it == visitedNodes.end()) +// { +// callerNode = addNode(graph_, node); +// decorateNode(graph_, callerNode, callerNodeDecoration); +// visitedNodes.insert(it, std::make_pair(node.id, callerNode)); +// } +// else +// callerNode = it->second; + +// if (!graph_.hasEdge(callerNode, centerNode)) +// { +// util::Graph::Edge edge = graph_.createEdge(callerNode, centerNode); +// decorateEdge(graph_, edge, callerEdgeDecoration); +// } +// } + +// _subgraphs.clear(); +// } + +// void CsharpDiagram::getDetailedClassDiagram( +// util::Graph& graph_, +// const core::AstNodeId& astNodeId_) +// { +// std::vector nodes; + +// graph_.setAttribute("rankdir", "BT"); + +// //--- Center node ---// + +// _cppHandler.getReferences( +// nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); + +// if (nodes.empty()) +// return; + +// AstNodeInfo nodeInfo = nodes.front(); + +// util::Graph::Node currentNode = addNode(graph_, nodeInfo); +// graph_.setNodeAttribute(currentNode, "label", +// getDetailedClassNodeLabel(nodeInfo), true); +// graph_.setNodeAttribute(currentNode, "shape", "none"); + +// nodes.clear(); + +// //--- Types from which the queried type inherits ---// + +// _cppHandler.getReferences(nodes, nodeInfo.id, +// CppServiceHandler::INHERIT_FROM, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// util::Graph::Node inheritNode = addNode(graph_, node); +// graph_.setNodeAttribute(inheritNode, "label", +// getDetailedClassNodeLabel(node), true); +// graph_.setNodeAttribute(inheritNode, "shape", "none"); + +// util::Graph::Edge edge = graph_.createEdge(currentNode, inheritNode); +// decorateEdge(graph_, edge, inheritClassEdgeDecoration); +// } + +// nodes.clear(); + +// //--- Types by which the queried type is inherited ---// + +// _cppHandler.getReferences(nodes, nodeInfo.id, +// CppServiceHandler::INHERIT_BY, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// util::Graph::Node inheritNode = addNode(graph_, node); +// graph_.setNodeAttribute(inheritNode, "label", +// getDetailedClassNodeLabel(node), true); +// graph_.setNodeAttribute(inheritNode, "shape", "none"); + +// util::Graph::Edge edge = graph_.createEdge(inheritNode, currentNode); +// decorateEdge(graph_, edge, inheritClassEdgeDecoration); +// } +} + +std::string CsharpDiagram::getDetailedClassNodeLabel(const AstNodeInfo& nodeInfo_) +{ + std::string colAttr = "border='0' align='left'"; + std::string label = ""; + + label.append(graphHtmlTag("tr", graphHtmlTag("td", + graphHtmlTag("font", + util::escapeHtml(nodeInfo_.astNodeValue), "color='white'"), + "colspan='2' SIDES='B' bgcolor='#316ECF' align='center'"))); + + std::vector nodes; + +// //--- Data members of the class ---// + +// _cppHandler.getReferences(nodes, nodeInfo_.id, +// CppServiceHandler::DATA_MEMBER, {}); + +// for (auto it = nodes.begin(); it != nodes.end(); ++it) +// { +// std::string visibility = visibilityToHtml(*it); +// std::string content = memberContentToHtml(*it, +// util::escapeHtml(it->astNodeValue + " : " + getProperty(it->id, "Type"))); + +// std::string attr = colAttr; +// if (it == nodes.end() - 1) +// attr = "border='1' align='left' SIDES='B'"; + +// label += graphHtmlTag("tr", +// graphHtmlTag("td", visibility, attr) + +// graphHtmlTag("td", content, attr)); +// } + +// nodes.clear(); + +// //--- Methods of the class ---// + +// _cppHandler.getReferences(nodes, nodeInfo_.id, +// CppServiceHandler::METHOD, {}); + +// for (const AstNodeInfo& node : nodes) +// { +// std::string visibility = visibilityToHtml(node); + +// // TODO: Constructor and Destructor signatures can be empty. +// if (!node.astNodeValue.empty()) +// { +// std::string content = memberContentToHtml(node, +// util::escapeHtml(node.astNodeValue)); + +// label += graphHtmlTag("tr", +// graphHtmlTag("td", visibility, colAttr) + +// graphHtmlTag("td", content, colAttr)); +// } +// } + +// label.append("
"); + + return label; +} + +std::string CsharpDiagram::visibilityToHtml(const AstNodeInfo& node_) +{ + if (contains(node_.tags, "public")) + return graphHtmlTag("font", "+", "color='green'"); + if (contains(node_.tags, "private")) + return graphHtmlTag("font", "-", "color='red'"); + if (contains(node_.tags, "protected")) + return graphHtmlTag("font", "#", "color='blue'"); + + return ""; +} + +std::string CsharpDiagram::memberContentToHtml( + const AstNodeInfo& node_, + const std::string& content_) +{ + std::string startTags; + std::string endTags; + + if (contains(node_.tags, "static")) + { + startTags += ""; + endTags.insert(0, ""); + } + + if (contains(node_.tags, "virtual")) + { + startTags += ""; + endTags.insert(0, ""); + } + + return startTags + util::escapeHtml(content_) + endTags; +} + +// std::string CsharpDiagram::getProperty( +// const core::AstNodeId& astNodeId_, +// const std::string& property_) +// { +// std::map properties; +// _cppHandler.getProperties(properties, astNodeId_); +// return properties[property_]; +// } + +util::Graph::Node CsharpDiagram::addNode( + util::Graph& graph_, + const AstNodeInfo& nodeInfo_) +{ + util::Graph::Node node + = graph_.getOrCreateNode(nodeInfo_.id, + addSubgraph(graph_, nodeInfo_.range.file)); + + graph_.setNodeAttribute(node, "label", nodeInfo_.astNodeValue); + + return node; +} + +std::string CsharpDiagram::getDetailedClassLegend() +{ + util::LegendBuilder builder("Detailed Class CsharpDiagram"); + + builder.addNode("class", classNodeDecoration); + builder.addNode("public data member", {{"shape", "none"}, + {"label", graphHtmlTag("font", "+", "color='green'")}}, true); + builder.addNode("private data member", {{"shape", "none"}, + {"label", graphHtmlTag("font", "-", "color='red'")}}, true); + builder.addNode("protected data member", {{"shape", "none"}, + {"label", graphHtmlTag("font", "#", "color='blue'")}}, true); + builder.addNode("static method or data member", {{"shape", "none"}, + {"label", "static"}}, true); + builder.addNode("virtual method", {{"shape", "none"}, + {"label", "virtual"}}, true); + builder.addEdge("inheritance", inheritClassEdgeDecoration); + + return builder.getOutput(); +} + +std::string CsharpDiagram::getFunctionCallLegend() +{ + util::LegendBuilder builder("Function Call CsharpDiagram"); + + builder.addNode("center function", centerNodeDecoration); + builder.addNode("called function", calleeNodeDecoration); + builder.addNode("caller function", callerNodeDecoration); + builder.addNode("virtual function", virtualNodeDecoration); + builder.addEdge("called", calleeEdgeDecoration); + builder.addEdge("caller", callerEdgeDecoration); + + return builder.getOutput(); +} + +std::string CsharpDiagram::getClassCollaborationLegend() +{ + util::LegendBuilder builder("Class Collaboration CsharpDiagram"); + + builder.addNode("center class", centerClassNodeDecoration); + builder.addNode("class", classNodeDecoration); + builder.addEdge("contained or used class", usedClassEdgeDecoration); + builder.addEdge("inheritance", inheritClassEdgeDecoration); + + return builder.getOutput(); +} + +util::Graph::Subgraph CsharpDiagram::addSubgraph( + util::Graph& graph_, + const core::FileId& fileId_) +{ + auto it = _subgraphs.find(fileId_); + + if (it != _subgraphs.end()) + return it->second; + + core::FileInfo fileInfo; + _projectHandler.getFileInfo(fileInfo, fileId_); + + util::Graph::Subgraph subgraph + = graph_.getOrCreateSubgraph("cluster_" + fileInfo.path); + + graph_.setSubgraphAttribute(subgraph, "id", fileInfo.id); + graph_.setSubgraphAttribute(subgraph, "label", fileInfo.path); + + _subgraphs.insert(it, std::make_pair(fileInfo.path, subgraph)); + + return subgraph; +} + +void CsharpDiagram::decorateNode( + util::Graph& graph_, + const util::Graph::Node& node_, + const Decoration& decoration_) const +{ + for (const auto& attr : decoration_) + graph_.setNodeAttribute(node_, attr.first, attr.second); +} + +void CsharpDiagram::decorateEdge( + util::Graph& graph_, + const util::Graph::Edge& edge_, + const Decoration& decoration_) const +{ + for (const auto& attr : decoration_) + graph_.setEdgeAttribute(edge_, attr.first, attr.second); +} + +void CsharpDiagram::decorateSubgraph( + util::Graph& graph_, + const util::Graph::Subgraph& subgraph_, + const Decoration& decoration_) const +{ + for (const auto& attr : decoration_) + graph_.setSubgraphAttribute(subgraph_, attr.first, attr.second); +} + +const CsharpDiagram::Decoration CsharpDiagram::centerNodeDecoration = { + {"style", "filled"}, + {"fillcolor", "gold"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::calleeNodeDecoration = { + {"style", "filled"}, + {"fillcolor", "lightblue"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::callerNodeDecoration = { + {"style", "filled"}, + {"fillcolor", "coral"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::virtualNodeDecoration = { + {"shape", "diamond"}, + {"style", "filled"}, + {"fillcolor", "cyan"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::calleeEdgeDecoration = { + {"color", "blue"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::callerEdgeDecoration = { + {"color", "red"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::centerClassNodeDecoration = { + {"style", "filled"}, + {"fillcolor", "gold"}, + {"shape", "box"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::classNodeDecoration = { + {"shape", "box"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::usedClassEdgeDecoration = { + {"style", "dashed"}, + {"color", "mediumpurple"} +}; + +const CsharpDiagram::Decoration CsharpDiagram::inheritClassEdgeDecoration = { + {"arrowhead", "empty"} +}; + +} +} +} diff --git a/plugins/csharp/service/src/csharpdiagram.h b/plugins/csharp/service/src/csharpdiagram.h new file mode 100644 index 000000000..e93b363ab --- /dev/null +++ b/plugins/csharp/service/src/csharpdiagram.h @@ -0,0 +1,168 @@ +#ifndef CC_SERVICE_LANGUAGE_CSHARPDIAGRAM_H +#define CC_SERVICE_LANGUAGE_CSHARPDIAGRAM_H + +#include +#include +#include + +namespace cc +{ +namespace service +{ +namespace language +{ + +class CsharpDiagram +{ +public: + CsharpDiagram( + std::shared_ptr db_, + std::shared_ptr datadir_, + const cc::webserver::ServerContext& context_); + + void getFunctionCallDiagram( + util::Graph& graph_, + const core::AstNodeId& astNodeId_); + + /** + * This function creates legend for the Function call diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getFunctionCallLegend(); + + /** + * This is a classical UML class diagram for the selected class and its + * direct children and parents. The nodes contain the methods and member + * variables with their visibility. + */ + void getDetailedClassDiagram( + util::Graph& graph_, + const core::AstNodeId& astNodeId_); + + /** + * This function creates legend for the Detailed class diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getDetailedClassLegend(); + + /** + * This diagram for a class shows recursively the related classes and their + * inheritance and containment relationships. + */ + void getClassCollaborationDiagram( + util::Graph& graph_, + const core::AstNodeId& astNodeId_); + + /** + * This function creates legend for the Class collaboration diagram. + * @return The generated legend as a string in SVG format. + */ + std::string getClassCollaborationLegend(); + +private: + typedef std::vector> Decoration; + typedef std::pair GraphNodePair; + + /** + * This function adds a node which represents an AST node. The label of the + * node is the AST node value. A node associated with the file is added only + * once. If already added then the previous one is returned. + */ + util::Graph::Node addNode( + util::Graph& graph_, + const AstNodeInfo& nodeInfo_); + + /** + * This function adds a subgraph which represents a file. The label of the + * subgraph will be the file path and the subgraph will have a border. A + * subgraph associated with the file is added only once. If already added then + * the previous one is returned. + */ + util::Graph::Subgraph addSubgraph( + util::Graph& graph_, + const core::FileId& fileId_); + + /** + * This function creates node label for UML class diagram for the + * selected class. + */ + std::string getDetailedClassNodeLabel(const AstNodeInfo& nodeInfo_); + + /** + * This function return string representation visibility of an AST node + * in HTML format. + */ + std::string visibilityToHtml(const AstNodeInfo& node_); + + /** + * This function returns member content styled by their properties. + * (E.g.: static -> underline, virtual -> italic etc.) + */ + std::string memberContentToHtml( + const AstNodeInfo& node_, + const std::string& content_); + + /** + * This function returns the property of an AST node. + */ + std::string getProperty( + const core::AstNodeId& astNodeId_, + const std::string& property_); + + /** + * This function decorates a graph node. + * @param graph_ A graph object. + * @param elem_ A graph node + * @param decoration_ A map which describes the style attributes. + */ + void decorateNode( + util::Graph& graph_, + const util::Graph::Node& node_, + const Decoration& decoration_) const; + + /** + * This function decorates a graph edge. + * @param graph_ A graph object. + * @param elem_ A graph edge + * @param decoration_ A map which describes the style attributes. + */ + void decorateEdge( + util::Graph& graph_, + const util::Graph::Edge& edge_, + const Decoration& decoration_) const; + + /** + * This function decorates a graph subgraph. + * @param graph_ A graph object. + * @param elem_ A graph subgraph + * @param decoration_ A map which describes the style attributes. + */ + void decorateSubgraph( + util::Graph& graph_, + const util::Graph::Subgraph& subgrap_, + const Decoration& decoration_) const; + + static const Decoration centerNodeDecoration; + static const Decoration calleeNodeDecoration; + static const Decoration callerNodeDecoration; + static const Decoration virtualNodeDecoration; + static const Decoration calleeEdgeDecoration; + static const Decoration callerEdgeDecoration; + static const Decoration centerClassNodeDecoration; + static const Decoration classNodeDecoration; + static const Decoration usedClassEdgeDecoration; + static const Decoration inheritClassEdgeDecoration; + + std::map _subgraphs; + + //CppServiceHandler _cppHandler; + std::shared_ptr _db; + util::OdbTransaction _transaction; + core::ProjectServiceHandler _projectHandler; +}; + +} +} +} + +#endif diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index e113a68b3..7a4354d14 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -407,7 +407,7 @@ class CsharpFileDiagram std::shared_ptr _db; util::OdbTransaction _transaction; //CppServiceHandler _cppHandler; - cc::service::csharp::CSharpQueryHandler _csharpQueryHandler; + //cc::service::csharp::CSharpQueryHandler _csharpQueryHandler; core::ProjectServiceHandler _projectHandler; }; diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index d07ab290c..1d3d96f6a 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -683,6 +683,7 @@ public async Task getDiagramAsync(string astNodeId, int diagramId, public async Task> getFileDiagramTypesAsync(string fileId, CancellationToken cancellationToken = default(CancellationToken)) { + //TODO: DELETE return await Task.FromResult(new Dictionary(){ {"TEST DIAGRAM", 999} }); @@ -690,100 +691,7 @@ public async Task> getFileDiagramTypesAsync(string fileI public async Task getFileDiagramAsync(string fileId, int diagramId, CancellationToken cancellationToken = default(CancellationToken)) - { - switch (diagramId) - { - case 0: //FILE_USAGES - //Gather files(IDs) which our file uses - // var uses = dbContext.CsharpEdges - // .Where(a => a.From.ToString() == fileId && - // a.Type == EdgeType.USE) - // .Select(a => a.To) - // .ToList(); - - // //Gather files(IDs) which use our file - // var revUses = dbContext.CsharpEdges - // .Where(a => a.To.ToString() == fileId && - // a.Type == EdgeType.USE) - // .Select(a => a.From) - // .ToList(); - - // //Store files(IDs) into string, uses and usedBys separated by ":" - // string data = ""; - // foreach(var use in uses) - // { - // data += $" {use.ToString()}"; - // } - // data += ":"; - // foreach(var revUse in revUses) - // { - // data += $"{revUse.ToString()} "; - // } - // data.Trim(); - - // var table = dbContext.CsharpEdges - // .Where(a => a.Type == EdgeType.USE) - // .ToList(); - // var edges = new Dictionary>(); - // foreach (var row in table) - // { - // string from = row.From.ToString(); - // string to = row.To.ToString(); - // EdgeType type = row.Type; - - // if (!edges.ContainsKey(from)) - // { - // edges[from] = new List<(string, string)>(); - // } - // edges[from].Add((from,to)); - - // if (!edges.ContainsKey(to)) - // { - // edges[to] = new List<(string,string)>(); - // } - // edges[to].Add((from, to)); - // } - // foreach (var entry in edges) - // { - // var id = entry.Key; - // var fileEdges = entry.Value; - // Console.WriteLine($"File ID: {id}"); - // Console.WriteLine("Edges:"); - - // foreach(var edge in fileEdges) - // { - // Console.WriteLine($"From: {edge.Item1}, To: {edge.Item2}"); - // } - - // Console.WriteLine(); - // } - - // var reachableFilesDict = new Dictionary>(); - // foreach (var file in edges.Keys) - // { - // var reachableFiles = new List(); - // TraverseGraph(file, edges, reachableFiles, new HashSet()); - // reachableFilesDict[file] = reachableFiles; - // } - // foreach (var entry in reachableFilesDict) - // { - // var file = entry.Key; - // var filesReachable = entry.Value; - // Console.WriteLine($"File ID: {file}"); - // Console.WriteLine("Reachable Files:"); - - // foreach(var fileR in filesReachable) - // { - // Console.WriteLine($"{fileR}"); - // } - - // Console.WriteLine(); - // } - - return await Task.FromResult(""); - break; - } - + { return await Task.FromResult("File Diagram"); } @@ -872,52 +780,4 @@ public static Dictionary> BFSBuild( // } return visitedFiles; } - - - - // public static HashSet> BFSBuild( - // string startFile, - // Func> relations, - // int level = -1) - // { - // var visitedFiles = new HashSet>(); - // visitedFiles.Add(Tuple.Create("", startFile)); - - // if (level < -1) - // { - // return visitedFiles; - // } - - // int currentLevel = 0; - // Queue queue = new Queue(); - // queue.Enqueue(startFile); - - // bool walkLevel = true; - // while (queue.Count > 0 && walkLevel) - // { - // string currentFile = queue.Dequeue(); - - // foreach (string to in relations(currentFile)) - // { - // var tuple = Tuple.Create(currentFile, to); - // if (!visitedFiles.Contains(tuple)) - // { - // queue.Enqueue(to); - // visitedFiles.Add(tuple); - // } - // } - - // currentLevel++; - // if (level != -1) - // { - // walkLevel = currentLevel != level; - // } - // } - - // System.Console.WriteLine(visitedFiles); - // return visitedFiles; - // } - - - } \ No newline at end of file From fe7d19df48e5fe95ca0767ccab591dea674fa7ea Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Fri, 28 Apr 2023 17:25:15 +0200 Subject: [PATCH 30/49] Diagrams :: New diagram types show With this commit the new diagram types Function call diagram and Detailed class diagrams show as options when right clicking on either a function or a class. Also, CodeBites option is available. --- plugins/csharp/service/include/service/csharpservice.h | 1 + plugins/csharp/service/src/csharpservice.cpp | 8 +++++++- .../csharp/service/src_csharp/CSharpQueryHandler.cs | 10 ++++++++++ .../csharp/service/src_csharp/CSharpServiceEnums.cs | 2 ++ 4 files changed, 20 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index e0ee9b7cc..80e7d5314 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -356,6 +356,7 @@ class CsharpServiceHandler : virtual public LanguageServiceIf enum DiagramType { FILE_USAGES, + FUNCTION_CALL, /*!< In the function call diagram the nodes are functions and the edges are the function calls between them. The diagram also displays some dynamic information such as virtual function calls. */ diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index c5325e794..30d8ea18e 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -9,6 +9,7 @@ #include #include "csharpfilediagram.h" +#include "csharpdiagram.h" namespace cc { @@ -143,7 +144,7 @@ void CsharpServiceHandler::getDiagramTypes( const core::AstNodeId& astNodeId_) { LOG(info) << "getDiagramTypes"; - //_csharpQueryHandler.getDiagramTypes(return_, astNodeId_); + _csharpQueryHandler.getDiagramTypes(return_, astNodeId_); } void CsharpServiceHandler::getDiagram( @@ -152,6 +153,11 @@ void CsharpServiceHandler::getDiagram( const std::int32_t diagramId_) { LOG(info) << "getDiagram"; + CsharpDiagram diagram(_db,_datadir,_context); + util::Graph graph; + + + //_csharpQueryHandler.getDiagram(return_, astNodeId_, diagramId_); } diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 1d3d96f6a..a6e622f4a 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -664,6 +664,16 @@ public async Task getFileReferenceCountAsync(string path, int referenceId, public async Task> getDiagramTypesAsync(string astNodeId, CancellationToken cancellationToken = default(CancellationToken)) { + var node = queryCsharpAstNode(astNodeId); + + switch (node.AstSymbolType) + { + case AstSymbolTypeEnum.Method: + return await Task.FromResult(new Dictionary{ {"Function call diagram", (int)DiagramType.FUNCTION_CALL} }); + case AstSymbolTypeEnum.Class: + return await Task.FromResult(new Dictionary{ {"Detailed class diagram", (int)DiagramType.DETAILED_CLASS} }); + } + return await Task.FromResult(new Dictionary()); } diff --git a/plugins/csharp/service/src_csharp/CSharpServiceEnums.cs b/plugins/csharp/service/src_csharp/CSharpServiceEnums.cs index 8046956b6..93eeefe70 100644 --- a/plugins/csharp/service/src_csharp/CSharpServiceEnums.cs +++ b/plugins/csharp/service/src_csharp/CSharpServiceEnums.cs @@ -100,6 +100,8 @@ inclusion directive. */ enum DiagramType { +FILE_USAGES, + FUNCTION_CALL, /*!< In the function call diagram the nodes are functions and the edges are the function calls between them. The diagram also displays some dynamic information such as virtual function calls. */ From 30b63bb335616ac3beb94a0758e8c9f97261d46c Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 29 Apr 2023 17:54:04 +0200 Subject: [PATCH 31/49] Diagrams :: Function call diagram added This commit adds a first version of the function call diagram which can be visualized by right clicking on the declaration of a function --- .../service/include/service/csharpservice.h | 90 ++++++++++++++++++- plugins/csharp/service/src/csharpdiagram.cpp | 56 +++++++++--- plugins/csharp/service/src/csharpdiagram.h | 4 +- plugins/csharp/service/src/csharpservice.cpp | 47 ++++++++-- .../service/src_csharp/CSharpQueryHandler.cs | 18 +++- 5 files changed, 191 insertions(+), 24 deletions(-) diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index 80e7d5314..b5ae7d6d0 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -356,7 +356,7 @@ class CsharpServiceHandler : virtual public LanguageServiceIf enum DiagramType { FILE_USAGES, - + FUNCTION_CALL, /*!< In the function call diagram the nodes are functions and the edges are the function calls between them. The diagram also displays some dynamic information such as virtual function calls. */ @@ -398,6 +398,94 @@ enum DiagramType of a module. */ }; +enum ReferenceType + { + DEFINITION, /*!< By this option the definition(s) of the AST node can be + queried. However according to the "one definition rule" a named entity + can have only one definition, in a parsing several definitions might be + available. This is the case when the project is built for several targets + and in the different builds different definitions are defined for an + entity (e.g. because of an #ifdef section). */ + + DECLARATION, /*!< By this options the declaration(s) of the AST node can be + queried. */ + + USAGE, /*!< By this option the usages of the AST node can be queried, i.e. + the nodes of which the entity hash is identical to the queried one. */ + + THIS_CALLS, /*!< Get function calls in a function. WARNING: If the + definition of the AST node is not unique then it returns the callees of + one of them. */ + + CALLS_OF_THIS, /*!< Get calls of a function. */ + + CALLEE, /*!< Get called functions definitions. WARNING: If the definition of + the AST node is not unique then it returns the callees of one of them. */ + + CALLER, /*!< Get caller functions. */ + + VIRTUAL_CALL, /*!< A function may be used virtually on a base type object. + The exact type of the object is based on dynamic information, which can't + be determined statically. Weak usage returns these possible calls. */ + + FUNC_PTR_CALL, /*!< Functions can be assigned to function pointers which + can be invoked later. This option returns these invocations. */ + + PARAMETER, /*!< This option returns the parameters of a function. */ + + LOCAL_VAR, /*!< This option returns the local variables of a function. */ + + RETURN_TYPE, /*!< This option returns the return type of a function. */ + + OVERRIDE, /*!< This option returns the functions which the given function + overrides. */ + + OVERRIDDEN_BY, /*!< This option returns the overrides of a function. */ + + USAGEREAD, /*!< This option returns the places where a variable is read. */ + + WRITE, /*!< This option returns the places where a variable is written. */ + + READ, + TYPE, /*!< This option returns the type of a variable. */ + + ALIAS, /*!< Types may have aliases, e.g. by typedefs. */ + + INHERIT_FROM, /*!< Types from which the queried type inherits. */ + + INHERIT_BY, /*!< Types by which the queried type is inherited. */ + + DATA_MEMBER, /*!< Data members of a class. */ + + METHOD, /*!< Members of a class. */ + + FRIEND, /*!< The friends of a class. */ + + UNDERLYING_TYPE, /*!< Underlying type of a typedef. */ + + ENUM_CONSTANTS, /*!< Enum constants. */ + + EXPANSION, /*!< Macro expansion. */ + + UNDEFINITION, /*!< Macro undefinition. */ + + EVALUATION, // LINQ evaluation + + DATA_MODIFICATION, // LINQ underlying datadtruct is modified + + CONSTRUCTOR, + + DESTRUCTOR, + + OPERATOR, + + ACCESSOR, + + DELEGATE, + + EVENT + }; + std::shared_ptr _db; util::OdbTransaction _transaction; diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index ec193ed16..3003a6695 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -184,26 +184,55 @@ void CsharpDiagram::getClassCollaborationDiagram( void CsharpDiagram::getFunctionCallDiagram( util::Graph& graph_, - const core::AstNodeId& astNodeId_) + const AstNodeInfo& centerNodeInfo_, + const std::vector& calleeNodeInfos_, + const std::vector& callerNodeInfos_) { std::map visitedNodes; std::vector nodes; -// graph_.setAttribute("rankdir", "LR"); + graph_.setAttribute("rankdir", "LR"); -// //--- Center node ---// + // Center node + LOG(info) << "CENTER ASTNODE: " << centerNodeInfo_.astNodeValue; + AstNodeInfo nodeInfo = centerNodeInfo_; + nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); + util::Graph::Node centerNode = addNode(graph_, nodeInfo); + decorateNode(graph_, centerNode, centerNodeDecoration); +// visitedNodes[astNodeId_] = centerNode; -// _cppHandler.getReferences( -// nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); + // Callees -// if (nodes.empty()) -// return; + for (const auto& calleeNodeInfo : calleeNodeInfos_) + { + AstNodeInfo calleeInfo = calleeNodeInfo; + calleeInfo.astNodeValue = calleeInfo.astNodeValue.substr(0,calleeInfo.astNodeValue.find('{')); + util::Graph::Node calleeNode = addNode(graph_, calleeInfo); + decorateNode(graph_, centerNode, calleeNodeDecoration); + + if (!graph_.hasEdge(centerNode, calleeNode)) + { + util::Graph::Edge edge = graph_.createEdge(centerNode, calleeNode); + decorateEdge(graph_, edge, calleeEdgeDecoration); + } + } -// util::Graph::Node centerNode = addNode(graph_, nodes.front()); -// decorateNode(graph_, centerNode, centerNodeDecoration); -// visitedNodes[astNodeId_] = centerNode; + // Callers -// //--- Callees ---// + for (const auto& callerNodeInfo : callerNodeInfos_) + { + AstNodeInfo callerInfo = callerNodeInfo; + callerInfo.astNodeValue = callerInfo.astNodeValue.substr(0,callerInfo.astNodeValue.find('{')); + util::Graph::Node callerNode = addNode(graph_, callerInfo); + decorateNode(graph_, centerNode, callerNodeDecoration); + + if (!graph_.hasEdge(centerNode, callerNode)) + { + util::Graph::Edge edge = graph_.createEdge(callerNode, centerNode); + decorateEdge(graph_, edge, callerEdgeDecoration); + } + } + _subgraphs.clear(); // nodes.clear(); // _cppHandler.getReferences(nodes, astNodeId_, CppServiceHandler::CALLEE, {}); @@ -256,7 +285,7 @@ void CsharpDiagram::getFunctionCallDiagram( // } // _subgraphs.clear(); -// } + } // void CsharpDiagram::getDetailedClassDiagram( // util::Graph& graph_, @@ -316,7 +345,7 @@ void CsharpDiagram::getFunctionCallDiagram( // util::Graph::Edge edge = graph_.createEdge(inheritNode, currentNode); // decorateEdge(graph_, edge, inheritClassEdgeDecoration); // } -} +//} std::string CsharpDiagram::getDetailedClassNodeLabel(const AstNodeInfo& nodeInfo_) { @@ -425,6 +454,7 @@ util::Graph::Node CsharpDiagram::addNode( util::Graph& graph_, const AstNodeInfo& nodeInfo_) { + LOG(info) << "addNode: " << nodeInfo_.id << nodeInfo_.range.file; util::Graph::Node node = graph_.getOrCreateNode(nodeInfo_.id, addSubgraph(graph_, nodeInfo_.range.file)); diff --git a/plugins/csharp/service/src/csharpdiagram.h b/plugins/csharp/service/src/csharpdiagram.h index e93b363ab..960df7e82 100644 --- a/plugins/csharp/service/src/csharpdiagram.h +++ b/plugins/csharp/service/src/csharpdiagram.h @@ -22,7 +22,9 @@ class CsharpDiagram void getFunctionCallDiagram( util::Graph& graph_, - const core::AstNodeId& astNodeId_); + const AstNodeInfo& centerNodeInfo_, + const std::vector& calleeNodeInfos_, + const std::vector& callerNodeInfos_); /** * This function creates legend for the Function call diagram. diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 30d8ea18e..402abc040 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -81,9 +81,9 @@ void CsharpServiceHandler::getAstNodeInfo( FileQuery::path == return_.range.file); }); std::stringstream ss; - ss << file; + ss << file->id; // itt csak siman ss< calleeInfos; + getReferences(calleeInfos,astNodeId_,(int)ReferenceType::CALLEE,{}); + //logging purposes + for (const auto& info : calleeInfos){ + LOG(info) << "CalleeInfo: " << info.astNodeValue; + } + // Caller nodes + std::vector callerInfos; + getReferences(callerInfos,astNodeId_,(int)ReferenceType::CALLER,{}); + //logging purposes + for (const auto& info : calleeInfos){ + LOG(info) << "CallerInfo: " << info.astNodeValue; + } + diagram.getFunctionCallDiagram(graph,centerInfo,calleeInfos,callerInfos); + break; + } + } + + + if (graph.nodeCount() != 0) + return_ = graph.output(util::Graph::SVG); //_csharpQueryHandler.getDiagram(return_, astNodeId_, diagramId_); } @@ -202,11 +238,8 @@ void CsharpServiceHandler::getFileDiagram( LOG(info) << "getFileDiagram"; CsharpFileDiagram diagram(_db,_datadir, _context); - LOG(info) << "1"; util::Graph graph; - LOG(info) << "2"; graph.setAttribute("rankdir", "LR"); - LOG(info) << "3"; switch (diagramId_){ case FILE_USAGES: //FILE_USAGES @@ -336,7 +369,7 @@ void CsharpServiceHandler::getReferences( const std::int32_t referenceId_, const std::vector& tags_) { - //LOG(info) << "getReferences"; + LOG(info) << "getReferences"; _csharpQueryHandler.getReferences(return_, astNodeId_, referenceId_, tags_); std::vector ret; for (AstNodeInfo nodeinfo : return_) @@ -345,6 +378,8 @@ void CsharpServiceHandler::getReferences( return _db->query_one( FileQuery::path == nodeinfo.range.file); }); + LOG(info) << "getreferences: nodeInfo: " << nodeinfo.astNodeValue << " | " << nodeinfo.astNodeType; + LOG(info) << "getreferences: file: " << file->filename; std::stringstream ss; ss << file->id; diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index a6e622f4a..1009ea5f4 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -289,7 +289,7 @@ private List queryEvents(CsharpAstNode astNode) CancellationToken cancellationToken = default(CancellationToken)) { System.Console.WriteLine("[CSharpService] getAstNodeInfoAsync"); - return await Task.FromResult(new language.AstNodeInfo()); + return await Task.FromResult(createAstNodeInfo(queryCsharpAstNode(astNodeId))); } public async Task getAstNodeInfoByPositionAsync(string path_, @@ -574,15 +574,22 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, int referenceId, List tags, CancellationToken cancellationToken = default(CancellationToken)) { - var node = queryCsharpAstNode(astNodeId); + var node = queryCsharpAstNode(astNodeId); + Console.WriteLine("getreferencesasync NODE"); + Console.WriteLine("getreferencesasync astsymboltype: " + node.AstSymbolType); + Console.WriteLine("getreferencesasync asttype: " + node.AstType); + Console.WriteLine("getreferencesasync astvalue: " + node.AstValue); + Console.WriteLine("getreferencesasync reftype: " + (ReferenceType)referenceId); + Console.WriteLine("getreferencesasync refid: " + referenceId); var ret = new List(); switch ((ReferenceType)referenceId) { case ReferenceType.USAGE: - ret = createAstNodeInfoList(queryInvocations(node)); + return await Task.FromResult(createAstNodeInfoList(queryInvocations(node))); break; case ReferenceType.DEFINITION: case ReferenceType.DECLARATION: + Console.WriteLine("im in declaration"); ret = createAstNodeInfoList(queryDeclarators(node)); break; case ReferenceType.EVALUATION: @@ -598,6 +605,7 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, ret = createAstNodeInfoList(queryProperties(node)); break; case ReferenceType.THIS_CALLS: + Console.WriteLine("im in this_calls"); ret = createAstNodeInfoList(queryCalls(node)); break; case ReferenceType.CALLEE: @@ -635,6 +643,10 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, " ReferenceType is unhandled"); break; } + foreach(var r in ret){ + System.Console.WriteLine("getreferencesasync result: ",r.AstNodeType); + System.Console.WriteLine(r.AstNodeValue); + } return await Task.FromResult(ret); } From f9fd44f498290c3b1cf8c6a1cb08c2946e717825 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 30 Apr 2023 16:13:52 +0200 Subject: [PATCH 32/49] Diagrams :: Add Detailed Class diagram This commit adds the detailed class diagram which creates a UML diagram on the desired class. --- plugins/csharp/service/src/csharpdiagram.cpp | 179 ++++++------------ plugins/csharp/service/src/csharpdiagram.h | 9 +- plugins/csharp/service/src/csharpservice.cpp | 23 +++ .../service/src_csharp/CSharpQueryHandler.cs | 27 +-- 4 files changed, 108 insertions(+), 130 deletions(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 3003a6695..6359f66ce 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -188,9 +188,6 @@ void CsharpDiagram::getFunctionCallDiagram( const std::vector& calleeNodeInfos_, const std::vector& callerNodeInfos_) { - std::map visitedNodes; - std::vector nodes; - graph_.setAttribute("rankdir", "LR"); // Center node @@ -199,7 +196,6 @@ void CsharpDiagram::getFunctionCallDiagram( nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); util::Graph::Node centerNode = addNode(graph_, nodeInfo); decorateNode(graph_, centerNode, centerNodeDecoration); -// visitedNodes[astNodeId_] = centerNode; // Callees @@ -233,69 +229,26 @@ void CsharpDiagram::getFunctionCallDiagram( } } _subgraphs.clear(); - -// nodes.clear(); -// _cppHandler.getReferences(nodes, astNodeId_, CppServiceHandler::CALLEE, {}); - -// for (const AstNodeInfo& node : nodes) -// { -// util::Graph::Node calleeNode; - -// auto it = visitedNodes.find(node.id); -// if (it == visitedNodes.end()) -// { -// calleeNode = addNode(graph_, node); -// decorateNode(graph_, calleeNode, calleeNodeDecoration); -// visitedNodes.insert(it, std::make_pair(node.id, calleeNode)); -// } -// else -// calleeNode = it->second; - -// if (!graph_.hasEdge(centerNode, calleeNode)) -// { -// util::Graph::Edge edge = graph_.createEdge(centerNode, calleeNode); -// decorateEdge(graph_, edge, calleeEdgeDecoration); -// } -// } - -// //--- Callers ---// - -// nodes.clear(); -// _cppHandler.getReferences(nodes, astNodeId_, CppServiceHandler::CALLER, {}); - -// for (const AstNodeInfo& node : nodes) -// { -// util::Graph::Node callerNode; - -// auto it = visitedNodes.find(node.id); -// if (it == visitedNodes.end()) -// { -// callerNode = addNode(graph_, node); -// decorateNode(graph_, callerNode, callerNodeDecoration); -// visitedNodes.insert(it, std::make_pair(node.id, callerNode)); -// } -// else -// callerNode = it->second; - -// if (!graph_.hasEdge(callerNode, centerNode)) -// { -// util::Graph::Edge edge = graph_.createEdge(callerNode, centerNode); -// decorateEdge(graph_, edge, callerEdgeDecoration); -// } -// } - -// _subgraphs.clear(); } -// void CsharpDiagram::getDetailedClassDiagram( -// util::Graph& graph_, -// const core::AstNodeId& astNodeId_) -// { -// std::vector nodes; +void CsharpDiagram::getDetailedClassDiagram( + util::Graph& graph_, + const AstNodeInfo& centerNodeInfo_, + const std::vector& propertyNodeInfos_, + const std::vector& methodNodeInfos_) +{ + graph_.setAttribute("rankdir", "BT"); -// graph_.setAttribute("rankdir", "BT"); + // Center node -// //--- Center node ---// + //LOG(info) << "CENTER ASTNODE: " << centerNodeInfo_.astNodeValue; + AstNodeInfo nodeInfo = centerNodeInfo_; + nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); + util::Graph::Node centerNode = addNode(graph_, nodeInfo); + graph_.setNodeAttribute(centerNode,"label", + getDetailedClassNodeLabel(nodeInfo,propertyNodeInfos_,methodNodeInfos_), + true); + graph_.setNodeAttribute(centerNode,"shape", "none"); // _cppHandler.getReferences( // nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); @@ -345,75 +298,67 @@ void CsharpDiagram::getFunctionCallDiagram( // util::Graph::Edge edge = graph_.createEdge(inheritNode, currentNode); // decorateEdge(graph_, edge, inheritClassEdgeDecoration); // } -//} +} -std::string CsharpDiagram::getDetailedClassNodeLabel(const AstNodeInfo& nodeInfo_) +std::string CsharpDiagram::getDetailedClassNodeLabel( + const AstNodeInfo& centerNodeInfo_, + const std::vector& propertyNodeInfos_, + const std::vector& methodNodeInfos_) { std::string colAttr = "border='0' align='left'"; std::string label = ""; label.append(graphHtmlTag("tr", graphHtmlTag("td", graphHtmlTag("font", - util::escapeHtml(nodeInfo_.astNodeValue), "color='white'"), + util::escapeHtml(centerNodeInfo_.astNodeValue), "color='white'"), "colspan='2' SIDES='B' bgcolor='#316ECF' align='center'"))); - std::vector nodes; - -// //--- Data members of the class ---// - -// _cppHandler.getReferences(nodes, nodeInfo_.id, -// CppServiceHandler::DATA_MEMBER, {}); - -// for (auto it = nodes.begin(); it != nodes.end(); ++it) -// { -// std::string visibility = visibilityToHtml(*it); -// std::string content = memberContentToHtml(*it, -// util::escapeHtml(it->astNodeValue + " : " + getProperty(it->id, "Type"))); - -// std::string attr = colAttr; -// if (it == nodes.end() - 1) -// attr = "border='1' align='left' SIDES='B'"; + //--- Data members of the class -// label += graphHtmlTag("tr", -// graphHtmlTag("td", visibility, attr) + -// graphHtmlTag("td", content, attr)); -// } + for (auto it = propertyNodeInfos_.begin(); it != propertyNodeInfos_.end(); ++it) + { + std::string visibility = visibilityToHtml(*it); + std::string content = memberContentToHtml(*it, + util::escapeHtml(it->astNodeValue.substr(0,it->astNodeValue.find('{')))/* + " : " + getProperty(it->id, "Type")*/); -// nodes.clear(); + std::string attr = colAttr; + if (it == propertyNodeInfos_.end() - 1) + attr = "border='1' align='left' SIDES='B'"; -// //--- Methods of the class ---// + label += graphHtmlTag("tr", + graphHtmlTag("td", visibility, attr) + + graphHtmlTag("td", content, attr)); + } -// _cppHandler.getReferences(nodes, nodeInfo_.id, -// CppServiceHandler::METHOD, {}); + // Methods of the class -// for (const AstNodeInfo& node : nodes) -// { -// std::string visibility = visibilityToHtml(node); + for (const AstNodeInfo& node : methodNodeInfos_) + { + std::string visibility = visibilityToHtml(node); -// // TODO: Constructor and Destructor signatures can be empty. -// if (!node.astNodeValue.empty()) -// { -// std::string content = memberContentToHtml(node, -// util::escapeHtml(node.astNodeValue)); + if (!node.astNodeValue.empty()) + { + std::string content = memberContentToHtml(node, + util::escapeHtml(node.astNodeValue.substr(0,node.astNodeValue.find('{')))); -// label += graphHtmlTag("tr", -// graphHtmlTag("td", visibility, colAttr) + -// graphHtmlTag("td", content, colAttr)); -// } -// } + label += graphHtmlTag("tr", + graphHtmlTag("td", visibility, colAttr) + + graphHtmlTag("td", content, colAttr)); + } + } -// label.append("
"); + label.append(""); return label; } std::string CsharpDiagram::visibilityToHtml(const AstNodeInfo& node_) { - if (contains(node_.tags, "public")) + if (contains(node_.tags, "Public")) return graphHtmlTag("font", "+", "color='green'"); - if (contains(node_.tags, "private")) + if (contains(node_.tags, "Private")) return graphHtmlTag("font", "-", "color='red'"); - if (contains(node_.tags, "protected")) + if (contains(node_.tags, "Protected")) return graphHtmlTag("font", "#", "color='blue'"); return ""; @@ -426,13 +371,13 @@ std::string CsharpDiagram::memberContentToHtml( std::string startTags; std::string endTags; - if (contains(node_.tags, "static")) + if (contains(node_.tags, "Static")) { startTags += ""; endTags.insert(0, ""); } - if (contains(node_.tags, "virtual")) + if (contains(node_.tags, "Virtual")) { startTags += ""; endTags.insert(0, ""); @@ -441,14 +386,14 @@ std::string CsharpDiagram::memberContentToHtml( return startTags + util::escapeHtml(content_) + endTags; } -// std::string CsharpDiagram::getProperty( -// const core::AstNodeId& astNodeId_, -// const std::string& property_) -// { -// std::map properties; -// _cppHandler.getProperties(properties, astNodeId_); -// return properties[property_]; -// } +std::string CsharpDiagram::getProperty( + const core::AstNodeId& astNodeId_, + const std::string& property_) +{ + // std::map properties; + // _cppHandler.getProperties(properties, astNodeId_); + // return properties[property_]; +} util::Graph::Node CsharpDiagram::addNode( util::Graph& graph_, diff --git a/plugins/csharp/service/src/csharpdiagram.h b/plugins/csharp/service/src/csharpdiagram.h index 960df7e82..a401cd01e 100644 --- a/plugins/csharp/service/src/csharpdiagram.h +++ b/plugins/csharp/service/src/csharpdiagram.h @@ -39,7 +39,9 @@ class CsharpDiagram */ void getDetailedClassDiagram( util::Graph& graph_, - const core::AstNodeId& astNodeId_); + const AstNodeInfo& centerNodeInfo_, + const std::vector& propertyNodeInfos_, + const std::vector& methodNodeInfos_); /** * This function creates legend for the Detailed class diagram. @@ -88,7 +90,10 @@ class CsharpDiagram * This function creates node label for UML class diagram for the * selected class. */ - std::string getDetailedClassNodeLabel(const AstNodeInfo& nodeInfo_); + std::string getDetailedClassNodeLabel( + const AstNodeInfo& centerNodeInfo_, + const std::vector& propertyNodeInfos_, + const std::vector& methodNodeInfos_); /** * This function return string representation visibility of an AST node diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 402abc040..842d85740 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -189,6 +189,29 @@ void CsharpServiceHandler::getDiagram( diagram.getFunctionCallDiagram(graph,centerInfo,calleeInfos,callerInfos); break; } + case DETAILED_CLASS: + { + // Center node + AstNodeInfo centInfo; + getAstNodeInfo(centInfo,astNodeId_); + + //Data members - property nodes + std::vector propertyInfos; + getReferences(propertyInfos, astNodeId_,(int)ReferenceType::DATA_MEMBER,{}); + for (const auto& info : propertyInfos){ + LOG(info) << "PropertyInfo: " << info.astNodeValue; + } + + // Method nodes + std::vector methodInfos; + getReferences(methodInfos,astNodeId_,(int)ReferenceType::METHOD,{}); + for (const auto& info : methodInfos){ + LOG(info) << "MethodInfo: " << info.astNodeValue; + } + + diagram.getDetailedClassDiagram(graph,centInfo,propertyInfos,methodInfos); + break; + } } diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 1009ea5f4..2b9fe4ed0 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -258,7 +258,8 @@ private List queryEnumConsts(CsharpAstNode astNode) private List queryMethods(CsharpAstNode astNode) { var ret = dbContext.CsharpMethods - .Where(e => e.ParentNode.Id == astNode.Id) + .Where(e => e.ParentNode.Id == astNode.Id + && e.MethodType != MethodTypeEnum.Accessor) .Select(e => e.AstNode) .ToList(); return ret; @@ -575,21 +576,20 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, CancellationToken cancellationToken = default(CancellationToken)) { var node = queryCsharpAstNode(astNodeId); - Console.WriteLine("getreferencesasync NODE"); - Console.WriteLine("getreferencesasync astsymboltype: " + node.AstSymbolType); - Console.WriteLine("getreferencesasync asttype: " + node.AstType); - Console.WriteLine("getreferencesasync astvalue: " + node.AstValue); - Console.WriteLine("getreferencesasync reftype: " + (ReferenceType)referenceId); - Console.WriteLine("getreferencesasync refid: " + referenceId); + // Console.WriteLine("getreferencesasync NODE"); + // Console.WriteLine("getreferencesasync astsymboltype: " + node.AstSymbolType); + // Console.WriteLine("getreferencesasync asttype: " + node.AstType); + // Console.WriteLine("getreferencesasync astvalue: " + node.AstValue); + // Console.WriteLine("getreferencesasync reftype: " + (ReferenceType)referenceId); + // Console.WriteLine("getreferencesasync refid: " + referenceId); var ret = new List(); switch ((ReferenceType)referenceId) { case ReferenceType.USAGE: - return await Task.FromResult(createAstNodeInfoList(queryInvocations(node))); + ret = createAstNodeInfoList(queryInvocations(node)); break; case ReferenceType.DEFINITION: case ReferenceType.DECLARATION: - Console.WriteLine("im in declaration"); ret = createAstNodeInfoList(queryDeclarators(node)); break; case ReferenceType.EVALUATION: @@ -605,7 +605,6 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, ret = createAstNodeInfoList(queryProperties(node)); break; case ReferenceType.THIS_CALLS: - Console.WriteLine("im in this_calls"); ret = createAstNodeInfoList(queryCalls(node)); break; case ReferenceType.CALLEE: @@ -643,9 +642,15 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, " ReferenceType is unhandled"); break; } + System.Console.WriteLine("getreferencesasync result: "); foreach(var r in ret){ - System.Console.WriteLine("getreferencesasync result: ",r.AstNodeType); + System.Console.WriteLine("nodeinfo: ",r.AstNodeType); System.Console.WriteLine(r.AstNodeValue); + foreach(var tag in r.Tags) + { + System.Console.WriteLine(tag); + } + } return await Task.FromResult(ret); } From fd66dc9aeab42222df0cfcc81f7473b11624aadf Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 30 Apr 2023 16:30:45 +0200 Subject: [PATCH 33/49] Diagrams :: Add diagram legends This commit adds diagram legends to function call and detailed class diagrams. --- plugins/csharp/service/src/csharpdiagram.cpp | 2 +- plugins/csharp/service/src/csharpservice.cpp | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 6359f66ce..6d31f858f 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -424,7 +424,7 @@ std::string CsharpDiagram::getDetailedClassLegend() {"label", "static"}}, true); builder.addNode("virtual method", {{"shape", "none"}, {"label", "virtual"}}, true); - builder.addEdge("inheritance", inheritClassEdgeDecoration); + //builder.addEdge("inheritance", inheritClassEdgeDecoration); return builder.getOutput(); } diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 842d85740..3c230286f 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -225,6 +225,19 @@ void CsharpServiceHandler::getDiagramLegend( const std::int32_t diagramId_) { LOG(info) << "getDiagramLegend"; + + CsharpDiagram diagram(_db,_datadir, _context); + + switch (diagramId_) + { + case FUNCTION_CALL: + return_ = diagram.getFunctionCallLegend(); + break; + + case DETAILED_CLASS: + return_ = diagram.getDetailedClassLegend(); + break; + } } void CsharpServiceHandler::getFileDiagramTypes( From 43c824957c81253df1d66b94d365688a8f1a9975 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 30 Apr 2023 17:36:02 +0200 Subject: [PATCH 34/49] Diagrams :: Add file diagram legends --- .../csharp/service/src/csharpfilediagram.cpp | 55 ++++++------------- .../csharp/service/src/csharpfilediagram.h | 8 +-- plugins/csharp/service/src/csharpservice.cpp | 19 ++++++- 3 files changed, 38 insertions(+), 44 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index f67e937e5..6d60047d0 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -93,7 +93,7 @@ std::string CsharpFileDiagram::getComponentUsersDiagramLegend() } */ -void CsharpFileDiagram::getIncludeDependencyDiagram( +void CsharpFileDiagram::getFileUsagesDiagram( util::Graph& graph_, const core::FileId& fileId_, const Usages& useIds_, @@ -145,25 +145,23 @@ void CsharpFileDiagram::getIncludeDependencyDiagram( } } + + decorateNode(graph_, currentNode, centerNodeDecoration); } -/* -std::string CsharpFileDiagram::getIncludeDependencyDiagramLegend() + +std::string CsharpFileDiagram::getFileUsagesDiagramLegend() { - util::LegendBuilder builder("Include Dependency Diagram"); + util::LegendBuilder builder("File Usages Diagram"); - builder.addNode("center file", centerNodeDecoration); - builder.addNode("directory", directoryNodeDecoration); - builder.addNode("binary file", binaryFileNodeDecoration); + builder.addNode("center node", centerNodeDecoration); builder.addNode("source file", sourceFileNodeDecoration); - builder.addNode("header file", headerFileNodeDecoration); - builder.addNode("object file", objectFileNodeDecoration); builder.addEdge("uses", usagesEdgeDecoration); builder.addEdge("used by files", revUsagesEdgeDecoration); return builder.getOutput(); } - +/* void CsharpFileDiagram::getExternalDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_) @@ -228,22 +226,12 @@ void CsharpFileDiagram::getExternalUsersDiagram( //to get the directory tree getSubsystemDependencyDiagram(graph_,fileId_); - //util::Graph::Node lastNode; for (const auto& map : dirRevUsages_) { core::FileId fileId = map.first; core::FileInfo fInfo; _projectHandler.getFileInfo(fInfo, fileId); util::Graph::Node dirNode = addNode(graph_, fInfo); - // if (!lastNode.empty()) - // { - // if (!graph_.hasEdge(lastNode,dirNode)) - // { - // util::Graph::Edge subDirEdge = graph_.createEdge(lastNode,dirNode); - // decorateEdge(graph_, subDirEdge, subdirEdgeDecoration); - // } - // } - LOG(info) << "C# DIRECTORY: " << fInfo.path; for (const auto& innerMap : map.second) { @@ -252,14 +240,12 @@ void CsharpFileDiagram::getExternalUsersDiagram( for (const auto& revUseId : revUseIds.second) { core::FileInfo info; - LOG(info) << "C# FILES: " << info.path; _projectHandler.getFileInfo(info, revUseId); if (info.path.find(fileInfo.path + '/') == std::string::npos) { core::FileInfo externalDirInfo; _projectHandler.getFileInfo(externalDirInfo, info.parent); - LOG(info) << "C# EXTERNAL DIRECTORY: " << externalDirInfo.path; util::Graph::Node externalDirNode = addNode(graph_,externalDirInfo); if (!graph_.hasEdge(dirNode,externalDirNode)) @@ -271,31 +257,26 @@ void CsharpFileDiagram::getExternalUsersDiagram( } } } - //lastNode = dirNode; } } -/* + std::string CsharpFileDiagram::getExternalUsersDiagramLegend() { util::LegendBuilder builder("External Users Diagram"); builder.addNode("center file", centerNodeDecoration); builder.addNode("directory", directoryNodeDecoration); - builder.addNode("binary file", binaryFileNodeDecoration); builder.addNode("source file", sourceFileNodeDecoration); - builder.addNode("header file", headerFileNodeDecoration); - builder.addNode("object file", objectFileNodeDecoration); builder.addEdge("sub directory", subdirEdgeDecoration); - builder.addEdge("implemented by", revImplementsEdgeDecoration); - builder.addEdge("dependent on", revDependsEdgeDecoration); + builder.addEdge("used by", revUsagesEdgeDecoration); return builder.getOutput(); } - +/* void CsharpFileDiagram::getInterfaceDiagram( util::Graph& graph_, const core::FileId& fileId_) @@ -365,25 +346,19 @@ void CsharpFileDiagram::getSubsystemDependencyDiagram( subdirs.insert(currentNode); } -/* + std::string CsharpFileDiagram::getSubsystemDependencyDiagramLegend() { util::LegendBuilder builder("Subsystem Dependency Diagram"); builder.addNode("center file", centerNodeDecoration); builder.addNode("directory", directoryNodeDecoration); - builder.addNode("binary file", binaryFileNodeDecoration); - builder.addNode("source file", sourceFileNodeDecoration); - builder.addNode("header file", headerFileNodeDecoration); - builder.addNode("object file", objectFileNodeDecoration); builder.addEdge("sub directory", subdirEdgeDecoration); - builder.addEdge("implements", implementsEdgeDecoration); - builder.addEdge("depends on", dependsEdgeDecoration); return builder.getOutput(); } - +/* std::vector FileDiagram::getIncludedFiles( util::Graph& graph_, const util::Graph::Node& node_, @@ -816,8 +791,10 @@ std::string CsharpFileDiagram::getLastNParts(const std::string& path_, std::size } const CsharpFileDiagram::Decoration CsharpFileDiagram::centerNodeDecoration = { + {"shape", "ellipse"}, {"style", "filled"}, - {"fillcolor", "gold"} + {"fillcolor", "gold"}, + {"fontcolor", "black"} }; const CsharpFileDiagram::Decoration CsharpFileDiagram::sourceFileNodeDecoration = { diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index 7a4354d14..9878242d7 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -54,12 +54,12 @@ class CsharpFileDiagram * This function creates legend for the External users diagram. * @return The generated legend as a string in SVG format. */ - //std::string getExternalUsersDiagramLegend(); + std::string getExternalUsersDiagramLegend(); /** * This diagram shows of the `#include` file dependencies. */ - void getIncludeDependencyDiagram( + void getFileUsagesDiagram( util::Graph& graph_, const core::FileId& fileId_, const Usages& useIds_, @@ -69,7 +69,7 @@ class CsharpFileDiagram * This function creates legend for the Include dependency diagram. * @return The generated legend as a string in SVG format. */ - //std::string getIncludeDependencyDiagramLegend(); + std::string getFileUsagesDiagramLegend(); /** * Interface diagram shows the used and provided interfaces of a source code @@ -98,7 +98,7 @@ class CsharpFileDiagram * This function creates legend for the Subsystem dependency diagram. * @return The generated legend as a string in SVG format. */ - //std::string getSubsystemDependencyDiagramLegend(); + std::string getSubsystemDependencyDiagramLegend(); /** * Component users diagram for source file S shows which source files depend diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 3c230286f..c80c9fb16 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -292,7 +292,7 @@ void CsharpServiceHandler::getFileDiagram( Usages revUseIds; _csharpQueryHandler.getFileUsages(revUseIds,fileId_,true); - diagram.getIncludeDependencyDiagram(graph,fileId_,useIds,revUseIds); + diagram.getFileUsagesDiagram(graph,fileId_,useIds,revUseIds); break; } @@ -381,6 +381,23 @@ void CsharpServiceHandler::getFileDiagramLegend( const std::int32_t diagramId_) { LOG(info) << "getFileDiagramLegend"; + CsharpFileDiagram diagram(_db, _datadir, _context); + + switch (diagramId_) + { + + case EXTERNAL_USERS: + return_ = diagram.getExternalUsersDiagramLegend(); + break; + + case FILE_USAGES: + return_ = diagram.getFileUsagesDiagramLegend(); + break; + + case SUBSYSTEM_DEPENDENCY: + return_ = diagram.getSubsystemDependencyDiagramLegend(); + break; + } } void CsharpServiceHandler::getReferenceTypes( From 707b155287aabf804cbf8d86fdbf4fee7a5e06f0 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 30 Apr 2023 23:16:38 +0200 Subject: [PATCH 35/49] Diagrams :: TestDiagram removed and minor upgrade This commit removes previously written testdiagram and the menu now shows C# Diagrams option instead of Diagrams. --- .../csharp/service/src/csharpfilediagram.cpp | 29 ------------------- .../csharp/service/src/csharpfilediagram.h | 5 ---- plugins/csharp/webgui/js/csharpMenu.js | 2 +- 3 files changed, 1 insertion(+), 35 deletions(-) diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 6d60047d0..465b1a073 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -881,35 +881,6 @@ const CsharpFileDiagram::Decoration CsharpFileDiagram::revDependsEdgeDecoration {"color", "blue"} }; -void CsharpFileDiagram::getTestDiagram( - std::string firstAstNodeValue, - util::Graph& graph_, - const core::FileId& fileId_) -{ - core::FileInfo fileInfo; - CsharpFileDiagram::_projectHandler.getFileInfo(fileInfo, fileId_); - util::Graph::Node currentNode = addNode(graph_, fileInfo); - decorateNode(graph_, currentNode, sourceFileNodeDecoration); - - core::FileInfo parentInfo; - CsharpFileDiagram::_projectHandler.getFileInfo(parentInfo,fileInfo.parent); - util::Graph::Node nextNode = addNode(graph_, parentInfo); - decorateNode(graph_, nextNode, directoryNodeDecoration); - - util::Graph::Node FirstAstValueToFileNode = graph_.createNode(); - graph_.setNodeAttribute(FirstAstValueToFileNode, "label", firstAstNodeValue); - decorateNode(graph_, FirstAstValueToFileNode, centerNodeDecoration); - - util::Graph::Edge edge = graph_.createEdge(nextNode, currentNode); - decorateEdge(graph_, edge, containsEdgeDecoration); - - util::Graph::Edge edgeToValue = graph_.createEdge(currentNode, FirstAstValueToFileNode); - decorateEdge(graph_, edgeToValue, containsEdgeDecoration); - - - -} - } // language } // service } // cc \ No newline at end of file diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index 9878242d7..b2cc3f11f 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -113,11 +113,6 @@ class CsharpFileDiagram * @return The generated legend as a string in SVG format. */ //std::string getComponentUsersDiagramLegend(); - - void getTestDiagram( - std::string firstAstNodeValue, - util::Graph& graph_, - const core::FileId& fileId_); private: typedef std::vector> Decoration; diff --git a/plugins/csharp/webgui/js/csharpMenu.js b/plugins/csharp/webgui/js/csharpMenu.js index bd95aca1b..eab8ff360 100644 --- a/plugins/csharp/webgui/js/csharpMenu.js +++ b/plugins/csharp/webgui/js/csharpMenu.js @@ -138,7 +138,7 @@ function (topic, Menu, MenuItem, PopupMenuItem, astHelper, model, urlHandler, vi if (Object.keys(diagramTypes).length !== 0) return new PopupMenuItem({ - label : 'Diagrams', + label : 'C# Diagrams', popup : submenu }); } From f13d1a1e3bbf73a5ce7c04e915fbb57ab56007a3 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Mon, 1 May 2023 19:19:36 +0200 Subject: [PATCH 36/49] Diagrams :: Experimental CodeBites added --- plugins/csharp/service/src/csharpservice.cpp | 5 +++-- .../service/src_csharp/CSharpQueryHandler.cs | 17 +++++++++++------ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index c80c9fb16..1e79f3f53 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -95,6 +95,7 @@ void CsharpServiceHandler::getAstNodeInfoByPosition( FileQuery::id == std::stoull(fpos_.file)); }); _csharpQueryHandler.getAstNodeInfoByPosition(return_, file->path, fpos_.pos); + return_.range.file = fpos_.file; //so that getFileInfo requests contain the file id. } void CsharpServiceHandler::getSourceText( @@ -108,7 +109,7 @@ void CsharpServiceHandler::getSourceText( return_ = _transaction([&, this](){ model::FilePtr file = _db->query_one( - FileQuery::id == std::stoull(fileRange.file)); + FileQuery::path == /*std::stoull(*/fileRange.file/*)*/); // id volt if (!file) { return std::string(); @@ -423,7 +424,7 @@ void CsharpServiceHandler::getReferences( const std::vector& tags_) { LOG(info) << "getReferences"; - _csharpQueryHandler.getReferences(return_, astNodeId_, referenceId_, tags_); + _csharpQueryHandler.getReferences(return_, astNodeId_, referenceId_, {}); std::vector ret; for (AstNodeInfo nodeinfo : return_) { diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 2b9fe4ed0..38f556af6 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -576,12 +576,12 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, CancellationToken cancellationToken = default(CancellationToken)) { var node = queryCsharpAstNode(astNodeId); - // Console.WriteLine("getreferencesasync NODE"); - // Console.WriteLine("getreferencesasync astsymboltype: " + node.AstSymbolType); - // Console.WriteLine("getreferencesasync asttype: " + node.AstType); - // Console.WriteLine("getreferencesasync astvalue: " + node.AstValue); - // Console.WriteLine("getreferencesasync reftype: " + (ReferenceType)referenceId); - // Console.WriteLine("getreferencesasync refid: " + referenceId); + Console.WriteLine("getreferencesasync NODE"); + Console.WriteLine("getreferencesasync astsymboltype: " + node.AstSymbolType); + Console.WriteLine("getreferencesasync asttype: " + node.AstType); + Console.WriteLine("getreferencesasync astvalue: " + node.AstValue); + Console.WriteLine("getreferencesasync reftype: " + (ReferenceType)referenceId); + Console.WriteLine("getreferencesasync refid: " + referenceId); var ret = new List(); switch ((ReferenceType)referenceId) { @@ -589,6 +589,11 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, ret = createAstNodeInfoList(queryInvocations(node)); break; case ReferenceType.DEFINITION: + Console.WriteLine("inside DEFINITION"); + var nodes = new List(); + nodes.Add(node); + ret = createAstNodeInfoList(nodes); //experimental + break; case ReferenceType.DECLARATION: ret = createAstNodeInfoList(queryDeclarators(node)); break; From 1035fb5882d161a2385cbf15724c78b9b925291b Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 4 May 2023 15:29:58 +0200 Subject: [PATCH 37/49] Diagrams :: Remove accessability tags in detailed class diagram This commit removes accessability tags from the signature of methods,classes and properties since there is a visual aid in form of +,- and #, so there is no need to write out the accessability of each. --- plugins/csharp/service/src/csharpdiagram.cpp | 82 +++++++------------ .../service/src_csharp/CSharpQueryHandler.cs | 7 +- 2 files changed, 33 insertions(+), 56 deletions(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 6d31f858f..a0bdc6785 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -46,8 +46,18 @@ std::string graphHtmlTag( .append(">"); } +void removeAccessibilityTags(std::string& str){ + std::vector accessibilityTags = + {"public", "private", "protected", "internal", "protected internal", "private protected"}; + for (auto const& tag : accessibilityTags){ + if (str.find(tag) != std::string::npos) + { + str.erase(0,str.find(tag) + tag.length() + 1); + } + } } +} namespace cc { namespace service @@ -241,63 +251,15 @@ void CsharpDiagram::getDetailedClassDiagram( // Center node - //LOG(info) << "CENTER ASTNODE: " << centerNodeInfo_.astNodeValue; AstNodeInfo nodeInfo = centerNodeInfo_; nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); + removeAccessibilityTags(nodeInfo.astNodeValue); + util::Graph::Node centerNode = addNode(graph_, nodeInfo); graph_.setNodeAttribute(centerNode,"label", getDetailedClassNodeLabel(nodeInfo,propertyNodeInfos_,methodNodeInfos_), true); graph_.setNodeAttribute(centerNode,"shape", "none"); - -// _cppHandler.getReferences( -// nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); - -// if (nodes.empty()) -// return; - -// AstNodeInfo nodeInfo = nodes.front(); - -// util::Graph::Node currentNode = addNode(graph_, nodeInfo); -// graph_.setNodeAttribute(currentNode, "label", -// getDetailedClassNodeLabel(nodeInfo), true); -// graph_.setNodeAttribute(currentNode, "shape", "none"); - -// nodes.clear(); - -// //--- Types from which the queried type inherits ---// - -// _cppHandler.getReferences(nodes, nodeInfo.id, -// CppServiceHandler::INHERIT_FROM, {}); - -// for (const AstNodeInfo& node : nodes) -// { -// util::Graph::Node inheritNode = addNode(graph_, node); -// graph_.setNodeAttribute(inheritNode, "label", -// getDetailedClassNodeLabel(node), true); -// graph_.setNodeAttribute(inheritNode, "shape", "none"); - -// util::Graph::Edge edge = graph_.createEdge(currentNode, inheritNode); -// decorateEdge(graph_, edge, inheritClassEdgeDecoration); -// } - -// nodes.clear(); - -// //--- Types by which the queried type is inherited ---// - -// _cppHandler.getReferences(nodes, nodeInfo.id, -// CppServiceHandler::INHERIT_BY, {}); - -// for (const AstNodeInfo& node : nodes) -// { -// util::Graph::Node inheritNode = addNode(graph_, node); -// graph_.setNodeAttribute(inheritNode, "label", -// getDetailedClassNodeLabel(node), true); -// graph_.setNodeAttribute(inheritNode, "shape", "none"); - -// util::Graph::Edge edge = graph_.createEdge(inheritNode, currentNode); -// decorateEdge(graph_, edge, inheritClassEdgeDecoration); -// } } std::string CsharpDiagram::getDetailedClassNodeLabel( @@ -317,9 +279,13 @@ std::string CsharpDiagram::getDetailedClassNodeLabel( for (auto it = propertyNodeInfos_.begin(); it != propertyNodeInfos_.end(); ++it) { + std::string astValueToShow = it->astNodeValue; + astValueToShow = astValueToShow.substr(0,astValueToShow.find('{')); + removeAccessibilityTags(astValueToShow); + std::string visibility = visibilityToHtml(*it); std::string content = memberContentToHtml(*it, - util::escapeHtml(it->astNodeValue.substr(0,it->astNodeValue.find('{')))/* + " : " + getProperty(it->id, "Type")*/); + util::escapeHtml(astValueToShow)); std::string attr = colAttr; if (it == propertyNodeInfos_.end() - 1) @@ -338,8 +304,12 @@ std::string CsharpDiagram::getDetailedClassNodeLabel( if (!node.astNodeValue.empty()) { + std::string astValueToShow = node.astNodeValue; + astValueToShow = astValueToShow.substr(0,astValueToShow.find('{')); + removeAccessibilityTags(astValueToShow); + std::string content = memberContentToHtml(node, - util::escapeHtml(node.astNodeValue.substr(0,node.astNodeValue.find('{')))); + util::escapeHtml(astValueToShow)); label += graphHtmlTag("tr", graphHtmlTag("td", visibility, colAttr) + @@ -358,8 +328,14 @@ std::string CsharpDiagram::visibilityToHtml(const AstNodeInfo& node_) return graphHtmlTag("font", "+", "color='green'"); if (contains(node_.tags, "Private")) return graphHtmlTag("font", "-", "color='red'"); + if (contains(node_.tags, "Private protected")) + return graphHtmlTag("font", "-", "color='red'"); if (contains(node_.tags, "Protected")) return graphHtmlTag("font", "#", "color='blue'"); + if (contains(node_.tags, "Internal")) + return graphHtmlTag("font", "#", "color='blue'"); + if (contains(node_.tags, "Protected internal")) + return graphHtmlTag("font", "#", "color='blue'"); return ""; } @@ -555,4 +531,4 @@ const CsharpDiagram::Decoration CsharpDiagram::inheritClassEdgeDecoration = { } } -} +} \ No newline at end of file diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 38f556af6..af206de9c 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -590,9 +590,10 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, break; case ReferenceType.DEFINITION: Console.WriteLine("inside DEFINITION"); - var nodes = new List(); - nodes.Add(node); - ret = createAstNodeInfoList(nodes); //experimental + // var nodes = new List(); + // nodes.Add(node); + // ret = createAstNodeInfoList(nodes); //experimental + ret = createAstNodeInfoList(queryDeclarators(node)); break; case ReferenceType.DECLARATION: ret = createAstNodeInfoList(queryDeclarators(node)); From d77870b58b391b1f8a9682ff8ad2f9297b36b840 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 4 May 2023 16:01:42 +0200 Subject: [PATCH 38/49] Diagrams :: Fix annotated signatures in diagram This commit fixes a case where the detailed class diagram will include the annotations before the signature in the diagram. This commit fixes this. It looks clean now. --- plugins/csharp/service/src/csharpdiagram.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index a0bdc6785..413ac37bc 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -53,6 +53,7 @@ void removeAccessibilityTags(std::string& str){ if (str.find(tag) != std::string::npos) { str.erase(0,str.find(tag) + tag.length() + 1); + break; } } } @@ -252,8 +253,8 @@ void CsharpDiagram::getDetailedClassDiagram( // Center node AstNodeInfo nodeInfo = centerNodeInfo_; - nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); removeAccessibilityTags(nodeInfo.astNodeValue); + nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); util::Graph::Node centerNode = addNode(graph_, nodeInfo); graph_.setNodeAttribute(centerNode,"label", @@ -280,8 +281,8 @@ std::string CsharpDiagram::getDetailedClassNodeLabel( for (auto it = propertyNodeInfos_.begin(); it != propertyNodeInfos_.end(); ++it) { std::string astValueToShow = it->astNodeValue; - astValueToShow = astValueToShow.substr(0,astValueToShow.find('{')); removeAccessibilityTags(astValueToShow); + astValueToShow = astValueToShow.substr(0,astValueToShow.find('{')); std::string visibility = visibilityToHtml(*it); std::string content = memberContentToHtml(*it, @@ -305,8 +306,8 @@ std::string CsharpDiagram::getDetailedClassNodeLabel( if (!node.astNodeValue.empty()) { std::string astValueToShow = node.astNodeValue; - astValueToShow = astValueToShow.substr(0,astValueToShow.find('{')); removeAccessibilityTags(astValueToShow); + astValueToShow = astValueToShow.substr(0,astValueToShow.find('{')); std::string content = memberContentToHtml(node, util::escapeHtml(astValueToShow)); From 5aaec7ac51ee9da134d0233c707d1676a0cb6c13 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 4 May 2023 16:35:29 +0200 Subject: [PATCH 39/49] Diagrams :: CodeBites option will appear on every node --- plugins/csharp/webgui/js/csharpMenu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/csharp/webgui/js/csharpMenu.js b/plugins/csharp/webgui/js/csharpMenu.js index eab8ff360..e3fb32406 100644 --- a/plugins/csharp/webgui/js/csharpMenu.js +++ b/plugins/csharp/webgui/js/csharpMenu.js @@ -136,7 +136,7 @@ function (topic, Menu, MenuItem, PopupMenuItem, astHelper, model, urlHandler, vi } })); - if (Object.keys(diagramTypes).length !== 0) + //if (Object.keys(diagramTypes).length !== 0) return new PopupMenuItem({ label : 'C# Diagrams', popup : submenu From 1a80bf8866585c6ebf9a4725962e477fa4e7be03 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Thu, 4 May 2023 16:48:04 +0200 Subject: [PATCH 40/49] Diagrams :: Delete comment in csharpMenu.js --- plugins/csharp/webgui/js/csharpMenu.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/plugins/csharp/webgui/js/csharpMenu.js b/plugins/csharp/webgui/js/csharpMenu.js index e3fb32406..666292b65 100644 --- a/plugins/csharp/webgui/js/csharpMenu.js +++ b/plugins/csharp/webgui/js/csharpMenu.js @@ -136,11 +136,10 @@ function (topic, Menu, MenuItem, PopupMenuItem, astHelper, model, urlHandler, vi } })); - //if (Object.keys(diagramTypes).length !== 0) - return new PopupMenuItem({ - label : 'C# Diagrams', - popup : submenu - }); + return new PopupMenuItem({ + label : 'C# Diagrams', + popup : submenu + }); } }; From 9b130cc73ec0eb89c0369a76b3ddd61772dce1f7 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Fri, 5 May 2023 15:17:36 +0200 Subject: [PATCH 41/49] Diagrams :: Minor fixes --- plugins/csharp/service/src/csharpdiagram.cpp | 3 +++ plugins/csharp/service/src/csharpfilediagram.cpp | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 413ac37bc..1992131ef 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -204,6 +204,7 @@ void CsharpDiagram::getFunctionCallDiagram( // Center node LOG(info) << "CENTER ASTNODE: " << centerNodeInfo_.astNodeValue; AstNodeInfo nodeInfo = centerNodeInfo_; + removeAccessibilityTags(nodeInfo.astNodeValue); nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); util::Graph::Node centerNode = addNode(graph_, nodeInfo); decorateNode(graph_, centerNode, centerNodeDecoration); @@ -213,6 +214,7 @@ void CsharpDiagram::getFunctionCallDiagram( for (const auto& calleeNodeInfo : calleeNodeInfos_) { AstNodeInfo calleeInfo = calleeNodeInfo; + removeAccessibilityTags(calleeInfo.astNodeValue); calleeInfo.astNodeValue = calleeInfo.astNodeValue.substr(0,calleeInfo.astNodeValue.find('{')); util::Graph::Node calleeNode = addNode(graph_, calleeInfo); decorateNode(graph_, centerNode, calleeNodeDecoration); @@ -229,6 +231,7 @@ void CsharpDiagram::getFunctionCallDiagram( for (const auto& callerNodeInfo : callerNodeInfos_) { AstNodeInfo callerInfo = callerNodeInfo; + removeAccessibilityTags(callerInfo.astNodeValue); callerInfo.astNodeValue = callerInfo.astNodeValue.substr(0,callerInfo.astNodeValue.find('{')); util::Graph::Node callerNode = addNode(graph_, callerInfo); decorateNode(graph_, centerNode, callerNodeDecoration); diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index 465b1a073..ca382d31c 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -269,7 +269,6 @@ std::string CsharpFileDiagram::getExternalUsersDiagramLegend() builder.addNode("center file", centerNodeDecoration); builder.addNode("directory", directoryNodeDecoration); - builder.addNode("source file", sourceFileNodeDecoration); builder.addEdge("sub directory", subdirEdgeDecoration); builder.addEdge("used by", revUsagesEdgeDecoration); @@ -339,6 +338,7 @@ void CsharpFileDiagram::getSubsystemDependencyDiagram( _projectHandler.getFileInfo(fileInfo, fileId_); util::Graph::Node currentNode = addNode(graph_, fileInfo); decorateNode(graph_, currentNode, centerNodeDecoration); + decorateNode(graph_, currentNode, directoryNodeDecoration); std::set subdirs = util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getSubDirs, this, std::placeholders::_1, From 2b2768339ff2c3ecd8f6d1655458f29e7f26a72e Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 6 May 2023 11:28:43 +0200 Subject: [PATCH 42/49] Diagrams :: CodeBites available This commit adds a functional version of CodeBites. This was achieved by modifying AstVisitor.cs by adding declarations into CsharpEtcEntitys table. Modifications to CodeBites.js were also needed since new behavior was introduced in case of .CS files. Now edges dont show declarations and declarations can be moved to a new box. --- .../csharp/parser/src_csharp/AstVisitor.cs | 218 +++++++++++++++++- .../service/src_csharp/CSharpQueryHandler.cs | 31 ++- webgui/scripts/codecompass/view/codeBites.js | 62 +++-- 3 files changed, 279 insertions(+), 32 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/AstVisitor.cs b/plugins/csharp/parser/src_csharp/AstVisitor.cs index b64fce38e..0491f0220 100644 --- a/plugins/csharp/parser/src_csharp/AstVisitor.cs +++ b/plugins/csharp/parser/src_csharp/AstVisitor.cs @@ -143,6 +143,21 @@ public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) DbContext.CsharpNamespaces.Add(csharpNamespace); } + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + base.VisitNamespaceDeclaration(node); } @@ -178,7 +193,22 @@ public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) QualifiedName = qName, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash - }; + }; + + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); foreach (PropertyDeclarationSyntax propertyDeclaration in node.Members.OfType()) { @@ -231,6 +261,21 @@ public override void VisitStructDeclaration(StructDeclarationSyntax node) EntityHash = astNode.EntityHash }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + foreach (VariableDeclarationSyntax variableDeclaration in node.Members.OfType()) { //WriteLine($"Variable name: {variableDeclaration.Variables.First().Identifier}"); @@ -329,6 +374,21 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node) EntityHash = astNode.EntityHash }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + foreach (var variableDeclaration in node.Members.OfType()) { //WriteLine($"Variable name: {variableDeclaration.Variables.First().Identifier}"); @@ -427,6 +487,21 @@ public override void VisitRecordDeclaration(RecordDeclarationSyntax node) { EntityHash = astNode.EntityHash }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + foreach (var variableDeclaration in node.Members.OfType()) { //WriteLine($"Variable name: {variableDeclaration.Variables.First().Identifier}"); @@ -518,6 +593,21 @@ private void VisitDelegateDecl(DelegateDeclarationSyntax node, CsharpAstNode par MethodType = MethodTypeEnum.Delegate }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + if (node.ParameterList.Parameters.Count > 0) { VisitMethodParameters(node.ParameterList.Parameters, astNode); @@ -552,6 +642,21 @@ private void VisitDestructorDecl(DestructorDeclarationSyntax node, CsharpAstNode MethodType = MethodTypeEnum.Destuctor }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + if (node.ParameterList.Parameters.Count > 0) { VisitMethodParameters(node.ParameterList.Parameters,astNode); @@ -591,6 +696,21 @@ private void VisitConstructorDecl(ConstructorDeclarationSyntax node, CsharpAstNo MethodType = MethodTypeEnum.Constructor }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + //QualifiedType = type, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + if (node.ParameterList.Parameters.Count > 0) { VisitMethodParameters(node.ParameterList.Parameters,astNode); @@ -643,6 +763,21 @@ private void VisitMethodDecl(MethodDeclarationSyntax node, CsharpAstNode parent) MethodType = MethodTypeEnum.Method }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.ToString(), + QualifiedType = qType, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + if (node.ParameterList.Parameters.Count > 0) { VisitMethodParameters(node.ParameterList.Parameters,astNode); @@ -696,6 +831,21 @@ private void VisitOperatorDecl(OperatorDeclarationSyntax node, CsharpAstNode par MethodType = MethodTypeEnum.Operator }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = Name, + QualifiedType = qType, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + if (node.ParameterList.Parameters.Count > 0) { VisitMethodParameters(node.ParameterList.Parameters,astNode); @@ -787,6 +937,26 @@ private void VisitVariableDecl(VariableDeclarationSyntax node, CsharpAstNode par }; DbContext.CsharpVariables.Add(csharpVariable); } + + // var astNode2 = AstNode(node, AstSymbolTypeEnum.Variable); + // System.Console.WriteLine("success"); + // if (astNode2 != null) + // { + // System.Console.WriteLine(astNode2.AstValue); + // CsharpEtcEntity expr = new CsharpEtcEntity + // { + // AstNode = astNode2, + // DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + // EntityHash = astNode2.EntityHash, + // ParentNode = parent, + // //EtcEntityType = EtcEntityTypeEnum.Invocation, + // DeclaratorNodeId = astNode2.Id, + // //Name = node.ToString() + // //QualifiedType = varQType, + // //QualifiedName = Model.GetDeclaredSymbol(node).ToString() + // }; + // DbContext.CsharpEtcEntitys.Add(expr); + // } } private void VisitPropertyDecl(PropertyDeclarationSyntax node, CsharpAstNode parent) @@ -814,6 +984,21 @@ private void VisitPropertyDecl(PropertyDeclarationSyntax node, CsharpAstNode par ParentNode = parent }; DbContext.CsharpVariables.Add(variable); + + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.Identifier.Text, + QualifiedType = varQType, + //QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); } private void VisitAccessors(AccessorListSyntax node, String propertyName, CsharpAstNode parent) @@ -903,6 +1088,21 @@ public override void VisitEnumDeclaration(EnumDeclarationSyntax node) EntityHash = astNode.EntityHash }; + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + //ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.Identifier.Text, + //QualifiedType = varQType, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + foreach (EnumMemberDeclarationSyntax enumMemberDeclarationSyntax in node.Members) { csharpEnum.AddMember(VisitEnumMemberDecl(enumMemberDeclarationSyntax, astNode)); @@ -931,6 +1131,22 @@ private CsharpEnumMember VisitEnumMemberDecl(EnumMemberDeclarationSyntax node, C EntityHash = astNode.EntityHash, ParentNode = parent }; + + //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); + CsharpEtcEntity expr = new CsharpEtcEntity + { + AstNode = astNode, + DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), + EntityHash = astNode.EntityHash, + ParentNode = parent, + //EtcEntityType = EtcEntityTypeEnum.Invocation, + DeclaratorNodeId = astNode.Id, + Name = node.Identifier.Text, + //QualifiedType = varQType, + QualifiedName = qName + }; + DbContext.CsharpEtcEntitys.Add(expr); + if (node.EqualsValue != null) { try diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index af206de9c..24c3a63b5 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -143,6 +143,17 @@ private List queryDeclarators(CsharpAstNode astNode) } } + private List queryDeclaratorsForCodeBites(CsharpAstNode astNode) + { + var ret = dbContext.CsharpEtcEntitys + .Where(e => e.AstNode.Id == astNode.Id && + e.DeclaratorNodeId == 1) + .Select(e => e.AstNode) + .ToList(); + + return ret; + } + private List queryEvals(CsharpAstNode astNode) { var ret = @@ -593,6 +604,7 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, // var nodes = new List(); // nodes.Add(node); // ret = createAstNodeInfoList(nodes); //experimental + //ret = createAstNodeInfoList(queryDeclarators(node)); ret = createAstNodeInfoList(queryDeclarators(node)); break; case ReferenceType.DECLARATION: @@ -648,16 +660,17 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, " ReferenceType is unhandled"); break; } - System.Console.WriteLine("getreferencesasync result: "); - foreach(var r in ret){ - System.Console.WriteLine("nodeinfo: ",r.AstNodeType); - System.Console.WriteLine(r.AstNodeValue); - foreach(var tag in r.Tags) - { - System.Console.WriteLine(tag); - } + if (ret.Any()) + System.Console.WriteLine("getreferencesasync result: ", ret.First()); + // foreach(var r in ret){ + // System.Console.WriteLine("nodeinfo: ",r.AstNodeType); + // System.Console.WriteLine(r.AstNodeValue); + // foreach(var tag in r.Tags) + // { + // System.Console.WriteLine(tag); + // } - } + // } return await Task.FromResult(ret); } diff --git a/webgui/scripts/codecompass/view/codeBites.js b/webgui/scripts/codecompass/view/codeBites.js index dbaea2cf7..b16526bda 100644 --- a/webgui/scripts/codecompass/view/codeBites.js +++ b/webgui/scripts/codecompass/view/codeBites.js @@ -50,6 +50,11 @@ function (declare, array, dom, style, topic, on, ContentPane, ResizeHandle, */ var colorIdx = 0; + /** + * This element contains the data related to the current file. + */ + var fileInfo = null; + /** * Default properties of boxes. */ @@ -91,7 +96,7 @@ function (declare, array, dom, style, topic, on, ContentPane, ResizeHandle, //--- Set content ---// - var fileInfo = model.project.getFileInfo(astNodeInfo.range.file); + fileInfo = model.project.getFileInfo(astNodeInfo.range.file); languageService = model.getLanguageService(fileInfo.type); if (astNodeInfo.astNodeType !== 'Definition') @@ -117,18 +122,29 @@ function (declare, array, dom, style, topic, on, ContentPane, ResizeHandle, dom.place(newElement.domNode, panel.domNode); - if (parent) - newElement.connection = panel._jsPlumbInstance.connect({ - source : parent.domNode, - target : newElement.domNode, - paintStyle : { stroke : colors[colorIdx], strokeWidth : 2 }, - Anchors : ['Perimeter', { shape : 'Ellipse' }], - Endpoint : ['Dot', { radius : 1 }], - overlays : [['Label', { - label : astNodeInfo.astNodeValue, - cssClass : 'cb-label cb-label-' + colorIdx - }]] - }); + if (parent){ + if (fileInfo.type === "CS"){ + newElement.connection = panel._jsPlumbInstance.connect({ + source : parent.domNode, + target : newElement.domNode, + paintStyle : { stroke : colors[colorIdx], strokeWidth : 2 } + }); + } + else{ + newElement.connection = panel._jsPlumbInstance.connect({ + source : parent.domNode, + target : newElement.domNode, + paintStyle : { stroke : colors[colorIdx], strokeWidth : 2 }, + Anchors : ['Perimeter', { shape : 'Ellipse' }], + Endpoint : ['Dot', { radius : 1 }], + overlays : [['Label', { + label : astNodeInfo.astNodeValue, + cssClass : 'cb-label cb-label-' + colorIdx + }]] + }); + } + } + if (window.gtag) { window.gtag ('event', 'code_bites', { @@ -353,15 +369,17 @@ function (declare, array, dom, style, topic, on, ContentPane, ResizeHandle, astNodeInfo.id, refTypes["Definition"])[0]; //--- Check if it's necessary to open a new box ---// - - if (astNodeInfo.id === defAstNodeInfo.id) - return; - - if (hasRow(this.row + 1) && - array.some(elementMatrix[this.row + 1], function (element) { - return element.astNodeInfo.id === defAstNodeInfo.id; - })) - return; + + if (fileInfo.type !== "CS"){ + if (astNodeInfo.id === defAstNodeInfo.id) + return; + + if (hasRow(this.row + 1) && + array.some(elementMatrix[this.row + 1], function (element) { + return element.astNodeInfo.id === defAstNodeInfo.id; + })) + return; + } //--- Color selection and open new box ---// From 22a294233811172890a07ef3bf14da97772305bf Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 7 May 2023 03:30:33 +0200 Subject: [PATCH 43/49] Clean up RelationCollector and Program There were some commented lines of code and a variable which needed to be deleted. --- plugins/csharp/parser/src_csharp/Program.cs | 28 ++---- .../parser/src_csharp/RelationCollector.cs | 93 +------------------ 2 files changed, 9 insertions(+), 112 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index 1f7389e93..c93f3c5e8 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -91,16 +91,12 @@ static int Main(string[] args) assemblies_base = GetSourceFilesFromDir(_buildDirBase, ".dll"); List trees = new List(); - var workspace = new AdhocWorkspace(); - var project = workspace.AddProject("MyProject", LanguageNames.CSharp); foreach (string file in allFiles) { string programText = File.ReadAllText(file); SyntaxTree tree = CSharpSyntaxTree.ParseText(programText, null, file); trees.Add(tree); - var document = workspace.AddDocument(project.Id, file, Microsoft.CodeAnalysis.Text.SourceText.From(File.ReadAllText(file))); } - var solution = workspace.CurrentSolution; CSharpCompilation compilation = CSharpCompilation.Create("CSharpCompilation") .AddReferences(MetadataReference.CreateFromFile(typeof(object).Assembly.Location)) @@ -116,7 +112,7 @@ static int Main(string[] args) } var runtask = ParalellRun(csharpConnectionString, threadNum, trees, compilation); - var collecttask = ParalellCollect(csharpConnectionString, threadNum, trees, compilation, solution); + var collecttask = ParalellCollect(csharpConnectionString, threadNum, trees, compilation); int ret = runtask.Result; int res = collecttask.Result; @@ -188,7 +184,7 @@ private static async Task ParseTree(CsharpDbContext context, // private static async Task ParalellCollect(string csharpConnectionString, int threadNum, - List trees, CSharpCompilation compilation, Solution solution) + List trees, CSharpCompilation compilation) { var options = new DbContextOptionsBuilder() .UseNpgsql(csharpConnectionString) @@ -208,7 +204,7 @@ private static async Task ParalellCollect(string csharpConnectionString, in int maxThread = threadNum < trees.Count() ? threadNum : trees.Count(); for (int i = 0; i < maxThread; i++) { - CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i,edges,solution)); + CollectingTasks.Add(CollectRelation(contextList[i],trees[i],compilation,i,edges)); } int nextTreeIndex = maxThread; @@ -221,38 +217,28 @@ private static async Task ParalellCollect(string csharpConnectionString, in if (nextTreeIndex < trees.Count) { CollectingTasks.Add(CollectRelation(contextList[nextContextIndex], - trees[nextTreeIndex],compilation,nextContextIndex, edges, solution)); + trees[nextTreeIndex],compilation,nextContextIndex, edges)); ++nextTreeIndex; } } foreach (var edge in edges) { - //var duplicate = dbContext.CsharpEdges. - // Where(a => a.Id == edge.Key). - // FirstOrDefault(); - //if (duplicate == null) - dbContext.CsharpEdges.Add(edge.Value); + dbContext.CsharpEdges.Add(edge.Value); } dbContext.SaveChanges(); - //foreach (var ctx in contextList) - //{ - // ctx.SaveChanges(); - //} - return 0; } private static async Task CollectRelation(CsharpDbContext context, - SyntaxTree tree, CSharpCompilation compilation, int index, ConcurrentDictionary edges, - Solution solution) + SyntaxTree tree, CSharpCompilation compilation, int index, ConcurrentDictionary edges) { var CollectingTask = Task.Run(() => { SemanticModel model = compilation.GetSemanticModel(tree); - var visitor = new RelationCollector(context, model, tree, edges, solution); + var visitor = new RelationCollector(context, model, tree, edges); visitor.Visit(tree.GetCompilationUnitRoot()); return index; }); diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index 4c2476ec6..6c179aed7 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -17,20 +17,16 @@ partial class RelationCollector : CSharpSyntaxWalker private readonly CsharpDbContext DbContext; private readonly SemanticModel Model; private readonly SyntaxTree Tree; - private readonly Solution Solution; private readonly ConcurrentDictionary Edges; - public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree, ConcurrentDictionary edges, Solution solution) + public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTree tree, ConcurrentDictionary edges) { this.DbContext = context; this.Model = model; this.Tree = tree; - this.Edges = edges; - this.Solution = solution; + this.Edges = edges; } - //test - public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { if (node.Initializer == null) return; @@ -86,91 +82,6 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node) base.VisitInvocationExpression(node); } - - /* - public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) - { - var symbol = Model.GetDeclaredSymbol(node); - - ProcessReferencesAsync(node, symbol).Wait(); - - base.VisitVariableDeclarator(node); - } - - private async Task ProcessReferencesAsync(VariableDeclaratorSyntax node, ISymbol symbol) - { - var references = await SymbolFinder.FindReferencesAsync(symbol, Solution); - - foreach (var reference in references) - { - var referenceNode = reference.Definition.DeclaringSyntaxReferences[0].GetSyntax(); - if (referenceNode != node) - { - var referenceSymbol = Model.GetSymbolInfo(referenceNode).Symbol; - - var declaringNode = node.Parent.Parent; // The parent of the variable declarator is the variable declaration syntax, whose parent is the member declaration syntax. - var declaringFile = declaringNode.SyntaxTree.FilePath; - - var referenceFile = referenceNode.SyntaxTree.FilePath; - - if (referenceFile != null && - declaringFile != null && - referenceFile != declaringFile) - { - WriteLine($"Value declaringFile: {declaringFile}; referenceFile: {referenceFile}"); - - CsharpEdge csharpEdge = new CsharpEdge(); - csharpEdge.From = fnvHash(declaringFile); - csharpEdge.To = fnvHash(referenceFile); - csharpEdge.Type = EdgeType.USE; - csharpEdge.Id = createIdentifier(csharpEdge); - DbContext.CsharpEdges.Add(csharpEdge); - } - } - } - } - */ - - /* - public override void VisitInvocationExpression(InvocationExpressionSyntax node) - { - var symbol = Model.GetSymbolInfo(node).Symbol; - - if (symbol != null && symbol.Kind == SymbolKind.Method) - { - var methodSymbol = (IMethodSymbol)symbol; - - var containingType = methodSymbol.ContainingType; - if (containingType != null && containingType.Name != "") - { - var declaringFile = node.SyntaxTree.FilePath; - - string referenceFile = null; - if (containingType.Locations.Length > 0 && containingType.Locations[0].SourceTree != null) - { - referenceFile = containingType.Locations[0].SourceTree.FilePath; - } - - if (referenceFile != null && - declaringFile != null && - referenceFile != declaringFile) - { - WriteLine($"Method declaringFile: {declaringFile}; referenceFile: {referenceFile}"); - - CsharpEdge csharpEdge = new CsharpEdge(); - csharpEdge.From = fnvHash(declaringFile); - csharpEdge.To = fnvHash(referenceFile); - csharpEdge.Type = EdgeType.USE; - csharpEdge.Id = createIdentifier(csharpEdge); - //DbContext.CsharpEdges.Add(csharpEdge); - } - } - } - - base.VisitInvocationExpression(node); - } - */ - private ulong createIdentifier(CsharpEdge edge_) { return fnvHash($"{edge_.From}{edge_.To}{typeToString(edge_.Type)}"); From a2a91f81b7a41e4e6ba3058091701c6423850047 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sun, 7 May 2023 07:07:22 +0200 Subject: [PATCH 44/49] Diagrams :: Improve queries This commit improves queryCallers,queryCallees and queryCall functions so that it will not query itself. --- plugins/csharp/service/src_csharp/CSharpQueryHandler.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 24c3a63b5..3f3458f75 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -204,6 +204,7 @@ from invoc in dbContext.CsharpEtcEntitys join node in dbContext.CsharpAstNodes on invoc.DeclaratorNodeId equals node.Id where node.AstSymbolType == AstSymbolTypeEnum.Method + && invoc.DeclaratorNodeId != invoc.AstNode.Id && invoc.AstNode.Path == astNode.Path && invoc.AstNode.Location_range_start_line >= astNode.Location_range_start_line && invoc.AstNode.Location_range_end_line <= astNode.Location_range_end_line @@ -218,6 +219,7 @@ from invoc in dbContext.CsharpEtcEntitys join node in dbContext.CsharpAstNodes on invoc.DeclaratorNodeId equals node.Id where node.AstSymbolType == AstSymbolTypeEnum.Method + && invoc.DeclaratorNodeId != invoc.AstNode.Id && invoc.AstNode.Path == astNode.Path && invoc.AstNode.Location_range_start_line >= astNode.Location_range_start_line && invoc.AstNode.Location_range_end_line <= astNode.Location_range_end_line @@ -228,7 +230,8 @@ on invoc.DeclaratorNodeId equals node.Id private List queryCallers(CsharpAstNode astNode) { var invocations = dbContext.CsharpEtcEntitys - .Where(e => e.DeclaratorNodeId == astNode.Id) + .Where(e => e.DeclaratorNodeId == astNode.Id && + e.DeclaratorNodeId != e.AstNode.Id) .Select(e => e.AstNode); var ret = from invoc in invocations From d656d4ab2f11836f8014bec4db9cb3d6d4664d86 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Mon, 8 May 2023 22:48:04 +0200 Subject: [PATCH 45/49] Code cleanup With this commit I am cleaning up code which is either commented or not in use. --- .../csharp/parser/src_csharp/AstVisitor.cs | 65 +- .../parser/src_csharp/RelationCollector.cs | 10 +- plugins/csharp/service/csharpservice.thrift | 9 - .../service/include/service/csharpservice.h | 23 - plugins/csharp/service/src/csharpdiagram.cpp | 174 +----- plugins/csharp/service/src/csharpdiagram.h | 25 - .../csharp/service/src/csharpfilediagram.cpp | 566 ------------------ .../csharp/service/src/csharpfilediagram.h | 277 +-------- plugins/csharp/service/src/csharpservice.cpp | 34 +- .../service/src_csharp/CSharpQueryHandler.cs | 56 +- 10 files changed, 32 insertions(+), 1207 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/AstVisitor.cs b/plugins/csharp/parser/src_csharp/AstVisitor.cs index 0491f0220..c59e0553a 100644 --- a/plugins/csharp/parser/src_csharp/AstVisitor.cs +++ b/plugins/csharp/parser/src_csharp/AstVisitor.cs @@ -143,17 +143,13 @@ public override void VisitNamespaceDeclaration(NamespaceDeclarationSyntax node) DbContext.CsharpNamespaces.Add(csharpNamespace); } - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, - //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -195,17 +191,13 @@ public override void VisitInterfaceDeclaration(InterfaceDeclarationSyntax node) EntityHash = astNode.EntityHash }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, - //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -261,17 +253,13 @@ public override void VisitStructDeclaration(StructDeclarationSyntax node) EntityHash = astNode.EntityHash }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, - //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -374,17 +362,13 @@ public override void VisitClassDeclaration(ClassDeclarationSyntax node) EntityHash = astNode.EntityHash }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, - //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -487,17 +471,13 @@ public override void VisitRecordDeclaration(RecordDeclarationSyntax node) { EntityHash = astNode.EntityHash }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, - //ParentNode = DbContext.CsharpAstNodes.Find(astNode.Id), - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -593,17 +573,14 @@ private void VisitDelegateDecl(DelegateDeclarationSyntax node, CsharpAstNode par MethodType = MethodTypeEnum.Delegate }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -642,17 +619,14 @@ private void VisitDestructorDecl(DestructorDeclarationSyntax node, CsharpAstNode MethodType = MethodTypeEnum.Destuctor }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -696,17 +670,14 @@ private void VisitConstructorDecl(ConstructorDeclarationSyntax node, CsharpAstNo MethodType = MethodTypeEnum.Constructor }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), - //QualifiedType = type, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -763,14 +734,12 @@ private void VisitMethodDecl(MethodDeclarationSyntax node, CsharpAstNode parent) MethodType = MethodTypeEnum.Method }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.ToString(), QualifiedType = qType, @@ -831,14 +800,12 @@ private void VisitOperatorDecl(OperatorDeclarationSyntax node, CsharpAstNode par MethodType = MethodTypeEnum.Operator }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = Name, QualifiedType = qType, @@ -937,26 +904,6 @@ private void VisitVariableDecl(VariableDeclarationSyntax node, CsharpAstNode par }; DbContext.CsharpVariables.Add(csharpVariable); } - - // var astNode2 = AstNode(node, AstSymbolTypeEnum.Variable); - // System.Console.WriteLine("success"); - // if (astNode2 != null) - // { - // System.Console.WriteLine(astNode2.AstValue); - // CsharpEtcEntity expr = new CsharpEtcEntity - // { - // AstNode = astNode2, - // DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), - // EntityHash = astNode2.EntityHash, - // ParentNode = parent, - // //EtcEntityType = EtcEntityTypeEnum.Invocation, - // DeclaratorNodeId = astNode2.Id, - // //Name = node.ToString() - // //QualifiedType = varQType, - // //QualifiedName = Model.GetDeclaredSymbol(node).ToString() - // }; - // DbContext.CsharpEtcEntitys.Add(expr); - // } } private void VisitPropertyDecl(PropertyDeclarationSyntax node, CsharpAstNode parent) @@ -985,18 +932,15 @@ private void VisitPropertyDecl(PropertyDeclarationSyntax node, CsharpAstNode par }; DbContext.CsharpVariables.Add(variable); - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.Identifier.Text, - QualifiedType = varQType, - //QualifiedName = qName + QualifiedType = varQType }; DbContext.CsharpEtcEntitys.Add(expr); } @@ -1088,17 +1032,13 @@ public override void VisitEnumDeclaration(EnumDeclarationSyntax node) EntityHash = astNode.EntityHash }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, - //ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.Identifier.Text, - //QualifiedType = varQType, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); @@ -1132,17 +1072,14 @@ private CsharpEnumMember VisitEnumMemberDecl(EnumMemberDeclarationSyntax node, C ParentNode = parent }; - //var astNode = AstNode(node, AstSymbolTypeEnum.EtcEntity, AstTypeEnum.Declaration); CsharpEtcEntity expr = new CsharpEtcEntity { AstNode = astNode, DocumentationCommentXML = Model.GetDeclaredSymbol(node).GetDocumentationCommentXml(), EntityHash = astNode.EntityHash, ParentNode = parent, - //EtcEntityType = EtcEntityTypeEnum.Invocation, DeclaratorNodeId = astNode.Id, Name = node.Identifier.Text, - //QualifiedType = varQType, QualifiedName = qName }; DbContext.CsharpEtcEntitys.Add(expr); diff --git a/plugins/csharp/parser/src_csharp/RelationCollector.cs b/plugins/csharp/parser/src_csharp/RelationCollector.cs index 6c179aed7..65be1d92d 100644 --- a/plugins/csharp/parser/src_csharp/RelationCollector.cs +++ b/plugins/csharp/parser/src_csharp/RelationCollector.cs @@ -27,6 +27,9 @@ public RelationCollector(CsharpDbContext context, SemanticModel model, SyntaxTre this.Edges = edges; } + /// + /// Method VisitVariableDeclarator will gather aggregation type of relations. + /// public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) { if (node.Initializer == null) return; @@ -44,7 +47,7 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) symbolFilePath == usageFilePath) return; - WriteLine($"Value usageFilePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); + // WriteLine($"Value usageFilePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); CsharpEdge csharpEdge = new CsharpEdge(); csharpEdge.From = fnvHash(usageFilePath); @@ -57,6 +60,9 @@ public override void VisitVariableDeclarator(VariableDeclaratorSyntax node) base.VisitVariableDeclarator(node); } + /// + /// Method VisitInvocationExpression will gather association type of relations. + /// public override void VisitInvocationExpression(InvocationExpressionSyntax node) { var methodSymbol = Model.GetSymbolInfo(node).Symbol as IMethodSymbol; @@ -69,7 +75,7 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node) usageFilePath == null || symbolFilePath == usageFilePath) return; - WriteLine($"Value usageFilePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); + // WriteLine($"Value usageFilePath: {usageFilePath}; symbolFilePath: {symbolFilePath}"); CsharpEdge csharpEdge = new CsharpEdge(); csharpEdge.From = fnvHash(usageFilePath); diff --git a/plugins/csharp/service/csharpservice.thrift b/plugins/csharp/service/csharpservice.thrift index d8b424572..9e9708d5e 100644 --- a/plugins/csharp/service/csharpservice.thrift +++ b/plugins/csharp/service/csharpservice.thrift @@ -49,19 +49,10 @@ service CsharpService map getDiagramTypes(1:common.AstNodeId astNodeId) throws (1:common.InvalidId ex) - string getDiagram(1:common.AstNodeId astNodeId, 2:i32 diagramId) - throws (1:common.InvalidId exId, 2:common.Timeout exLong) - list getSyntaxHighlight( 1:common.FileRange range, 2:list content) - map getFileDiagramTypes(1:common.FileId fileId) - throws (1:common.InvalidId ex) - - string getFileDiagram(1:common.FileId fileId, 2:i32 diagramId) - throws (1:common.InvalidId exId, 2:common.Timeout exLong) - map> getFileUsages(1:common.FileId fileId, 2:bool reverse) throws (1:common.InvalidId exId, 2:common.Timeout exLong) } \ No newline at end of file diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index b5ae7d6d0..96c8bd5c2 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -184,14 +184,6 @@ class CSharpQueryHandler : public CsharpServiceIf _service -> getDiagramTypes(return_, astNodeId_); } - void getDiagram( - std::string& return_, - const core::AstNodeId& astNodeId_, - const std::int32_t diagramId_) override - { - _service -> getDiagram(return_, astNodeId_, diagramId_); - } - void getSyntaxHighlight( std::vector& return_, const core::FileRange& range_, @@ -205,21 +197,6 @@ class CSharpQueryHandler : public CsharpServiceIf _thriftServerPort = port; } - void getFileDiagramTypes( - std::map& return_, - const core::FileId& fileId_) override - { - _service -> getFileDiagramTypes(return_, fileId_); - } - - void getFileDiagram( - std::string& return_, - const core::FileId& fileId_, - const std::int32_t diagramId_) override - { - _service -> getFileDiagram(return_, fileId_, diagramId_); - } - void getFileUsages( std::map>& return_, const core::FileId& fileId_, diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 1992131ef..80d27cfe3 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -48,7 +48,7 @@ std::string graphHtmlTag( void removeAccessibilityTags(std::string& str){ std::vector accessibilityTags = - {"public", "private", "protected", "internal", "protected internal", "private protected"}; + {"protected internal", "private protected", "public", "private", "protected", "internal"}; for (auto const& tag : accessibilityTags){ if (str.find(tag) != std::string::npos) { @@ -76,123 +76,6 @@ CsharpDiagram::CsharpDiagram( { } -void CsharpDiagram::getClassCollaborationDiagram( - util::Graph& graph_, - const core::AstNodeId& astNodeId_) -{ - std::map visitedNodes; - std::map visitedEdges; - std::vector relatedNodes; - std::vector nodes; - -// graph_.setAttribute("rankdir", "BT"); - -// //--- Center node ---// - -// _cppHandler.getReferences( -// nodes, astNodeId_, CppServiceHandler::DEFINITION, {}); - -// if (nodes.empty()) -// return; - -// AstNodeInfo nodeInfo = nodes.front(); - -// util::Graph::Node centerNode = addNode(graph_, nodeInfo); -// decorateNode(graph_, centerNode, centerClassNodeDecoration); -// visitedNodes[nodeInfo.id] = centerNode; -// relatedNodes.push_back(nodeInfo); - -// nodes.clear(); - -// //--- Types from which the queried type inherits ---// - -// _cppHandler.getReferences(nodes, nodeInfo.id, -// CppServiceHandler::INHERIT_FROM, {}); - -// for (const AstNodeInfo& node : nodes) -// { -// util::Graph::Node inheritNode = addNode(graph_, node); -// graph_.setNodeAttribute(inheritNode, "label", -// node.astNodeValue, true); -// decorateNode(graph_, inheritNode, classNodeDecoration); - -// util::Graph::Edge edge = graph_.createEdge(centerNode, inheritNode); -// decorateEdge(graph_, edge, inheritClassEdgeDecoration); - -// visitedNodes[node.id] = inheritNode; -// relatedNodes.push_back(node); -// } - -// nodes.clear(); - -// //--- Types by which the queried type is inherited ---// - -// _cppHandler.getReferences(nodes, nodeInfo.id, -// CppServiceHandler::INHERIT_BY, {}); - -// for (const AstNodeInfo& node : nodes) -// { -// util::Graph::Node inheritNode = addNode(graph_, node); -// graph_.setNodeAttribute(inheritNode, "label", -// node.astNodeValue, true); -// decorateNode(graph_, inheritNode, classNodeDecoration); - -// util::Graph::Edge edge = graph_.createEdge(inheritNode, centerNode); -// decorateEdge(graph_, edge, inheritClassEdgeDecoration); - -// visitedNodes[node.id] = inheritNode; -// relatedNodes.push_back(node); -// } - -// //--- Get related types for the current and related types ---// - -// for (const AstNodeInfo& relatedNode : relatedNodes) -// { -// std::vector dataMembers; -// _cppHandler.getReferences(dataMembers, relatedNode.id, -// CppServiceHandler::DATA_MEMBER, {}); - -// for (const AstNodeInfo& node : dataMembers) -// { -// std::vector types; -// _cppHandler.getReferences(types, node.id, CppServiceHandler::TYPE, {}); - -// if (types.empty()) -// continue; - -// AstNodeInfo typeInfo = types.front(); - -// util::Graph::Node typeNode; -// auto it = visitedNodes.find(typeInfo.id); -// if (it == visitedNodes.end()) -// { -// typeNode = addNode(graph_, typeInfo); -// decorateNode(graph_, typeNode, classNodeDecoration); -// visitedNodes.insert(it, std::make_pair(typeInfo.id, typeNode)); -// } -// else -// typeNode = it->second; - -// GraphNodePair graphEdge(visitedNodes[relatedNode.id], typeNode); -// auto edgeIt = visitedEdges.find(graphEdge); -// if (edgeIt == visitedEdges.end()) -// { -// util::Graph::Edge edge = -// graph_.createEdge(visitedNodes[relatedNode.id], typeNode); -// decorateEdge(graph_, edge, usedClassEdgeDecoration); -// graph_.setEdgeAttribute(edge, "label", node.astNodeValue); -// visitedEdges.insert(edgeIt, std::make_pair(graphEdge, edge)); -// } -// else -// { -// std::string oldLabel = graph_.getEdgeAttribute(edgeIt->second, "label"); -// graph_.setEdgeAttribute(edgeIt->second, "label", -// oldLabel + ", " + node.astNodeValue); -// } -// } -// } -} - void CsharpDiagram::getFunctionCallDiagram( util::Graph& graph_, const AstNodeInfo& centerNodeInfo_, @@ -253,13 +136,15 @@ void CsharpDiagram::getDetailedClassDiagram( { graph_.setAttribute("rankdir", "BT"); - // Center node + // Center node - class AstNodeInfo nodeInfo = centerNodeInfo_; removeAccessibilityTags(nodeInfo.astNodeValue); nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); - util::Graph::Node centerNode = addNode(graph_, nodeInfo); + + // Property and method/contructor nodes + graph_.setNodeAttribute(centerNode,"label", getDetailedClassNodeLabel(nodeInfo,propertyNodeInfos_,methodNodeInfos_), true); @@ -333,13 +218,13 @@ std::string CsharpDiagram::visibilityToHtml(const AstNodeInfo& node_) if (contains(node_.tags, "Private")) return graphHtmlTag("font", "-", "color='red'"); if (contains(node_.tags, "Private protected")) - return graphHtmlTag("font", "-", "color='red'"); + return graphHtmlTag("font", "-#", "color='red'"); if (contains(node_.tags, "Protected")) return graphHtmlTag("font", "#", "color='blue'"); if (contains(node_.tags, "Internal")) - return graphHtmlTag("font", "#", "color='blue'"); + return graphHtmlTag("font", "~", "color='blue'"); if (contains(node_.tags, "Protected internal")) - return graphHtmlTag("font", "#", "color='blue'"); + return graphHtmlTag("font", "#~", "color='blue'"); return ""; } @@ -366,15 +251,6 @@ std::string CsharpDiagram::memberContentToHtml( return startTags + util::escapeHtml(content_) + endTags; } -std::string CsharpDiagram::getProperty( - const core::AstNodeId& astNodeId_, - const std::string& property_) -{ - // std::map properties; - // _cppHandler.getProperties(properties, astNodeId_); - // return properties[property_]; -} - util::Graph::Node CsharpDiagram::addNode( util::Graph& graph_, const AstNodeInfo& nodeInfo_) @@ -400,11 +276,16 @@ std::string CsharpDiagram::getDetailedClassLegend() {"label", graphHtmlTag("font", "-", "color='red'")}}, true); builder.addNode("protected data member", {{"shape", "none"}, {"label", graphHtmlTag("font", "#", "color='blue'")}}, true); + builder.addNode("internal data member", {{"shape", "none"}, + {"label", graphHtmlTag("font", "~", "color='blue'")}}, true); + builder.addNode("private protected data member", {{"shape", "none"}, + {"label", graphHtmlTag("font", "-#", "color='blue'")}}, true); + builder.addNode("protected internal data member", {{"shape", "none"}, + {"label", graphHtmlTag("font", "#~", "color='blue'")}}, true); builder.addNode("static method or data member", {{"shape", "none"}, {"label", "static"}}, true); builder.addNode("virtual method", {{"shape", "none"}, {"label", "virtual"}}, true); - //builder.addEdge("inheritance", inheritClassEdgeDecoration); return builder.getOutput(); } @@ -423,18 +304,6 @@ std::string CsharpDiagram::getFunctionCallLegend() return builder.getOutput(); } -std::string CsharpDiagram::getClassCollaborationLegend() -{ - util::LegendBuilder builder("Class Collaboration CsharpDiagram"); - - builder.addNode("center class", centerClassNodeDecoration); - builder.addNode("class", classNodeDecoration); - builder.addEdge("contained or used class", usedClassEdgeDecoration); - builder.addEdge("inheritance", inheritClassEdgeDecoration); - - return builder.getOutput(); -} - util::Graph::Subgraph CsharpDiagram::addSubgraph( util::Graph& graph_, const core::FileId& fileId_) @@ -514,25 +383,10 @@ const CsharpDiagram::Decoration CsharpDiagram::callerEdgeDecoration = { {"color", "red"} }; -const CsharpDiagram::Decoration CsharpDiagram::centerClassNodeDecoration = { - {"style", "filled"}, - {"fillcolor", "gold"}, - {"shape", "box"} -}; - const CsharpDiagram::Decoration CsharpDiagram::classNodeDecoration = { {"shape", "box"} }; -const CsharpDiagram::Decoration CsharpDiagram::usedClassEdgeDecoration = { - {"style", "dashed"}, - {"color", "mediumpurple"} -}; - -const CsharpDiagram::Decoration CsharpDiagram::inheritClassEdgeDecoration = { - {"arrowhead", "empty"} -}; - } } } \ No newline at end of file diff --git a/plugins/csharp/service/src/csharpdiagram.h b/plugins/csharp/service/src/csharpdiagram.h index a401cd01e..c5a82800b 100644 --- a/plugins/csharp/service/src/csharpdiagram.h +++ b/plugins/csharp/service/src/csharpdiagram.h @@ -49,20 +49,6 @@ class CsharpDiagram */ std::string getDetailedClassLegend(); - /** - * This diagram for a class shows recursively the related classes and their - * inheritance and containment relationships. - */ - void getClassCollaborationDiagram( - util::Graph& graph_, - const core::AstNodeId& astNodeId_); - - /** - * This function creates legend for the Class collaboration diagram. - * @return The generated legend as a string in SVG format. - */ - std::string getClassCollaborationLegend(); - private: typedef std::vector> Decoration; typedef std::pair GraphNodePair; @@ -109,13 +95,6 @@ class CsharpDiagram const AstNodeInfo& node_, const std::string& content_); - /** - * This function returns the property of an AST node. - */ - std::string getProperty( - const core::AstNodeId& astNodeId_, - const std::string& property_); - /** * This function decorates a graph node. * @param graph_ A graph object. @@ -155,14 +134,10 @@ class CsharpDiagram static const Decoration virtualNodeDecoration; static const Decoration calleeEdgeDecoration; static const Decoration callerEdgeDecoration; - static const Decoration centerClassNodeDecoration; static const Decoration classNodeDecoration; - static const Decoration usedClassEdgeDecoration; - static const Decoration inheritClassEdgeDecoration; std::map _subgraphs; - //CppServiceHandler _cppHandler; std::shared_ptr _db; util::OdbTransaction _transaction; core::ProjectServiceHandler _projectHandler; diff --git a/plugins/csharp/service/src/csharpfilediagram.cpp b/plugins/csharp/service/src/csharpfilediagram.cpp index ca382d31c..2a8c2ba68 100644 --- a/plugins/csharp/service/src/csharpfilediagram.cpp +++ b/plugins/csharp/service/src/csharpfilediagram.cpp @@ -19,16 +19,6 @@ namespace service namespace language { -//namespace language = cc::service::language; - -/*typedef odb::query IncludeQuery; -typedef odb::result IncludeResult; -typedef odb::query EdgeQuery; -typedef odb::result EdgeResult; -typedef odb::query TargetQuery; -typedef odb::result TargetResult; -typedef odb::query SourceQuery; -typedef odb::result SourceResult;*/ typedef odb::query FileQuery; typedef odb::result FileResult; typedef std::map> Usages; @@ -43,55 +33,6 @@ CsharpFileDiagram::CsharpFileDiagram( _projectHandler(db_, datadir_, context_) { } -/* -void CsharpFileDiagram::getComponentUsersDiagram( - util::Graph& graph_, - const core::FileId& fileId_) -{ - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId_); - util::Graph::Node currentNode = addNode(graph_, fileInfo); - decorateNode(graph_, currentNode, centerNodeDecoration); - - std::set provides = util::bfsBuild(graph_, currentNode, - std::bind(&CsharpFileDiagram::getProvides, this, std::placeholders::_1, - std::placeholders::_2), {}, providesEdgeDecoration, 1); - - std::set usedHeaders = provides; - for (const util::Graph::Node& provide : provides) - { - std::set revusages = util::bfsBuild(graph_, provide, - std::bind(&CsharpFileDiagram::getRevUsages, this, std::placeholders::_1, - std::placeholders::_2), {}, revUsagesEdgeDecoration); - - for (const util::Graph::Node& revusage : revusages) - usedHeaders.insert(revusage); - } - - for (const util::Graph::Node& source : usedHeaders) - util::bfsBuild(graph_, source, std::bind(&CsharpFileDiagram::getRevContains, - this, std::placeholders::_1, std::placeholders::_2), - {}, revContainsEdgeDecoration); -} - -std::string CsharpFileDiagram::getComponentUsersDiagramLegend() -{ - util::LegendBuilder builder("Component Users Diagram"); - - builder.addNode("center file", centerNodeDecoration); - builder.addNode("directory", directoryNodeDecoration); - builder.addNode("binary file", binaryFileNodeDecoration); - builder.addNode("source file", sourceFileNodeDecoration); - builder.addNode("header file", headerFileNodeDecoration); - builder.addNode("object file", objectFileNodeDecoration); - - builder.addEdge("provides", providesEdgeDecoration); - builder.addEdge("used by files", revUsagesEdgeDecoration); - builder.addEdge("contained by", revContainsEdgeDecoration); - - return builder.getOutput(); -} -*/ void CsharpFileDiagram::getFileUsagesDiagram( util::Graph& graph_, @@ -161,58 +102,7 @@ std::string CsharpFileDiagram::getFileUsagesDiagramLegend() return builder.getOutput(); } -/* -void CsharpFileDiagram::getExternalDependencyDiagram( - util::Graph& graph_, - const core::FileId& fileId_) -{ - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId_); - util::Graph::Node currentNode = addNode(graph_, fileInfo); - decorateNode(graph_, currentNode, centerNodeDecoration); - - std::set subdirs = util::bfsBuild(graph_, currentNode, - std::bind(&CsharpFileDiagram::getSubDirs, this, std::placeholders::_1, - std::placeholders::_2), {}, subdirEdgeDecoration); - - subdirs.insert(currentNode); - for (const util::Graph::Node& subdir : subdirs) - { - for (const util::Graph::Node& impl : getImplements(graph_, subdir)) - if (subdirs.find(impl) == subdirs.end()) - { - util::Graph::Edge edge = graph_.createEdge(subdir, impl); - decorateEdge(graph_, edge, implementsEdgeDecoration); - } - - for (const util::Graph::Node& dep : getDepends(graph_, subdir)) - if (subdirs.find(dep) == subdirs.end()) - { - util::Graph::Edge edge = graph_.createEdge(subdir, dep); - decorateEdge(graph_, edge, dependsEdgeDecoration); - } - } -} - -std::string CsharpFileDiagram::getExternalDependencyDiagramLegend() -{ - util::LegendBuilder builder("External Dependency Diagram"); - - builder.addNode("center file", centerNodeDecoration); - builder.addNode("directory", directoryNodeDecoration); - builder.addNode("binary file", binaryFileNodeDecoration); - builder.addNode("source file", sourceFileNodeDecoration); - builder.addNode("header file", headerFileNodeDecoration); - builder.addNode("object file", objectFileNodeDecoration); - - builder.addEdge("sub directory", subdirEdgeDecoration); - builder.addEdge("implements", implementsEdgeDecoration); - builder.addEdge("depends on", dependsEdgeDecoration); - - return builder.getOutput(); -} -*/ void CsharpFileDiagram::getExternalUsersDiagram( util::Graph& graph_, const core::FileId& fileId_, @@ -258,9 +148,6 @@ void CsharpFileDiagram::getExternalUsersDiagram( } } } - - - } std::string CsharpFileDiagram::getExternalUsersDiagramLegend() @@ -275,61 +162,7 @@ std::string CsharpFileDiagram::getExternalUsersDiagramLegend() return builder.getOutput(); } -/* -void CsharpFileDiagram::getInterfaceDiagram( - util::Graph& graph_, - const core::FileId& fileId_) -{ - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId_); - util::Graph::Node currentNode = addNode(graph_, fileInfo); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getProvides, - this, std::placeholders::_1, std::placeholders::_2), - {}, providesEdgeDecoration, 1); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getContains, - this, std::placeholders::_1, std::placeholders::_2), - {}, containsEdgeDecoration, 1); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getUsages, - this, std::placeholders::_1, std::placeholders::_2), - {}, usagesEdgeDecoration, 1); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevProvides, - this, std::placeholders::_1, std::placeholders::_2), - {}, revProvidesEdgeDecoration, 1); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevContains, - this, std::placeholders::_1, std::placeholders::_2), - {}, revContainsEdgeDecoration, 1); - - util::bfsBuild(graph_, currentNode, std::bind(&CsharpFileDiagram::getRevUsages, - this, std::placeholders::_1, std::placeholders::_2), - {}, revUsagesEdgeDecoration, 1); -} - -std::string CsharpFileDiagram::getInterfaceDiagramLegend() -{ - util::LegendBuilder builder("Interface Diagram"); - builder.addNode("center file", centerNodeDecoration); - builder.addNode("directory", directoryNodeDecoration); - builder.addNode("binary file", binaryFileNodeDecoration); - builder.addNode("source file", sourceFileNodeDecoration); - builder.addNode("header file", headerFileNodeDecoration); - builder.addNode("object file", objectFileNodeDecoration); - - builder.addEdge("provides", providesEdgeDecoration); - builder.addEdge("contains", containsEdgeDecoration); - builder.addEdge("uses", usagesEdgeDecoration); - builder.addEdge("provided by", revProvidesEdgeDecoration); - builder.addEdge("contained by", revContainsEdgeDecoration); - builder.addEdge("used by", revUsagesEdgeDecoration); - - return builder.getOutput(); -} -*/ void CsharpFileDiagram::getSubsystemDependencyDiagram( util::Graph& graph_, const core::FileId& fileId_) @@ -358,49 +191,7 @@ std::string CsharpFileDiagram::getSubsystemDependencyDiagramLegend() return builder.getOutput(); } -/* -std::vector FileDiagram::getIncludedFiles( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector include; - _transaction([&, this]{ - IncludeResult res = _db->query( - (reverse_ - ? IncludeQuery::included->id - : IncludeQuery::includer->id) == std::stoull(node_)); - - for (const auto& inclusion : res) - { - model::FileId fileId = reverse_ - ? inclusion.includer.object_id() - : inclusion.included.object_id(); - - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, std::to_string(fileId)); - include.push_back(addNode(graph_, fileInfo)); - } - }); - - return include; -} - -std::vector CsharpFileDiagram::getIncludes( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getIncludedFiles(graph_, node_); -} - -std::vector CsharpFileDiagram::getRevIncludes( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getIncludedFiles(graph_, node_, true); -} -*/ std::vector CsharpFileDiagram::getSubDirs( util::Graph& graph_, const util::Graph::Node& node_) @@ -423,299 +214,6 @@ std::vector CsharpFileDiagram::getSubDirs( return usages; } -/* -std::vector CsharpFileDiagram::getImplements( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getImplementedFiles(graph_, node_); -} - -std::vector CsharpFileDiagram::getRevImplements( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getImplementedFiles(graph_, node_, true); -} - -std::vector FileDiagram::getImplementedFiles( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector implements; - _transaction([&, this] - { - auto contained = _db->query( - odb::query::parent == std::stoull(node_) && - odb::query::type != model::File::DIRECTORY_TYPE - ); - std::unordered_set used; - - for (const model::File &file : contained) - { - auto files = getProvidedFileIds(graph_, std::to_string(file.id), reverse_); - used.insert(files.begin(), files.end()); - } - for (const core::FileId& fileId : used) - { - auto file = _db->load(std::stoull(fileId)); - implements.push_back(std::to_string(file.get()->parent.object_id())); - } - std::sort(implements.begin(), implements.end()); - auto it = std::unique(implements.begin(), implements.end()); - implements.resize(it - implements.begin()); - implements.erase(std::remove_if(implements.begin(), implements.end(), - [&node_](const util::Graph::Node& n){ return node_ == n; }), - implements.end()); - }); - - std::vector annotated; - - for (const core::FileId& fileId : implements) - { - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId); - - annotated.push_back(addNode(graph_, fileInfo)); - } - return annotated; -} - -std::vector CsharpFileDiagram::getDepends( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getDependFiles(graph_, node_); -} - -std::vector CsharpFileDiagram::getRevDepends( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getDependFiles(graph_, node_, true); -} - -std::vector FileDiagram::getDependFiles( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector depends; - - _transaction([&, this]{ - auto contained = _db->query( - odb::query::parent == std::stoull(node_) && - odb::query::type != model::File::DIRECTORY_TYPE - ); - - std::unordered_set used; - - for(const model::File& file : contained) - { - auto files = getUsedFileIds(graph_, std::to_string(file.id), reverse_); - used.insert(files.begin(), files.end()); - } - - for(const core::FileId& fileId : used) - { - auto files =_db->query( - odb::query::id == std::stoull(fileId) - ); - - for(const model::File& file : files) - { - depends.push_back(std::to_string(file.parent.object_id())); - } - } - - std::sort(depends.begin(), depends.end()); - auto it = std::unique(depends.begin(), depends.end()); - depends.resize(it - depends.begin()); - depends.erase(std::remove_if(depends.begin(), depends.end(), - [&node_](const util::Graph::Node& n){ return node_ == n; }), - depends.end()); - }); - - std::vector annotated; - - for (const core::FileId& fileId: depends) - { - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId); - - annotated.push_back(addNode(graph_, fileInfo)); - } - return annotated; -} - -std::vector CsharpFileDiagram::getProvides( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getProvidedFiles(graph_, node_); -} - -std::vector CsharpFileDiagram::getRevProvides( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getProvidedFiles(graph_, node_, true); -} - -std::vector CsharpFileDiagram::getProvidedFiles( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector depends; - - std::vector fileIds = getProvidedFileIds(graph_, node_, reverse_); - - for (const core::FileId& fileId : fileIds) - { - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId); - - depends.push_back(addNode(graph_, fileInfo)); - } - - return depends; -} - -std::vector FileDiagram::getProvidedFileIds( - util::Graph&, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector depends; - - _transaction([&, this]{ - EdgeResult res = _db->query( - (reverse_ - ? EdgeQuery::to->id - : EdgeQuery::from->id) == std::stoull(node_) && - EdgeQuery::type == model::CppEdge::PROVIDE); - - for (const model::CppEdge& edge : res) - { - core::FileId fileId = reverse_ ? std::to_string(edge.from->id) : std::to_string(edge.to->id); - depends.push_back(fileId); - } - }); - - return depends; -} - -std::vector FileDiagram::getContains( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - std::vector contained; - - _transaction([&, this]{ - TargetResult targets = _db->query( - TargetQuery::file == std::stoull(node_)); - - for (const model::BuildTarget& target : targets) - for (const auto& source : target.action->sources) - { - model::FileId fileId = source.lock().load()->file->id; - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, std::to_string(fileId)); - contained.push_back(addNode(graph_, fileInfo)); - } - }); - - return contained; -} - -std::vector FileDiagram::getRevContains( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - std::vector contained; - std::set files; - - _transaction([&, this]{ - SourceResult sources = _db->query( - SourceQuery::file == std::stoull(node_)); - for (const model::BuildSource& source : sources) - for (const auto& target : source.action->targets) - { - model::FileId fileId = target.lock().load()->file->id; - - if (!files.insert(fileId).second) - continue; - - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, std::to_string(fileId)); - contained.push_back(addNode(graph_, fileInfo)); - } - }); - - return contained; -} - -std::vector CsharpFileDiagram::getUsages( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getUsedFiles(graph_, node_); -} - -std::vector CsharpFileDiagram::getRevUsages( - util::Graph& graph_, - const util::Graph::Node& node_) -{ - return getUsedFiles(graph_, node_, true); -} - -std::vector CsharpFileDiagram::getUsedFiles( - util::Graph& graph_, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector usages; - - // std::vector fileIds = getUsedFileIds(graph_, node_, reverse_); - - for (const core::FileId& fileId: fileIds) - { - core::FileInfo fileInfo; - _projectHandler.getFileInfo(fileInfo, fileId); - - usages.push_back(addNode(graph_, fileInfo)); - } - - return usages; -} - -/*std::vector FileDiagram::getUsedFileIds( - util::Graph&, - const util::Graph::Node& node_, - bool reverse_) -{ - std::vector usages; - - _transaction([&, this]{ - EdgeResult res = _db->query( - (reverse_ - ? EdgeQuery::to->id - : EdgeQuery::from->id) == std::stoull(node_) && - EdgeQuery::type == model::CppEdge::USE); - - for (const model::CppEdge& edge : res) - { - core::FileId fileId = reverse_ ? std::to_string(edge.from->id) : std::to_string(edge.to->id); - - usages.push_back(fileId); - } - }); - - return usages; -} -*/ std::vector CsharpFileDiagram::getNodesFromIds( util::Graph& graph, @@ -745,10 +243,6 @@ util::Graph::Node CsharpFileDiagram::addNode( { decorateNode(graph_, node, directoryNodeDecoration); } - else if (fileInfo_.type == model::File::BINARY_TYPE) - { - decorateNode(graph_, node, binaryFileNodeDecoration); - } else if (fileInfo_.type == "CS") { std::string ext = boost::filesystem::extension(fileInfo_.path); @@ -804,26 +298,6 @@ const CsharpFileDiagram::Decoration CsharpFileDiagram::sourceFileNodeDecoration {"fontcolor", "white"} }; -const CsharpFileDiagram::Decoration CsharpFileDiagram::headerFileNodeDecoration = { - {"style", "filled"}, - {"fillcolor", "#ef4756"}, - {"fontcolor", "white"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::binaryFileNodeDecoration = { - {"shape", "box3d"}, - {"style", "filled"}, - {"fillcolor", "#f18a21"}, - {"fontcolor", "white"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::objectFileNodeDecoration = { - {"shape", "folder"}, - {"style", "filled"}, - {"fillcolor", "#6fc59e"}, - {"fontcolor", "white"} -}; - const CsharpFileDiagram::Decoration CsharpFileDiagram::directoryNodeDecoration = { {"shape", "folder"} }; @@ -836,51 +310,11 @@ const CsharpFileDiagram::Decoration CsharpFileDiagram::revUsagesEdgeDecoration = {"label", "used by"} }; -const CsharpFileDiagram::Decoration CsharpFileDiagram::providesEdgeDecoration = { - {"label", "provides"}, - {"color", "red"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::revProvidesEdgeDecoration = { - {"label", "provided by"}, - {"color", "red"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::containsEdgeDecoration = { - {"label", "contains"}, - {"color", "blue"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::revContainsEdgeDecoration = { - {"label", "contained by"}, - {"color", "blue"} -}; - const CsharpFileDiagram::Decoration CsharpFileDiagram::subdirEdgeDecoration = { {"label", "subdir"}, {"color", "green"} }; -const CsharpFileDiagram::Decoration CsharpFileDiagram::implementsEdgeDecoration = { - {"label", "implements"}, - {"color", "red"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::revImplementsEdgeDecoration = { - {"label", "implemented by"}, - {"color", "red"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::dependsEdgeDecoration = { - {"label", "depends on"}, - {"color", "blue"} -}; - -const CsharpFileDiagram::Decoration CsharpFileDiagram::revDependsEdgeDecoration = { - {"label", "dependent on"}, - {"color", "blue"} -}; - } // language } // service } // cc \ No newline at end of file diff --git a/plugins/csharp/service/src/csharpfilediagram.h b/plugins/csharp/service/src/csharpfilediagram.h index b2cc3f11f..411acd21f 100644 --- a/plugins/csharp/service/src/csharpfilediagram.h +++ b/plugins/csharp/service/src/csharpfilediagram.h @@ -1,8 +1,6 @@ #ifndef CC_SERVICE_LANGUAGE_CSHARPFILEDIAGRAM_H #define CC_SERVICE_LANGUAGE_CSHARPFILEDIAGRAM_H -//copied - #include #include #include @@ -14,7 +12,6 @@ namespace service namespace language { -//namespace language = cc::service::language; typedef std::map> Usages; typedef std::map> DirectoryUsages; @@ -26,21 +23,6 @@ class CsharpFileDiagram std::shared_ptr datadir_, const cc::webserver::ServerContext& context_); - /** - * This diagram shows the module which directory depends on. The "depends on" - * diagram on module A traverses the subdirectories of module A and shows all - * directories that contain files that any of the source files in A includes. - */ - //void getExternalDependencyDiagram( - // util::Graph& graph_, - // const core::FileId& fileId_); - - /** - * This function creates legend for the External dependency diagram. - * @return The generated legend as a string in SVG format. - */ - //std::string getExternalDependencyDiagramLegend(); - /** * This diagram shows directories (modules) that are users of the * queried module. @@ -57,7 +39,8 @@ class CsharpFileDiagram std::string getExternalUsersDiagramLegend(); /** - * This diagram shows of the `#include` file dependencies. + * This diagram shows of the aggregation and association + * related file "use" and "used" dependencies. */ void getFileUsagesDiagram( util::Graph& graph_, @@ -71,20 +54,6 @@ class CsharpFileDiagram */ std::string getFileUsagesDiagramLegend(); - /** - * Interface diagram shows the used and provided interfaces of a source code - * file and shows linking information. - */ - //void getInterfaceDiagram( - // util::Graph& graph_, - // const core::FileId& fileId_); - - /** - * This function creates legend for the Interface diagram. - * @return The generated legend as a string in SVG format. - */ - //std::string getInterfaceDiagramLegend(); - /** * This diagram shows the directories relationship between the subdirectories * of the queried module. This diagram is useful to understand the @@ -100,23 +69,13 @@ class CsharpFileDiagram */ std::string getSubsystemDependencyDiagramLegend(); - /** - * Component users diagram for source file S shows which source files depend - * on S through the interfaces S provides. - */ - //void getComponentUsersDiagram( - // util::Graph& graph_, - // const core::FileId& fileId_); - - /** - * This function creates legend for the Component users diagram. - * @return The generated legend as a string in SVG format. - */ - //std::string getComponentUsersDiagramLegend(); - private: typedef std::vector> Decoration; + /** + * This function gathers the fileInfo related to the given file IDs + * and returns a list of nodes using the file infos. + */ std::vector getNodesFromIds( util::Graph& graph, const std::vector& fileIds); @@ -158,38 +117,6 @@ class CsharpFileDiagram */ std::string getLastNParts(const std::string& path_, std::size_t n_); - /** - * This function creates graph nodes for each files which the given one - * includes. - * @see getIncludedFiles() - */ - //std::vector getIncludes( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function creates graph nodes for each files which includes the given - * file. - * @note This function is the revert version of the getIncludes function. - * @see getIncludedFiles() - */ - //std::vector getRevIncludes( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function returns the graph nodes which the given file includes. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @param reverse_ If true then it creates graph nodes for each file which - * includes the given file. - * @return Created graph nodes. - */ - /*std::vector getIncludedFiles( - util::Graph& graph_, - const util::Graph::Node& fileNode_, - bool reverse_ = false); - */ /** * This function creates graph nodes for sub directories of the actual file * node and returns the created graph nodes. @@ -201,208 +128,16 @@ class CsharpFileDiagram util::Graph& graph_, const util::Graph::Node& fileNode_); - /** - * This function creates graph nodes for each files which files implements - * the given one. - * @see getImplementedFiles() - */ - //std::vector getImplements( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function creates graph nodes for each files which implements the given - * file. - * @note This function is the revert version of the getImplements function. - * @see getImplementedFiles() - */ - //std::vector getRevImplements( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function creates graph nodes for each files which implements the - * given file. - * @note `A` implements `B` if a function which is defined in `A` declared - * in `B`. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @param reverse_ If true then it creates graph nodes for each file which - * implements the given file. - * @return Created graph nodes. - */ - //std::vector getImplementedFiles( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_, - // bool reverse_ = false); - - /** - * This function returns graph nodes which the given file depends on. - * @see getDependFiles() - */ - //std::vector getDepends( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function returns graph nodes which depends from the given file. - * @note This function is the revert version of the getImplements function. - * @see getDependFiles() - */ - //std::vector getRevDepends( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function returns graph nodes which the given file depends on. - * @note File `A` depends on file `B` if: - * - `A` has a value declaration which type is a record type which was - * declared in `B`. - * E.g.: In file A `T x;` is a value declaration and T is a record type - * which was declared in file `B` then `A` depends on `B`. - * - `A` has a function call which declaration is located in file `B`. - * E.g.: In file A `f()` is a function call which function was declared - * in file `B` then `A` depends on `B`. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @param reverse_ If true then it creates graph nodes for each file which - * depends the given file. - * @return Created graph nodes. - */ - //std::vector getDependFiles( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_, - // bool reverse_ = false); - - /** - * This function creates graph nodes for each files which files provides - * the given one. - * @see getProvidedFiles() - */ - //std::vector getProvides( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function creates graph nodes for each files which provides the given - * file. - * @note This function is the revert version of the getProvides function. - * @see getProvidedFiles() - */ - //std::vector getRevProvides( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function creates graph nodes for each files which provides the - * given file. - * `A` provides `B` if a function which is defined in `A` , declared in `B` - * and `A` is not the same as `B`. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @param reverse_ If true then it creates graph nodes for each file which - * provides the given file. - * @return Created graph nodes. - */ - //std::vector getProvidedFiles( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_, - // bool reverse_ = false); - - //std::vector getProvidedFileIds( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_, - // bool reverse_ = false); - - /** - * This function creates graph nodes for each build sources which related to - * the given build target. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @return Created graph nodes. - */ - //std::vector getContains( - // util::Graph& graph_, - // const util::Graph::Node& fileNode_); - - /** - * This function creates graph nodes for each build targets which related to - * the given build source. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @return Created graph nodes. - */ - //std::vector getRevContains( - // util::Graph& graph_, - // const util::Graph::Node& node_); - - /** - * This function creates graph nodes for each files which files use the - * given one. - * @see getUsedFiles() - */ - //std::vector getUsages( - // util::Graph& graph_, - // const util::Graph::Node& node_); - - /** - * This function creates graph nodes for each files which use the given file. - * @note This function is the revert version of the getUsages function. - * @see getUsedFiles() - */ - //std::vector getRevUsages( - // util::Graph& graph_, - // const util::Graph::Node& node_); - - /** - * This function returns graph nodes which the given file depends on. - * @note File `A` use file `B` (A<>B) if: - * - `A` has a value declaration which type is a record type which was - * declared in `B`. - * E.g.: In file A `T x;` is a value declaration and T is a record type - * which was declared in file `B` then `A` use `B`. - * - `A` has a function call which declaration is located in file `B`. - * E.g.: In file A `f()` is a function call which function was declared - * in file `B` then `A` use `B`. - * @param graph_ A graph object. - * @param fileNode_ Graph file node object which represents a file object. - * @param reverse_ If true then it creates graph nodes for each file which - * use the given file. - * @return Created graph nodes. - */ - //std::vector getUsedFiles( - // util::Graph& graph_, - // const util::Graph::Node& node_, - // bool reverse_ = false); - - //std::vector getUsedFileIds( - // util::Graph& graph_, - // const util::Graph::Node& node_, - // bool reverse_); - static const Decoration centerNodeDecoration; static const Decoration sourceFileNodeDecoration; - static const Decoration headerFileNodeDecoration; - static const Decoration binaryFileNodeDecoration; - static const Decoration objectFileNodeDecoration; static const Decoration directoryNodeDecoration; static const Decoration usagesEdgeDecoration; static const Decoration revUsagesEdgeDecoration; - static const Decoration providesEdgeDecoration; - static const Decoration revProvidesEdgeDecoration; - static const Decoration containsEdgeDecoration; - static const Decoration revContainsEdgeDecoration; static const Decoration subdirEdgeDecoration; - static const Decoration implementsEdgeDecoration; - static const Decoration revImplementsEdgeDecoration; - static const Decoration dependsEdgeDecoration; - static const Decoration revDependsEdgeDecoration; std::shared_ptr _db; util::OdbTransaction _transaction; - //CppServiceHandler _cppHandler; - //cc::service::csharp::CSharpQueryHandler _csharpQueryHandler; core::ProjectServiceHandler _projectHandler; }; diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index 1e79f3f53..b628a289b 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -164,28 +164,14 @@ void CsharpServiceHandler::getDiagram( // Center node AstNodeInfo centerInfo; getAstNodeInfo(centerInfo,astNodeId_); - //logging purposes - LOG(info) << "centerastnodeinfo: "; - LOG(info) << "astnodetype: " << centerInfo.astNodeType; - LOG(info) << "value: " << centerInfo.astNodeValue; - LOG(info) << "entityhash: " << centerInfo.entityHash; - LOG(info) << "symboltype: " << centerInfo.symbolType; // Callee nodes std::vector calleeInfos; getReferences(calleeInfos,astNodeId_,(int)ReferenceType::CALLEE,{}); - //logging purposes - for (const auto& info : calleeInfos){ - LOG(info) << "CalleeInfo: " << info.astNodeValue; - } // Caller nodes std::vector callerInfos; getReferences(callerInfos,astNodeId_,(int)ReferenceType::CALLER,{}); - //logging purposes - for (const auto& info : calleeInfos){ - LOG(info) << "CallerInfo: " << info.astNodeValue; - } diagram.getFunctionCallDiagram(graph,centerInfo,calleeInfos,callerInfos); break; @@ -215,10 +201,8 @@ void CsharpServiceHandler::getDiagram( } } - if (graph.nodeCount() != 0) return_ = graph.output(util::Graph::SVG); - //_csharpQueryHandler.getDiagram(return_, astNodeId_, diagramId_); } void CsharpServiceHandler::getDiagramLegend( @@ -246,7 +230,6 @@ void CsharpServiceHandler::getFileDiagramTypes( const core::FileId& fileId_) { LOG(info) << "getFileDiagramTypes"; - //_csharpQueryHandler.getFileDiagramTypes(return_, fileId_); //most irtam model::FilePtr file = _transaction([&, this](){ return _db->query_one( @@ -279,17 +262,10 @@ void CsharpServiceHandler::getFileDiagram( graph.setAttribute("rankdir", "LR"); switch (diagramId_){ - case FILE_USAGES: //FILE_USAGES + case FILE_USAGES: { Usages useIds; _csharpQueryHandler.getFileUsages(useIds,fileId_,false); - // for (const auto& entry : data){ - // LOG(info) << "Key: " << entry.first; - // LOG(info) << "Value:"; - // for (const auto& value : entry.second){ - // LOG(info) << value; - // } - // } Usages revUseIds; _csharpQueryHandler.getFileUsages(revUseIds,fileId_,true); @@ -312,7 +288,6 @@ void CsharpServiceHandler::getFileDiagram( FileQuery::id == std::stoull(fileId_) ); }); - LOG(info) << "MAIN DIR PATH" << directory->path; //This will contain all the directories from the project std::vector directories; @@ -334,12 +309,6 @@ void CsharpServiceHandler::getFileDiagram( sub.push_back(dir); } - //LOGGING: check fetched directories - for (const auto& s : sub) - { - LOG(info) << s->path; - } - // Iterate on subddirectories and add a BFS to each CS file // under the subdir. // Gather for each subdir every BFS for every CS file into @@ -359,7 +328,6 @@ void CsharpServiceHandler::getFileDiagram( for (const model::FilePtr& cs : css) { std::string id = std::to_string(cs->id); - LOG(info) << "Converted CS ID: " << id; _csharpQueryHandler.getFileUsages(rev,id,true); revs.push_back(rev); rev.clear(); diff --git a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs index 3f3458f75..fbacee3bb 100644 --- a/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs +++ b/plugins/csharp/service/src_csharp/CSharpQueryHandler.cs @@ -589,13 +589,7 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, int referenceId, List tags, CancellationToken cancellationToken = default(CancellationToken)) { - var node = queryCsharpAstNode(astNodeId); - Console.WriteLine("getreferencesasync NODE"); - Console.WriteLine("getreferencesasync astsymboltype: " + node.AstSymbolType); - Console.WriteLine("getreferencesasync asttype: " + node.AstType); - Console.WriteLine("getreferencesasync astvalue: " + node.AstValue); - Console.WriteLine("getreferencesasync reftype: " + (ReferenceType)referenceId); - Console.WriteLine("getreferencesasync refid: " + referenceId); + var node = queryCsharpAstNode(astNodeId); var ret = new List(); switch ((ReferenceType)referenceId) { @@ -603,11 +597,6 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, ret = createAstNodeInfoList(queryInvocations(node)); break; case ReferenceType.DEFINITION: - Console.WriteLine("inside DEFINITION"); - // var nodes = new List(); - // nodes.Add(node); - // ret = createAstNodeInfoList(nodes); //experimental - //ret = createAstNodeInfoList(queryDeclarators(node)); ret = createAstNodeInfoList(queryDeclarators(node)); break; case ReferenceType.DECLARATION: @@ -663,17 +652,7 @@ public async Task getReferenceCountAsync(string astNodeId, int referenceId, " ReferenceType is unhandled"); break; } - if (ret.Any()) - System.Console.WriteLine("getreferencesasync result: ", ret.First()); - // foreach(var r in ret){ - // System.Console.WriteLine("nodeinfo: ",r.AstNodeType); - // System.Console.WriteLine(r.AstNodeValue); - // foreach(var tag in r.Tags) - // { - // System.Console.WriteLine(tag); - // } - - // } + return await Task.FromResult(ret); } @@ -716,12 +695,6 @@ public async Task> getDiagramTypesAsync(string astNodeId return await Task.FromResult(new Dictionary()); } - public async Task getDiagramAsync(string astNodeId, int diagramId, - CancellationToken cancellationToken = default(CancellationToken)) - { - return await Task.FromResult("Diagram"); - } - public async Task> getSyntaxHighlightAsync(FileRange range, List content, CancellationToken cancellationToken = default(CancellationToken)) @@ -729,21 +702,6 @@ public async Task getDiagramAsync(string astNodeId, int diagramId, return await Task.FromResult(new List()); } - public async Task> getFileDiagramTypesAsync(string fileId, - CancellationToken cancellationToken = default(CancellationToken)) - { - //TODO: DELETE - return await Task.FromResult(new Dictionary(){ - {"TEST DIAGRAM", 999} - }); - } - - public async Task getFileDiagramAsync(string fileId, int diagramId, - CancellationToken cancellationToken = default(CancellationToken)) - { - return await Task.FromResult("File Diagram"); - } - public async Task>> getFileUsagesAsync(string fileId, bool reverse = false, CancellationToken cancellationToken = default(CancellationToken)) { @@ -817,16 +775,6 @@ public static Dictionary> BFSBuild( } } - //LOG USED FILES - // foreach(var entry in visitedFiles) - // { - // Console.WriteLine("Key: ", entry.Key); - // Console.WriteLine("Values:"); - // foreach (string value in entry.Value) - // { - // Console.WriteLine(value); - // } - // } return visitedFiles; } } \ No newline at end of file From 27c02ada31201413c8a8b1b5e3585190cf371512 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Fri, 12 May 2023 02:54:02 +0200 Subject: [PATCH 46/49] Minor fixes --- plugins/csharp/parser/src_csharp/Program.cs | 1 - plugins/csharp/service/include/service/csharpservice.h | 7 +------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/plugins/csharp/parser/src_csharp/Program.cs b/plugins/csharp/parser/src_csharp/Program.cs index c93f3c5e8..f5f8755fb 100644 --- a/plugins/csharp/parser/src_csharp/Program.cs +++ b/plugins/csharp/parser/src_csharp/Program.cs @@ -181,7 +181,6 @@ private static async Task ParseTree(CsharpDbContext context, return await ParingTask; } - // private static async Task ParalellCollect(string csharpConnectionString, int threadNum, List trees, CSharpCompilation compilation) diff --git a/plugins/csharp/service/include/service/csharpservice.h b/plugins/csharp/service/include/service/csharpservice.h index 96c8bd5c2..5f31ad6c1 100644 --- a/plugins/csharp/service/include/service/csharpservice.h +++ b/plugins/csharp/service/include/service/csharpservice.h @@ -219,7 +219,7 @@ using TransportException = apache::thrift::transport::TTransportException; class CsharpServiceHandler : virtual public LanguageServiceIf { - friend class Diagram; + friend class CsharpDiagram; public: CsharpServiceHandler( @@ -321,11 +321,6 @@ class CsharpServiceHandler : virtual public LanguageServiceIf void getSyntaxHighlight( std::vector& return_, const core::FileRange& range_) override; - - // void getFileUsages( - // std::map>& return_, - // const core::FileId& fileId_, - // const bool reverse_) override; private: From c402353da3a72e4f0dd2a2089cdf21e9a7718212 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 13 May 2023 11:13:37 +0200 Subject: [PATCH 47/49] Unnecessary logs deleted --- plugins/csharp/service/src/csharpdiagram.cpp | 2 -- plugins/csharp/service/src/csharpservice.cpp | 11 +---------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 80d27cfe3..225363b05 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -85,7 +85,6 @@ void CsharpDiagram::getFunctionCallDiagram( graph_.setAttribute("rankdir", "LR"); // Center node - LOG(info) << "CENTER ASTNODE: " << centerNodeInfo_.astNodeValue; AstNodeInfo nodeInfo = centerNodeInfo_; removeAccessibilityTags(nodeInfo.astNodeValue); nodeInfo.astNodeValue = nodeInfo.astNodeValue.substr(0,nodeInfo.astNodeValue.find('{')); @@ -255,7 +254,6 @@ util::Graph::Node CsharpDiagram::addNode( util::Graph& graph_, const AstNodeInfo& nodeInfo_) { - LOG(info) << "addNode: " << nodeInfo_.id << nodeInfo_.range.file; util::Graph::Node node = graph_.getOrCreateNode(nodeInfo_.id, addSubgraph(graph_, nodeInfo_.range.file)); diff --git a/plugins/csharp/service/src/csharpservice.cpp b/plugins/csharp/service/src/csharpservice.cpp index b628a289b..6eb1f33b6 100644 --- a/plugins/csharp/service/src/csharpservice.cpp +++ b/plugins/csharp/service/src/csharpservice.cpp @@ -81,9 +81,8 @@ void CsharpServiceHandler::getAstNodeInfo( FileQuery::path == return_.range.file); }); std::stringstream ss; - ss << file->id; // itt csak siman ss<id; return_.range.file = ss.str(); - LOG(info) << "csharpQuery.getAstNodeInfo: file = " << return_.range.file; } void CsharpServiceHandler::getAstNodeInfoByPosition( @@ -185,16 +184,10 @@ void CsharpServiceHandler::getDiagram( //Data members - property nodes std::vector propertyInfos; getReferences(propertyInfos, astNodeId_,(int)ReferenceType::DATA_MEMBER,{}); - for (const auto& info : propertyInfos){ - LOG(info) << "PropertyInfo: " << info.astNodeValue; - } // Method nodes std::vector methodInfos; getReferences(methodInfos,astNodeId_,(int)ReferenceType::METHOD,{}); - for (const auto& info : methodInfos){ - LOG(info) << "MethodInfo: " << info.astNodeValue; - } diagram.getDetailedClassDiagram(graph,centInfo,propertyInfos,methodInfos); break; @@ -400,8 +393,6 @@ void CsharpServiceHandler::getReferences( return _db->query_one( FileQuery::path == nodeinfo.range.file); }); - LOG(info) << "getreferences: nodeInfo: " << nodeinfo.astNodeValue << " | " << nodeinfo.astNodeType; - LOG(info) << "getreferences: file: " << file->filename; std::stringstream ss; ss << file->id; From 8ea3295c7377260a3bc7971cae8b826c13034027 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 13 May 2023 11:27:39 +0200 Subject: [PATCH 48/49] Minor fix in removeAccessabilityTags method --- plugins/csharp/service/src/csharpdiagram.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 225363b05..269d079bd 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -52,8 +52,7 @@ void removeAccessibilityTags(std::string& str){ for (auto const& tag : accessibilityTags){ if (str.find(tag) != std::string::npos) { - str.erase(0,str.find(tag) + tag.length() + 1); - break; + str.erase(str.find(tag),str.find(tag) + tag.length() + 1); } } } From 984dfe9f87c15147a9f51af13993caff481392f1 Mon Sep 17 00:00:00 2001 From: ervin7mk Date: Sat, 13 May 2023 13:17:19 +0200 Subject: [PATCH 49/49] Small fix to annotation removal method. --- plugins/csharp/service/src/csharpdiagram.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/plugins/csharp/service/src/csharpdiagram.cpp b/plugins/csharp/service/src/csharpdiagram.cpp index 269d079bd..0fa00b8e4 100644 --- a/plugins/csharp/service/src/csharpdiagram.cpp +++ b/plugins/csharp/service/src/csharpdiagram.cpp @@ -49,10 +49,23 @@ std::string graphHtmlTag( void removeAccessibilityTags(std::string& str){ std::vector accessibilityTags = {"protected internal", "private protected", "public", "private", "protected", "internal"}; + + std::stringstream ss(str), result; + std::string line; + + while(std::getline(ss, line)){ + + if (line.find('[') != 0) { + result << line << '\n'; + } + } + + str = result.str(); + boost::trim(str); for (auto const& tag : accessibilityTags){ if (str.find(tag) != std::string::npos) { - str.erase(str.find(tag),str.find(tag) + tag.length() + 1); + str.erase(str.find(tag), tag.length() + 1); } } }