Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added calculation for relational cohesion metric #747

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Build project
on: [push, pull_request, workflow_dispatch]

env:
BUILD_TYPE: Debug
BUILD_TYPE: RelWithDebInfo
## For locally compiled dependencies
INSTALL_PATH: ${{github.workspace}}/dependencies/install
## Temp directory for installers of the downloaded dependencies
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
analyze-cpp:
name: Analyze C-C++
env:
BUILD_TYPE: Debug
BUILD_TYPE: RelWithDebInfo
INSTALL_PATH: ${{github.workspace}}/dependencies/install
DOWNLOAD_PATH: ${{github.workspace}}/dependencies/download
runs-on: ubuntu-22.04
Expand Down
2 changes: 1 addition & 1 deletion .gitlab/build-codecompass.sh
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ cd $CC_BUILD_DIR
cmake $CC_SRC_DIR \
-DCMAKE_INSTALL_PREFIX=$CC_INSTALL_DIR \
-DDATABASE=pgsql \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_BUILD_TYPE=Release \
-DWITH_AUTH="plain;ldap" \
-DLLVM_DIR=$DEPS_INSTALL_RUNTIME_DIR/llvm/lib/cmake/llvm/ \
-DClang_DIR=$DEPS_INSTALL_RUNTIME_DIR/llvm/lib/cmake/clang/
Expand Down
8 changes: 4 additions & 4 deletions .gitlab/build-deps.sh
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,12 @@ rm -f $PACKAGES_DIR/release-1.10.0.tar.gz
#######

cd $PACKAGES_DIR
wget --no-verbose --no-clobber https://nodejs.org/dist/v16.20.2/node-v16.20.2-linux-x64.tar.xz
tar -xf node-v16.20.2-linux-x64.tar.xz -C $DEPS_INSTALL_RUNTIME_DIR
rm -f node-v16.20.2-linux-x64.tar.xz
wget --no-verbose --no-clobber https://nodejs.org/dist/v18.20.2/node-v18.20.2-linux-x64.tar.xz
tar -xf node-v18.20.2-linux-x64.tar.xz -C $DEPS_INSTALL_RUNTIME_DIR
rm -f node-v18.20.2-linux-x64.tar.xz

cd $DEPS_INSTALL_RUNTIME_DIR
mv node-v16.20.2-linux-x64 node-install
mv node-v18.20.2-linux-x64 node-install
export PATH=$DEPS_INSTALL_RUNTIME_DIR/node-install/bin:$PATH

############
Expand Down
79 changes: 8 additions & 71 deletions .gitlab/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,65 +61,16 @@ variables:
echo "GLIBC version: $GLIBC_VERSION"
echo "GLIBCXX versions: $GLIBCXX_VERSIONS"

tarball suse-15:
tarball ubuntu-20.04:
extends: .tarball
image: opensuse/leap:15
image: ubuntu:20.04
cache:
key: "leap"
key: "focal"
variables:
GCC_VERSION: 9.3.0
ODB_VERSION: 2.5.0
before_script:
- zypper refresh
- zypper update -y
# download tools
- zypper install -y curl wget gzip bzip2 unzip ca-certificates
# build tools for CodeCompass
- zypper install -y -t pattern devel_basis
- zypper install -y binutils gcc-c++ gmp-devel
# build tools for OpenLDAP
- zypper install -y groff
# build tools for ccdb-tools
- zypper install -y libffi-devel
# show GLIBC verison
- *show-glibc-version

# Permanently disabled job
# (Distribution package repository metadata not available anymore.)
.tarball suse-42.1:
extends: .tarball
image: opensuse/archive:42.1
cache:
key: "malachite"
variables:
GCC_VERSION: 5.5.0
ODB_VERSION: 2.4.0
before_script:
- zypper refresh
- zypper update -y
# download tools
- zypper install -y curl wget gzip bzip2 unzip ca-certificates
# build tools for CodeCompass
- zypper install -y -t pattern devel_basis
- zypper install -y binutils gcc-c++ gmp-devel
# build tools for OpenLDAP
- zypper install -y groff
# build tools for ccdb-tools
- zypper install -y libffi-devel
# disable SSL certificate check (distribution's cacert is outdated)
- echo "check_certificate = off" >> /etc/wgetrc
- echo insecure >> ~/.curlrc
# show GLIBC verison
- *show-glibc-version

