-
Notifications
You must be signed in to change notification settings - Fork 1
/
ObjectAnalyser.cpp
103 lines (93 loc) · 4.49 KB
/
ObjectAnalyser.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#include <string>
#include <utility>
#include <vector>
#include "header/ObjectAnalyser.h"
#include "header/OutputHandler.h"
#include "header/HelperFunctions.h"
#include "header/CodeMatcher.h"
using namespace objectanalysis;
namespace objectanalysis{
class ObjectAnalyser{
std::vector<ObjectInstance> oldObjects;
std::vector<ObjectInstance> newObjects;
OutputHandler* outputHandler;
int findObject(const std::vector<ObjectInstance>& set, const ObjectInstance& objectInstance){
// prioritylist (name has to be the same): qualifiedName > filename > closest match on location
std::map<int, ObjectInstance> possibleMatches;
for(int i=0;i<set.size();i++){
if(set.at(i).qualifiedName == objectInstance.qualifiedName && set.at(i).qualifiedName != "" && set.at(i).qualifiedName != "(anonymous)"){
//return i;
}
// qualifiedName is included, because anonymous objects dont have a name, but a qualifiedName
if(set.at(i).name == objectInstance.name || set.at(i).qualifiedName == objectInstance.qualifiedName){
possibleMatches.insert(std::make_pair(i, set.at(i)));
}
}
for(const auto& possibleMatch: possibleMatches){
// return the first match with the same filename
if(possibleMatch.second.filename == objectInstance.filename){
return possibleMatch.first;
}
}
/*
// TODO: introduce a threshold at which the location is considered to be too far away and then maybe omit the file check
// if there isn't even a match with the same filename, return the object with the closest matching location
int smallestDiff = std::numeric_limits<int>::max();
int candidate = -1;
for (const auto &item: possibleMatches){
auto matrix = matcher::levenshteinDistance(item.second.location, objectInstance.location);
if(smallestDiff > matrix[item.second.location.size()][objectInstance.location.size()]){
smallestDiff = matrix[item.second.location.size()][objectInstance.location.size()];
candidate = item.first;
}
}
*/
//return candidate;
return -1;
}
public:
ObjectAnalyser(const std::vector<ObjectInstance>& oldObjects, const std::vector<ObjectInstance>& newObjects, OutputHandler* outputHandler){
this->oldObjects = oldObjects;
this->newObjects = newObjects;
this->outputHandler = outputHandler;
}
void compareObjects(){
for (const auto &item: oldObjects){
outputHandler->initialiseObjectInstance(item);
auto indexInNew = findObject(newObjects, item);
if(indexInNew != -1){
ObjectInstance newItem = newObjects.at(indexInNew);
compareFilename(item, newItem);
compareLocation(item, newItem);
compareType(item, newItem);
if(item.isFinal != newItem.isFinal){
outputHandler->outputObjectFinalChange(item, newItem);
}
if(item.isAbstract != newItem.isAbstract){
outputHandler->outputObjectAbstractChange(item, newItem);
}
newObjects.erase(newObjects.begin() + indexInNew);
}else{
outputHandler->outputObjectDeleted(item);
}
outputHandler->endOfCurrentObject();
}
}
private:
void compareFilename(const ObjectInstance& oldObj, const ObjectInstance& newObj){
if(oldObj.filename != newObj.filename){
outputHandler->outputObjectFilenameChange(oldObj, newObj);
}
}
void compareLocation(const ObjectInstance& oldObj, const ObjectInstance& newObj){
if(helper::getAllNamespacesAsString(oldObj.location) != helper::getAllNamespacesAsString(newObj.location)){
outputHandler->outputObjectLocationChange(oldObj, newObj);
}
}
void compareType(const ObjectInstance& oldObj, const ObjectInstance& newObj){
if(oldObj.objectType != newObj.objectType){
outputHandler->outputObjectTypeChange(oldObj, newObj);
}
}
};
}