Skip to content

Commit 049cb5e

Browse files
authored
Merge pull request Ericsson#802 from barnabasdomozi/rework_cpptypedependency
Rework type level metrics calculations
2 parents d622a9c + 62a9314 commit 049cb5e

File tree

11 files changed

+471
-253
lines changed

11 files changed

+471
-253
lines changed

plugins/cpp/model/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ set(ODB_SOURCES
1515
include/model/cppmacro.h
1616
include/model/cppmacroexpansion.h
1717
include/model/cppedge.h
18-
include/model/cppdoccomment.h)
18+
include/model/cppdoccomment.h
19+
include/model/cpptypedependency.h)
1920

2021
generate_odb_files("${ODB_SOURCES}")
2122

plugins/cpp/model/include/model/cppfunction.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#ifndef CC_MODEL_CPPFUNCTION_H
22
#define CC_MODEL_CPPFUNCTION_H
33

4+
#include <cstdint>
45
#include <vector>
56

67
#include "cppentity.h"
@@ -23,6 +24,10 @@ struct CppFunction : CppTypedEntity
2324
unsigned int bumpiness;
2425
unsigned int statementCount;
2526

27+
// Hash of the record (e.g. class or struct) in which this function is declared
28+
// recordHash = 0 means this is a global function
29+
std::uint64_t recordHash = 0;
30+
2631
std::string toString() const
2732
{
2833
return std::string("CppFunction")
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
#ifndef CC_MODEL_CPPTYPEDEPENDENCY_H
2+
#define CC_MODEL_CPPTYPEDEPENDENCY_H
3+
4+
#include <cstdint>
5+
#include <string>
6+
#include <model/cppentity.h>
7+
#include <model/cpprecord.h>
8+
#include <model/cppastnode.h>
9+
#include <model/file.h>
10+
11+
namespace cc
12+
{
13+
namespace model
14+
{
15+
16+
#pragma db object
17+
struct CppTypeDependency
18+
{
19+
#pragma db id auto
20+
std::uint64_t id;
21+
22+
#pragma db not_null
23+
std::uint64_t entityHash;
24+
25+
#pragma db not_null
26+
std::uint64_t dependencyHash;
27+
28+
std::string toString() const
29+
{
30+
return std::string("CppTypeDependency")
31+
.append("\nid = ").append(std::to_string(id))
32+
.append("\nentityHash = ").append(std::to_string(entityHash))
33+
.append("\ndependencyHash = ").append(std::to_string(dependencyHash));
34+
}
35+
36+
#pragma db index member(entityHash)
37+
#pragma db index member(dependencyHash)
38+
};
39+
40+
typedef std::shared_ptr<CppTypeDependency> CppTypeDependencyPtr;
41+
42+
#pragma db view \
43+
object(CppTypeDependency) \
44+
object(CppAstNode = EntityAstNode : CppTypeDependency::entityHash == EntityAstNode::entityHash \
45+
&& EntityAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
46+
object(File = EntityFile : EntityAstNode::location.file == EntityFile::id) \
47+
object(CppAstNode = DependencyAstNode : CppTypeDependency::dependencyHash == DependencyAstNode::entityHash \
48+
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
49+
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
50+
struct CppTypeDependencyPathView
51+
{
52+
#pragma db column(CppTypeDependency::entityHash)
53+
std::size_t entityHash;
54+
55+
#pragma db column(CppTypeDependency::dependencyHash)
56+
std::size_t dependencyHash;
57+
58+
#pragma db column(EntityFile::path)
59+
std::string entityPath;
60+
61+
#pragma db column(DependencyFile::path)
62+
std::string dependencyPath;
63+
};
64+
65+
#pragma db view \
66+
object(CppTypeDependency) \
67+
object(CppAstNode = EntityAstNode : CppTypeDependency::entityHash == EntityAstNode::entityHash \
68+
&& EntityAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
69+
object(File = EntityFile : EntityAstNode::location.file == EntityFile::id) \
70+
object(CppAstNode = DependencyAstNode : CppTypeDependency::dependencyHash == DependencyAstNode::entityHash \
71+
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
72+
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
73+
struct CppTypeDependency_Count
74+
{
75+
#pragma db column("count(" + CppTypeDependency::id + ")")
76+
std::size_t count;
77+
};
78+
79+
#pragma db view \
80+
object(CppTypeDependency) \
81+
object(CppAstNode = EntityAstNode : CppTypeDependency::entityHash == EntityAstNode::entityHash \
82+
&& EntityAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
83+
object(File = EntityFile : EntityAstNode::location.file == EntityFile::id) \
84+
object(CppAstNode = DependencyAstNode : CppTypeDependency::dependencyHash == DependencyAstNode::entityHash \
85+
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
86+
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
87+
struct CppTypeDependency_Distinct_D_Count
88+
{
89+
#pragma db column("count(distinct" + CppTypeDependency::dependencyHash + ")")
90+
std::size_t count;
91+
};
92+
93+
#pragma db view \
94+
object(CppTypeDependency) \
95+
object(CppAstNode = EntityAstNode : CppTypeDependency::entityHash == EntityAstNode::entityHash \
96+
&& EntityAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
97+
object(File = EntityFile : EntityAstNode::location.file == EntityFile::id) \
98+
object(CppAstNode = DependencyAstNode : CppTypeDependency::dependencyHash == DependencyAstNode::entityHash \
99+
&& DependencyAstNode::astType == cc::model::CppAstNode::AstType::Definition) \
100+
object(File = DependencyFile : DependencyAstNode::location.file == DependencyFile::id)
101+
struct CppTypeDependency_Distinct_E_Count
102+
{
103+
#pragma db column("count(distinct" + CppTypeDependency::entityHash + ")")
104+
std::size_t count;
105+
};
106+
107+
#pragma db view \
108+
object(CppTypeDependency)
109+
struct CppTypeDependency_Efferent_Count
110+
{
111+
#pragma db column("count(distinct" + CppTypeDependency::dependencyHash + ")")
112+
std::size_t count;
113+
};
114+
115+
#pragma db view \
116+
object(CppTypeDependency)
117+
struct CppTypeDependency_Afferent_Count
118+
{
119+
#pragma db column("count(distinct" + CppTypeDependency::entityHash + ")")
120+
std::size_t count;
121+
};
122+
123+
} // model
124+
} // cc
125+
126+
#endif // CC_MODEL_CPPTYPEDEPENDENCY_H

plugins/cpp/parser/src/clangastvisitor.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@
3434
#include <model/cpprecord-odb.hxx>
3535
#include <model/cpptypedef.h>
3636
#include <model/cpptypedef-odb.hxx>
37+
#include <model/cpptypedependency.h>
38+
#include <model/cpptypedependency-odb.hxx>
3739

3840
#include <parser/parsercontext.h>
3941
#include <parser/sourcemanager.h>
@@ -129,6 +131,7 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
129131
util::persistAll(_friends, _ctx.db);
130132
util::persistAll(_functions, _ctx.db);
131133
util::persistAll(_relations, _ctx.db);
134+
util::persistAll(_typeDependencies, _ctx.db);
132135
});
133136
}
134137

@@ -571,6 +574,27 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
571574

572575
_locToTypeLoc[tl_.getBeginLoc().getRawEncoding()] = astNode;
573576

577+
//--- CppTypeDependency ---//
578+
std::uint64_t typeHash = 0;
579+
if (!_typeStack.empty())
580+
{
581+
typeHash = _typeStack.top()->entityHash;
582+
}
583+
584+
if (typeHash == 0 && !_functionStack.empty())
585+
{
586+
typeHash = _functionStack.top()->recordHash;
587+
}
588+
589+
if (typeHash != 0 && typeHash != astNode->entityHash)
590+
{
591+
model::CppTypeDependencyPtr td = std::make_shared<model::CppTypeDependency>();
592+
_typeDependencies.push_back(td);
593+
594+
td->entityHash = typeHash;
595+
td->dependencyHash = astNode->entityHash;
596+
}
597+
574598
return true;
575599
}
576600

@@ -913,6 +937,11 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
913937
clang::CXXMethodDecl* md = llvm::dyn_cast<clang::CXXMethodDecl>(fn_);
914938
if (md)
915939
{
940+
if (const clang::CXXRecordDecl* parent = md->getParent())
941+
{
942+
cppFunction->recordHash = util::fnvHash(getUSR(parent));
943+
}
944+
916945
if (md->isVirtual())
917946
cppFunction->tags.insert(model::Tag::Virtual);
918947

@@ -1837,6 +1866,7 @@ class ClangASTVisitor : public clang::RecursiveASTVisitor<ClangASTVisitor>
18371866
std::vector<model::CppInheritancePtr> _inheritances;
18381867
std::vector<model::CppFriendshipPtr> _friends;
18391868
std::vector<model::CppRelationPtr> _relations;
1869+
std::vector<model::CppTypeDependencyPtr> _typeDependencies;
18401870

18411871
// TODO: Maybe we don't even need a stack, if functions can't be nested.
18421872
// Check lambda.

plugins/cpp_metrics/model/CMakeLists.txt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ include_directories(
55
set(ODB_SOURCES
66
include/model/cppastnodemetrics.h
77
include/model/cppcohesionmetrics.h
8-
include/model/cppfilemetrics.h
9-
include/model/cpptypedependencymetrics.h)
8+
include/model/cppfilemetrics.h)
109

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

plugins/cpp_metrics/model/include/model/cpptypedependencymetrics.h

Lines changed: 0 additions & 100 deletions
This file was deleted.

0 commit comments

Comments
 (0)