tarball ubuntu-16.04:
extends: .tarball
image: ubuntu:16.04
cache:
key: "xenial"
variables:
GCC_VERSION: 5.5.0
ODB_VERSION: 2.4.0
# No interactive timezone dialog for tzdata
DEBIAN_FRONTEND: noninteractive
before_script:
- apt-get update -yqq
# download tools
Expand Down Expand Up @@ -154,22 +105,8 @@ tarball ubuntu-16.04:
- scp -P22 build/codecompass.tar.gz [email protected]:/var/www/codecompass/$FILENAME
- ssh -p22 [email protected] "mv -f /var/www/codecompass/$FILENAME /var/www/codecompass/live/wwwroot/tarball/$FILENAME"

upload suse-15:
extends: .upload
variables:
ARCH_SUFFIX: suse-15
needs: ["tarball suse-15"]

# Permanently disabled job
# (Distribution package repository metadata not available anymore.)
.upload suse-42.1:
extends: .upload
variables:
ARCH_SUFFIX: suse-42.1
needs: ["tarball suse-42.1"]

upload ubuntu-16.04:
upload ubuntu-20.04:
extends: .upload
variables:
ARCH_SUFFIX: ubuntu-16.04
needs: ["tarball ubuntu-16.04"]
ARCH_SUFFIX: ubuntu-20.04
needs: ["tarball ubuntu-20.04"]
5 changes: 3 additions & 2 deletions parser/src/sourcemanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <util/hash.h>
#include <util/logutil.h>
#include <util/dbutil.h>

#include <parser/sourcemanager.h>

Expand Down Expand Up @@ -238,9 +239,9 @@ void SourceManager::removeFile(const model::File& file_)
_transaction([&]() {
if(file_.content)
{
auto relFiles = _db->query<model::File>(
odb::result<model::File> relFiles = _db->query<model::File>(
odb::query<model::File>::content == file_.content.object_id());
if (relFiles.size() == 1)
if (util::isSingleResult(relFiles))
{
removeContent = true;
_db->erase<model::FileContent>(file_.content.object_id());
Expand Down
4 changes: 4 additions & 0 deletions plugins/cpp/parser/src/cppparser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,10 @@ bool CppParser::parseByJson(
LOG(warning)
<< '(' << job_.index << '/' << numCompileCommands << ')'
<< " Parsing " << command.Filename << " has been failed.";
else
LOG(debug)
<< '(' << job_.index << '/' << numCompileCommands << ')'
<< " Parsing " << command.Filename << " finished successfully.";
});

//--- Push all commands into the thread pool's queue ---//
Expand Down
5 changes: 3 additions & 2 deletions plugins/cpp_metrics/model/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@ include_directories(
set(ODB_SOURCES
include/model/cppastnodemetrics.h
include/model/cppcohesionmetrics.h
include/model/cppfilemetrics.h)
include/model/cppfilemetrics.h
include/model/cpprelationalcohesion.h)

generate_odb_files("${ODB_SOURCES}" "cpp")

add_odb_library(cppmetricsmodel ${ODB_CXX_SOURCES})
target_link_libraries(cppmetricsmodel cppmodel)

install_sql()
install_sql()
13 changes: 13 additions & 0 deletions plugins/cpp_metrics/model/include/model/cppastnodemetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ struct CppRecordMetricsView
double value;
};

#pragma db view \
object(CppAstNodeMetrics) \
object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \
object(File : CppAstNode::location.file)
struct CppAstNodeMetricsFileView
{
#pragma db column(CppAstNode::id)
CppAstNodeId astNodeId;

#pragma db column(File::id)
FileId fileId;
};

#pragma db view \
object(CppAstNodeMetrics) \
object(CppAstNode : CppAstNodeMetrics::astNodeId == CppAstNode::id) \
Expand Down
4 changes: 2 additions & 2 deletions plugins/cpp_metrics/model/include/model/cppfilemetrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ struct CppFileMetrics
{
enum Type
{
PLACEHOLDER
RELATIONAL_COHESION = 1
};

#pragma db id auto
Expand All @@ -26,7 +26,7 @@ struct CppFileMetrics
Type type;

#pragma db not_null
unsigned value;
double value;
};

#pragma db view \
Expand Down
116 changes: 116 additions & 0 deletions plugins/cpp_metrics/model/include/model/cpprelationalcohesion.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
#ifndef CC_MODEL_CPPRELATIONALCOHESION_H
#define CC_MODEL_CPPRELATIONALCOHESION_H

#include <model/cppentity.h>
#include <model/cpprecord.h>
#include <model/cppastnode.h>
#include <model/cppfunction.h>
#include <model/cppvariable.h>

namespace cc
{
namespace model
{

#pragma db view \
object(File)
struct RelationalCohesionFileView
{
#pragma db column(File::path)
std::string filePath;

#pragma db column(File::type)
std::string fileType;

#pragma db column(File::id)
std::size_t fileId;

};

#pragma db view \
object(CppRecord) \
object(CppAstNode : CppRecord::astNodeId == CppAstNode::id) \
object(File : CppAstNode::location.file) \
object(CppMemberType : CppMemberType::memberAstNode)
struct RelationalCohesionRecordView
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the same view is used in #757. In this case a more generic name should be used and code duplication should be avoided.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A common view could probably be used however the same applies to "CohesionCppRecordView" for example ("RelationalCohesionRecordView" contains this + typeHash).

Maybe this should be looked at separately to unify the commonly used views?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You started working concurrently on a second issue before finishing this one. I don't advise to merge in duplicated code segments so close to each other in time, and then refactor them in a follow-up issue.

{
#pragma db column(CppEntity::entityHash)
std::size_t entityHash;

#pragma db column(CppMemberType::typeHash)
std::size_t typeHash;

#pragma db column(CppEntity::qualifiedName)
std::string qualifiedName;

#pragma db column(CppEntity::astNodeId)
CppAstNodeId astNodeId;

#pragma db column(File::path)
std::string filePath;
};

#pragma db view \
object(CppFunction) \
object(CppAstNode : CppFunction::astNodeId == CppAstNode::id) \
object(File : CppAstNode::location.file)
struct RelationalCohesionFunctionView
{
#pragma db column(CppEntity::entityHash)
std::size_t entityHash;

#pragma db column(CppTypedEntity::typeHash)
std::size_t typeHash;

#pragma db column(File::path)
std::string filePath;
};


#pragma db view \
object(CppFunction) \
object(CppVariable = Parameters : CppFunction::parameters) \
object(CppAstNode : CppAstNode::id == CppFunction::astNodeId) \
object(File : CppAstNode::location.file)
struct RelationalCohessionFunctionParameterView
{
#pragma db column(Parameters::typeHash)
std::size_t typeHash;

#pragma db column(File::path)
std::string filePath;
};


#pragma db view \
object(CppFunction) \
object(CppVariable = Locals : CppFunction::locals) \
object(CppAstNode : CppAstNode::id == CppFunction::astNodeId) \
object(File : CppAstNode::location.file)
struct RelationalCohessionFunctionLocalView
{
#pragma db column(Locals::typeHash)
std::size_t typeHash;

#pragma db column(File::path)
std::string filePath;
};

#pragma db view \
object(CppVariable) \
object(CppAstNode : CppAstNode::id == CppEntity::astNodeId) \
object(File : CppAstNode::location.file)
struct RelationalCohesionVariableView
{
#pragma db column(CppVariable::typeHash)
std::size_t typeHash;

#pragma db column(File::path)
std::string filePath;

};

}
}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,21 @@ class CppMetricsParser : public AbstractParser
// Calculate the lack of cohesion between member variables
// and member functions for every type.
void lackOfCohesion();
// Calculate the cohesion within modules
void relationalCohesion();
// Check type relations in template parameter view.
// Used in relational cohesion metric.
template <typename T>
void checkTypes(
const std::string& path,
const std::unordered_set<std::uint64_t>& typesFound,
const std::unordered_map<std::uint64_t,std::string>& typeDefinitionPaths,
std::unordered_multimap<std::string, std::uint64_t>& relationsFoundInFile,
int& relationsInModule
);

std::vector<std::string> _inputPaths;
std::string _modulesPath;
std::unordered_set<model::FileId> _fileIdCache;
std::unordered_map<model::CppAstNodeId, model::FileId> _astNodeIdCache;
std::unique_ptr<util::JobQueueThreadPool<std::string>> _pool;
Expand Down
Loading
Loading