src: Refactored TokenLocation classes to SourceLocation classes
* Removed TokenLocationLine * decoupled TokenLocationFile from TokenLocationCollection * save vector of Token ids to SourceLocation * refactored SourceLocationFile::getFilteredByLines() * refactored snippet creation
This commit is contained in:
@@ -0,0 +1,205 @@
|
||||
#include "data/location/SourceLocation.h"
|
||||
|
||||
#include "data/location/SourceLocationFile.h"
|
||||
|
||||
SourceLocation::SourceLocation(
|
||||
SourceLocationFile* file,
|
||||
LocationType type,
|
||||
Id locationId,
|
||||
std::vector<Id> tokenIds,
|
||||
size_t lineNumber,
|
||||
size_t columnNumber,
|
||||
bool isStart
|
||||
)
|
||||
: m_file(file)
|
||||
, m_type(type)
|
||||
, m_locationId(locationId)
|
||||
, m_tokenIds(tokenIds)
|
||||
, m_lineNumber(lineNumber)
|
||||
, m_columnNumber(columnNumber)
|
||||
, m_other(nullptr)
|
||||
, m_isStart(isStart)
|
||||
{
|
||||
}
|
||||
|
||||
SourceLocation::SourceLocation(SourceLocation* other, size_t lineNumber, size_t columnNumber)
|
||||
: m_file(other->m_file)
|
||||
, m_type(other->m_type)
|
||||
, m_locationId(other->m_locationId)
|
||||
, m_tokenIds(other->m_tokenIds)
|
||||
, m_lineNumber(lineNumber)
|
||||
, m_columnNumber(columnNumber)
|
||||
, m_other(other)
|
||||
, m_isStart(!other->m_isStart)
|
||||
{
|
||||
other->setOtherLocation(this);
|
||||
}
|
||||
|
||||
SourceLocation::SourceLocation(const SourceLocation* other, SourceLocationFile* file)
|
||||
: m_file(file)
|
||||
, m_type(other->m_type)
|
||||
, m_locationId(other->m_locationId)
|
||||
, m_tokenIds(other->m_tokenIds)
|
||||
, m_lineNumber(other->m_lineNumber)
|
||||
, m_columnNumber(other->m_columnNumber)
|
||||
, m_other(nullptr)
|
||||
, m_isStart(other->m_isStart)
|
||||
{
|
||||
}
|
||||
|
||||
SourceLocation::~SourceLocation()
|
||||
{
|
||||
}
|
||||
|
||||
bool SourceLocation::operator==(const SourceLocation& rhs) const
|
||||
{
|
||||
return (
|
||||
getLineNumber() == rhs.getLineNumber() &&
|
||||
getColumnNumber() == rhs.getColumnNumber() &&
|
||||
getLocationId() == rhs.getLocationId() &&
|
||||
getType() == rhs.getType()
|
||||
);
|
||||
}
|
||||
|
||||
bool SourceLocation::operator<(const SourceLocation& rhs) const
|
||||
{
|
||||
if (getLineNumber() != rhs.getLineNumber())
|
||||
{
|
||||
return getLineNumber() < rhs.getLineNumber();
|
||||
}
|
||||
|
||||
if (getColumnNumber() != rhs.getColumnNumber())
|
||||
{
|
||||
return getColumnNumber() < rhs.getColumnNumber();
|
||||
}
|
||||
|
||||
return getLocationId() < rhs.getLocationId();
|
||||
}
|
||||
|
||||
bool SourceLocation::operator>(const SourceLocation& rhs) const
|
||||
{
|
||||
if (getLineNumber() != rhs.getLineNumber())
|
||||
{
|
||||
return getLineNumber() > rhs.getLineNumber();
|
||||
}
|
||||
|
||||
if (getColumnNumber() != rhs.getColumnNumber())
|
||||
{
|
||||
return getColumnNumber() > rhs.getColumnNumber();
|
||||
}
|
||||
|
||||
return getLocationId() > rhs.getLocationId();
|
||||
}
|
||||
|
||||
SourceLocationFile* SourceLocation::getSourceLocationFile() const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
Id SourceLocation::getLocationId() const
|
||||
{
|
||||
return m_locationId;
|
||||
}
|
||||
|
||||
const std::vector<Id>& SourceLocation::getTokenIds() const
|
||||
{
|
||||
return m_tokenIds;
|
||||
}
|
||||
|
||||
LocationType SourceLocation::getType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
size_t SourceLocation::getColumnNumber() const
|
||||
{
|
||||
return m_columnNumber;
|
||||
}
|
||||
|
||||
size_t SourceLocation::getLineNumber() const
|
||||
{
|
||||
return m_lineNumber;
|
||||
}
|
||||
|
||||
const FilePath& SourceLocation::getFilePath() const
|
||||
{
|
||||
return m_file->getFilePath();
|
||||
}
|
||||
|
||||
const SourceLocation* SourceLocation::getOtherLocation() const
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
|
||||
void SourceLocation::setOtherLocation(SourceLocation* other)
|
||||
{
|
||||
m_other = other;
|
||||
}
|
||||
|
||||
const SourceLocation* SourceLocation::getStartLocation() const
|
||||
{
|
||||
if (m_isStart)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
}
|
||||
|
||||
const SourceLocation* SourceLocation::getEndLocation() const
|
||||
{
|
||||
if (!m_isStart)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
}
|
||||
|
||||
bool SourceLocation::isStartLocation() const
|
||||
{
|
||||
return m_isStart;
|
||||
}
|
||||
|
||||
bool SourceLocation::isEndLocation() const
|
||||
{
|
||||
return !m_isStart;
|
||||
}
|
||||
|
||||
bool SourceLocation::isScopeLocation() const
|
||||
{
|
||||
return m_type == LOCATION_SCOPE;
|
||||
}
|
||||
|
||||
bool SourceLocation::isFullTextSearchMatch() const
|
||||
{
|
||||
return m_type == LOCATION_FULLTEXT;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocation& location)
|
||||
{
|
||||
if (location.isStartLocation())
|
||||
{
|
||||
ostream << '<';
|
||||
}
|
||||
|
||||
ostream << location.getColumnNumber() << ":[ ";
|
||||
for (Id tokenId : location.getTokenIds())
|
||||
{
|
||||
ostream << '\b' << tokenId << ' ';
|
||||
}
|
||||
|
||||
ostream << "\b]";
|
||||
|
||||
if (location.isEndLocation())
|
||||
{
|
||||
ostream << '>';
|
||||
}
|
||||
|
||||
ostream << ' ';
|
||||
return ostream;
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#ifndef SOURCE_LOCATION_H
|
||||
#define SOURCE_LOCATION_H
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "data/location/LocationType.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class FilePath;
|
||||
class SourceLocationFile;
|
||||
|
||||
class SourceLocation
|
||||
{
|
||||
public:
|
||||
SourceLocation(SourceLocationFile* file, LocationType type, Id locationId, std::vector<Id> tokenIds,
|
||||
size_t lineNumber, size_t columnNumber, bool isStart);
|
||||
SourceLocation(SourceLocation* other, size_t lineNumber, size_t columnNumber);
|
||||
SourceLocation(const SourceLocation* other, SourceLocationFile* file);
|
||||
virtual ~SourceLocation();
|
||||
|
||||
bool operator==(const SourceLocation& rhs) const;
|
||||
bool operator<(const SourceLocation& rhs) const;
|
||||
bool operator>(const SourceLocation& rhs) const;
|
||||
|
||||
SourceLocationFile* getSourceLocationFile() const;
|
||||
|
||||
Id getLocationId() const;
|
||||
const std::vector<Id>& getTokenIds() const;
|
||||
LocationType getType() const;
|
||||
|
||||
size_t getColumnNumber() const;
|
||||
size_t getLineNumber() const;
|
||||
const FilePath& getFilePath() const;
|
||||
|
||||
const SourceLocation* getOtherLocation() const;
|
||||
void setOtherLocation(SourceLocation* other);
|
||||
|
||||
const SourceLocation* getStartLocation() const;
|
||||
const SourceLocation* getEndLocation() const;
|
||||
|
||||
bool isStartLocation() const;
|
||||
bool isEndLocation() const;
|
||||
|
||||
bool isScopeLocation() const;
|
||||
bool isFullTextSearchMatch() const;
|
||||
|
||||
private:
|
||||
SourceLocationFile* m_file;
|
||||
|
||||
LocationType m_type;
|
||||
|
||||
const Id m_locationId;
|
||||
const std::vector<Id> m_tokenIds;
|
||||
|
||||
const size_t m_lineNumber;
|
||||
const size_t m_columnNumber;
|
||||
|
||||
SourceLocation* m_other;
|
||||
const bool m_isStart;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocation& location);
|
||||
|
||||
#endif // SOURCE_LOCATION_H
|
||||
@@ -0,0 +1,129 @@
|
||||
#include "data/location/SourceLocationCollection.h"
|
||||
|
||||
#include "data/location/SourceLocationFile.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
SourceLocationCollection::SourceLocationCollection()
|
||||
{
|
||||
}
|
||||
|
||||
SourceLocationCollection::~SourceLocationCollection()
|
||||
{
|
||||
}
|
||||
|
||||
const std::map<FilePath, std::shared_ptr<SourceLocationFile>>& SourceLocationCollection::getSourceLocationFiles() const
|
||||
{
|
||||
return m_files;
|
||||
}
|
||||
|
||||
size_t SourceLocationCollection::getSourceLocationCount() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (auto p : m_files)
|
||||
{
|
||||
count += p.second->getSourceLocationCount();
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t SourceLocationCollection::getSourceLocationFileCount() const
|
||||
{
|
||||
return m_files.size();
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceLocationFile> SourceLocationCollection::getSourceLocationFileByPath(const FilePath& filePath) const
|
||||
{
|
||||
std::map<FilePath, std::shared_ptr<SourceLocationFile>>::const_iterator it = m_files.find(filePath);
|
||||
if (it != m_files.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SourceLocation* SourceLocationCollection::getSourceLocationById(Id locationId) const
|
||||
{
|
||||
for (auto p : m_files)
|
||||
{
|
||||
SourceLocation* location = p.second->getSourceLocationById(locationId);
|
||||
if (location)
|
||||
{
|
||||
return location;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SourceLocation* SourceLocationCollection::addSourceLocation(
|
||||
LocationType type, Id locationId, std::vector<Id> tokenIds, const FilePath& filePath,
|
||||
size_t startLineNumber, size_t startColumnNumber,
|
||||
size_t endLineNumber, size_t endColumnNumber)
|
||||
{
|
||||
if (startLineNumber > endLineNumber || (startLineNumber == endLineNumber && startColumnNumber > endColumnNumber))
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "SourceLocation has wrong boundaries: " << filePath.str() << " "
|
||||
<< startLineNumber << ":" << startColumnNumber << " "
|
||||
<< endLineNumber << ":" << endColumnNumber);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SourceLocationFile* file = createSourceLocationFile(filePath);
|
||||
if (file->isWhole())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return file->addSourceLocation(type, locationId, tokenIds, startLineNumber, startColumnNumber, endLineNumber, endColumnNumber);
|
||||
}
|
||||
|
||||
SourceLocation* SourceLocationCollection::addSourceLocationCopy(SourceLocation* location)
|
||||
{
|
||||
return createSourceLocationFile(location->getFilePath())->addSourceLocationCopy(location);
|
||||
}
|
||||
|
||||
void SourceLocationCollection::addSourceLocationFile(std::shared_ptr<SourceLocationFile> file)
|
||||
{
|
||||
m_files.emplace(file->getFilePath(), file);
|
||||
}
|
||||
|
||||
void SourceLocationCollection::forEachSourceLocationFile(
|
||||
std::function<void(std::shared_ptr<SourceLocationFile>)> func) const
|
||||
{
|
||||
for (auto p : m_files)
|
||||
{
|
||||
func(p.second);
|
||||
}
|
||||
}
|
||||
|
||||
void SourceLocationCollection::forEachSourceLocation(std::function<void(SourceLocation*)> func) const
|
||||
{
|
||||
for (auto p : m_files)
|
||||
{
|
||||
p.second->forEachSourceLocation(func);
|
||||
}
|
||||
}
|
||||
|
||||
SourceLocationFile* SourceLocationCollection::createSourceLocationFile(const FilePath& filePath)
|
||||
{
|
||||
SourceLocationFile* file = getSourceLocationFileByPath(filePath).get();
|
||||
if (file)
|
||||
{
|
||||
return file;
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceLocationFile> filePtr = std::make_shared<SourceLocationFile>(filePath, false);
|
||||
m_files.emplace(filePath, filePtr);
|
||||
return filePtr.get();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocationCollection& base)
|
||||
{
|
||||
ostream << "Locations:\n";
|
||||
base.forEachSourceLocationFile([&ostream](std::shared_ptr<SourceLocationFile> f)
|
||||
{
|
||||
ostream << *(f.get());
|
||||
});
|
||||
return ostream;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
#ifndef SOURCE_LOCATION_COLLECTION_H
|
||||
#define SOURCE_LOCATION_COLLECTION_H
|
||||
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <vector>
|
||||
|
||||
#include "data/location/LocationType.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class FilePath;
|
||||
class SourceLocation;
|
||||
class SourceLocationFile;
|
||||
|
||||
class SourceLocationCollection
|
||||
{
|
||||
public:
|
||||
SourceLocationCollection();
|
||||
virtual ~SourceLocationCollection();
|
||||
|
||||
const std::map<FilePath, std::shared_ptr<SourceLocationFile>>& getSourceLocationFiles() const;
|
||||
|
||||
size_t getSourceLocationCount() const;
|
||||
size_t getSourceLocationFileCount() const;
|
||||
|
||||
std::shared_ptr<SourceLocationFile> getSourceLocationFileByPath(const FilePath& filePath) const;
|
||||
SourceLocation* getSourceLocationById(Id locationId) const;
|
||||
|
||||
SourceLocation* addSourceLocation(
|
||||
LocationType type, Id locationId, std::vector<Id> tokenIds, const FilePath& filePath,
|
||||
size_t startLineNumber, size_t startColumnNumber,
|
||||
size_t endLineNumber, size_t endColumnNumber);
|
||||
SourceLocation* addSourceLocationCopy(SourceLocation* location);
|
||||
|
||||
void addSourceLocationFile(std::shared_ptr<SourceLocationFile> file);
|
||||
|
||||
void forEachSourceLocationFile(std::function<void(std::shared_ptr<SourceLocationFile>)> func) const;
|
||||
void forEachSourceLocation(std::function<void(SourceLocation*)> func) const;
|
||||
|
||||
private:
|
||||
SourceLocationFile* createSourceLocationFile(const FilePath& filePath);
|
||||
|
||||
std::map<FilePath, std::shared_ptr<SourceLocationFile>> m_files;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocationCollection& base);
|
||||
|
||||
#endif // SOURCE_LOCATION_COLLECTION_H
|
||||
@@ -0,0 +1,215 @@
|
||||
#include "data/location/SourceLocationFile.h"
|
||||
|
||||
SourceLocationFile::SourceLocationFile(const FilePath& filePath, bool isWhole)
|
||||
: m_filePath(filePath)
|
||||
, m_isWhole(isWhole)
|
||||
{
|
||||
}
|
||||
|
||||
SourceLocationFile::~SourceLocationFile()
|
||||
{
|
||||
}
|
||||
|
||||
const FilePath& SourceLocationFile::getFilePath() const
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
void SourceLocationFile::setIsWhole(bool isWhole)
|
||||
{
|
||||
m_isWhole = isWhole;
|
||||
}
|
||||
|
||||
bool SourceLocationFile::isWhole() const
|
||||
{
|
||||
return m_isWhole;
|
||||
}
|
||||
|
||||
const std::multiset<std::shared_ptr<SourceLocation>, SourceLocationFile::LocationComp>& SourceLocationFile::getSourceLocations() const
|
||||
{
|
||||
return m_locations;
|
||||
}
|
||||
|
||||
size_t SourceLocationFile::getSourceLocationCount() const
|
||||
{
|
||||
return m_locationIndex.size();
|
||||
}
|
||||
|
||||
size_t SourceLocationFile::getUnscopedStartLocationCount() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (std::shared_ptr<SourceLocation> location : m_locations)
|
||||
{
|
||||
if (location->isStartLocation() && !location->isScopeLocation())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
SourceLocation* SourceLocationFile::addSourceLocation(
|
||||
LocationType type, Id locationId, std::vector<Id> tokenIds,
|
||||
size_t startLineNumber, size_t startColumnNumber,
|
||||
size_t endLineNumber, size_t endColumnNumber)
|
||||
{
|
||||
std::shared_ptr<SourceLocation> start =
|
||||
std::make_shared<SourceLocation>(this, type, locationId, tokenIds, startLineNumber, startColumnNumber, true);
|
||||
std::shared_ptr<SourceLocation> end = std::make_shared<SourceLocation>(start.get(), endLineNumber, endColumnNumber);
|
||||
|
||||
m_locations.insert(start);
|
||||
m_locations.insert(end);
|
||||
|
||||
m_locationIndex.emplace(start->getLocationId(), start.get());
|
||||
|
||||
return start.get();
|
||||
}
|
||||
|
||||
SourceLocation* SourceLocationFile::addSourceLocationCopy(const SourceLocation* location)
|
||||
{
|
||||
// Check whether this location was already added or if the other SourceLocation was added.
|
||||
SourceLocation* oldLocation = getSourceLocationById(location->getLocationId());
|
||||
if (oldLocation)
|
||||
{
|
||||
if (oldLocation->isStartLocation() == location->isStartLocation())
|
||||
{
|
||||
return oldLocation;
|
||||
}
|
||||
|
||||
const SourceLocation* otherOldLocation = oldLocation->getOtherLocation();
|
||||
if (otherOldLocation && otherOldLocation->isStartLocation() == location->isStartLocation())
|
||||
{
|
||||
return const_cast<SourceLocation*>(otherOldLocation);
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceLocation> copy = std::make_shared<SourceLocation>(location, this);
|
||||
m_locations.insert(copy);
|
||||
m_locationIndex.emplace(copy->getLocationId(), copy.get());
|
||||
|
||||
// If the old location was added before, then link them with each other.
|
||||
if (oldLocation)
|
||||
{
|
||||
oldLocation->setOtherLocation(copy.get());
|
||||
copy->setOtherLocation(oldLocation);
|
||||
}
|
||||
|
||||
return copy.get();
|
||||
}
|
||||
|
||||
SourceLocation* SourceLocationFile::getSourceLocationById(Id locationId) const
|
||||
{
|
||||
std::map<Id, SourceLocation*>::const_iterator it = m_locationIndex.find(locationId);
|
||||
|
||||
if (it != m_locationIndex.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SourceLocationFile::forEachSourceLocation(std::function<void(SourceLocation*)> func) const
|
||||
{
|
||||
for (std::shared_ptr<SourceLocation> location : m_locations)
|
||||
{
|
||||
func(location.get());
|
||||
}
|
||||
}
|
||||
|
||||
void SourceLocationFile::forEachStartSourceLocation(std::function<void(SourceLocation*)> func) const
|
||||
{
|
||||
for (std::shared_ptr<SourceLocation> location : m_locations)
|
||||
{
|
||||
if (location->isStartLocation())
|
||||
{
|
||||
func(location.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SourceLocationFile::forEachEndSourceLocation(std::function<void(SourceLocation*)> func) const
|
||||
{
|
||||
for (std::shared_ptr<SourceLocation> location : m_locations)
|
||||
{
|
||||
if (location->isEndLocation())
|
||||
{
|
||||
func(location.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceLocationFile> SourceLocationFile::getFilteredByLines(size_t firstLineNumber, size_t lastLineNumber) const
|
||||
{
|
||||
std::shared_ptr<SourceLocationFile> ret = std::make_shared<SourceLocationFile>(getFilePath(), false);
|
||||
|
||||
for (std::shared_ptr<SourceLocation> location : m_locations)
|
||||
{
|
||||
if (location->getLineNumber() >= firstLineNumber && location->getLineNumber() <= lastLineNumber)
|
||||
{
|
||||
ret->addSourceLocationCopy(location.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (isWhole() && ret->getSourceLocationCount() == getSourceLocationCount())
|
||||
{
|
||||
ret->setIsWhole(true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::shared_ptr<SourceLocationFile> SourceLocationFile::getFilteredByType(LocationType type) const
|
||||
{
|
||||
std::shared_ptr<SourceLocationFile> ret = std::make_shared<SourceLocationFile>(getFilePath(), false);
|
||||
|
||||
for (std::shared_ptr<SourceLocation> location : m_locations)
|
||||
{
|
||||
if (location->getType() == type)
|
||||
{
|
||||
ret->addSourceLocationCopy(location.get());
|
||||
}
|
||||
}
|
||||
|
||||
if (isWhole() && ret->getSourceLocationCount() == getSourceLocationCount())
|
||||
{
|
||||
ret->setIsWhole(true);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocationFile& file)
|
||||
{
|
||||
ostream << "file \"" << file.getFilePath().str() << "\"";
|
||||
|
||||
size_t line = 0;
|
||||
file.forEachSourceLocation(
|
||||
[&ostream, &line](SourceLocation* location)
|
||||
{
|
||||
if (location->getLineNumber() != line)
|
||||
{
|
||||
while (line < location->getLineNumber())
|
||||
{
|
||||
if (!line)
|
||||
{
|
||||
line = location->getLineNumber();
|
||||
}
|
||||
else
|
||||
{
|
||||
line++;
|
||||
}
|
||||
|
||||
ostream << '\n' << line;
|
||||
}
|
||||
|
||||
ostream << ": ";
|
||||
}
|
||||
|
||||
ostream << *location;
|
||||
}
|
||||
);
|
||||
|
||||
ostream << '\n';
|
||||
return ostream;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
#ifndef SOURCE_LOCATION_FILE_H
|
||||
#define SOURCE_LOCATION_FILE_H
|
||||
|
||||
#include <map>
|
||||
#include <ostream>
|
||||
#include <set>
|
||||
|
||||
#include "data/location/LocationType.h"
|
||||
#include "data/location/SourceLocation.h"
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class SourceLocationFile
|
||||
{
|
||||
public:
|
||||
struct LocationComp
|
||||
{
|
||||
bool operator()(const std::shared_ptr<SourceLocation>& lhs, const std::shared_ptr<SourceLocation>& rhs) const
|
||||
{
|
||||
return *(lhs.get()) < *(rhs.get());
|
||||
}
|
||||
};
|
||||
|
||||
SourceLocationFile(const FilePath& filePath, bool isWhole);
|
||||
virtual ~SourceLocationFile();
|
||||
|
||||
const FilePath& getFilePath() const;
|
||||
|
||||
void setIsWhole(bool isWhole);
|
||||
bool isWhole() const;
|
||||
|
||||
const std::multiset<std::shared_ptr<SourceLocation>, LocationComp>& getSourceLocations() const;
|
||||
|
||||
size_t getSourceLocationCount() const;
|
||||
size_t getUnscopedStartLocationCount() const;
|
||||
|
||||
SourceLocation* addSourceLocation(
|
||||
LocationType type, Id locationId, std::vector<Id> tokenIds,
|
||||
size_t startLineNumber, size_t startColumnNumber,
|
||||
size_t endLineNumber, size_t endColumnNumber);
|
||||
SourceLocation* addSourceLocationCopy(const SourceLocation* location);
|
||||
|
||||
SourceLocation* getSourceLocationById(Id locationId) const;
|
||||
|
||||
void forEachSourceLocation(std::function<void(SourceLocation*)> func) const;
|
||||
void forEachStartSourceLocation(std::function<void(SourceLocation*)> func) const;
|
||||
void forEachEndSourceLocation(std::function<void(SourceLocation*)> func) const;
|
||||
|
||||
std::shared_ptr<SourceLocationFile> getFilteredByLines(size_t firstLineNumber, size_t lastLineNumber) const;
|
||||
std::shared_ptr<SourceLocationFile> getFilteredByType(LocationType type) const;
|
||||
|
||||
private:
|
||||
const FilePath m_filePath;
|
||||
bool m_isWhole;
|
||||
|
||||
std::multiset<std::shared_ptr<SourceLocation>, LocationComp> m_locations;
|
||||
std::map<Id, SourceLocation*> m_locationIndex;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const SourceLocationFile& base);
|
||||
|
||||
#endif // SOURCE_LOCATION_FILE_H
|
||||
@@ -1,206 +0,0 @@
|
||||
#include "data/location/TokenLocation.h"
|
||||
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
|
||||
TokenLocation::TokenLocation(Id locationId, Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart)
|
||||
: m_id(locationId)
|
||||
, m_tokenId(tokenId)
|
||||
, m_type(LOCATION_TOKEN)
|
||||
, m_line(line)
|
||||
, m_columnNumber(columnNumber)
|
||||
, m_other(nullptr)
|
||||
, m_isStart(isStart)
|
||||
{
|
||||
}
|
||||
|
||||
TokenLocation::TokenLocation(TokenLocation *other, TokenLocationLine* line, unsigned int columnNumber, bool isStart)
|
||||
: m_id(other->m_id)
|
||||
, m_tokenId(other->m_tokenId)
|
||||
, m_type(other->m_type)
|
||||
, m_line(line)
|
||||
, m_columnNumber(columnNumber)
|
||||
, m_other(other)
|
||||
, m_isStart(isStart)
|
||||
{
|
||||
}
|
||||
|
||||
TokenLocation::TokenLocation(const TokenLocation& other, TokenLocationLine* line)
|
||||
: m_id(other.m_id)
|
||||
, m_tokenId(other.m_tokenId)
|
||||
, m_type(other.m_type)
|
||||
, m_line(line)
|
||||
, m_columnNumber(other.m_columnNumber)
|
||||
, m_other(nullptr)
|
||||
, m_isStart(other.m_isStart)
|
||||
{
|
||||
}
|
||||
|
||||
TokenLocation::~TokenLocation()
|
||||
{
|
||||
}
|
||||
|
||||
bool TokenLocation::operator<(const TokenLocation& rhs) const
|
||||
{
|
||||
return (
|
||||
getLineNumber() < rhs.getLineNumber() || (
|
||||
getLineNumber() == rhs.getLineNumber() &&
|
||||
getColumnNumber() < rhs.getColumnNumber()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
bool TokenLocation::operator>(const TokenLocation& rhs) const
|
||||
{
|
||||
return (
|
||||
getLineNumber() > rhs.getLineNumber() || (
|
||||
getLineNumber() == rhs.getLineNumber() &&
|
||||
getColumnNumber() > rhs.getColumnNumber()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
Id TokenLocation::getId() const
|
||||
{
|
||||
return m_id;
|
||||
}
|
||||
|
||||
Id TokenLocation::getTokenId() const
|
||||
{
|
||||
return m_tokenId;
|
||||
}
|
||||
|
||||
LocationType TokenLocation::getType() const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void TokenLocation::setType(LocationType type)
|
||||
{
|
||||
m_type = type;
|
||||
|
||||
if (m_other)
|
||||
{
|
||||
m_other->m_type = type;
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocationLine* TokenLocation::getTokenLocationLine() const
|
||||
{
|
||||
return m_line;
|
||||
}
|
||||
|
||||
TokenLocationFile* TokenLocation::getTokenLocationFile() const
|
||||
{
|
||||
return m_line->getTokenLocationFile();
|
||||
}
|
||||
|
||||
unsigned int TokenLocation::getColumnNumber() const
|
||||
{
|
||||
return m_columnNumber;
|
||||
}
|
||||
|
||||
unsigned int TokenLocation::getLineNumber() const
|
||||
{
|
||||
return m_line->getLineNumber();
|
||||
}
|
||||
|
||||
const FilePath& TokenLocation::getFilePath() const
|
||||
{
|
||||
return m_line->getFilePath();
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocation::getOtherTokenLocation() const
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
|
||||
void TokenLocation::setOtherTokenLocation(TokenLocation* location)
|
||||
{
|
||||
m_other = location;
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocation::getStartTokenLocation()
|
||||
{
|
||||
if (m_isStart)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocation::getEndTokenLocation()
|
||||
{
|
||||
if (!m_isStart)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
}
|
||||
|
||||
const TokenLocation* TokenLocation::getStartTokenLocation() const
|
||||
{
|
||||
if (m_isStart)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
}
|
||||
|
||||
const TokenLocation* TokenLocation::getEndTokenLocation() const
|
||||
{
|
||||
if (!m_isStart)
|
||||
{
|
||||
return this;
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_other;
|
||||
}
|
||||
}
|
||||
|
||||
bool TokenLocation::isStartTokenLocation() const
|
||||
{
|
||||
return m_isStart;
|
||||
}
|
||||
|
||||
bool TokenLocation::isEndTokenLocation() const
|
||||
{
|
||||
return !m_isStart;
|
||||
}
|
||||
|
||||
bool TokenLocation::isScopeTokenLocation() const
|
||||
{
|
||||
return m_type == LOCATION_SCOPE;
|
||||
}
|
||||
|
||||
bool TokenLocation::isFullTextSearchMatch() const
|
||||
{
|
||||
return m_type == LOCATION_FULLTEXT;
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocation& location)
|
||||
{
|
||||
if ((&location)->isStartTokenLocation())
|
||||
{
|
||||
ostream << "<";
|
||||
}
|
||||
|
||||
ostream << location.getColumnNumber() << ":[" << location.getTokenId() << "]";
|
||||
|
||||
if ((&location)->isEndTokenLocation())
|
||||
{
|
||||
ostream << ">";
|
||||
}
|
||||
|
||||
ostream << " ";
|
||||
return ostream;
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
#ifndef TOKEN_LOCATION_H
|
||||
#define TOKEN_LOCATION_H
|
||||
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "data/location/LocationType.h"
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class Token;
|
||||
class TokenLocationFile;
|
||||
class TokenLocationLine;
|
||||
|
||||
class TokenLocation
|
||||
{
|
||||
public:
|
||||
TokenLocation(Id locationId, Id tokenId, TokenLocationLine* line, unsigned int columnNumber, bool isStart);
|
||||
TokenLocation(TokenLocation* other, TokenLocationLine* line, unsigned int columnNumber, bool isStart);
|
||||
TokenLocation(const TokenLocation& other, TokenLocationLine* line);
|
||||
~TokenLocation();
|
||||
|
||||
bool operator<(const TokenLocation& rhs) const;
|
||||
bool operator>(const TokenLocation& rhs) const;
|
||||
|
||||
Id getId() const;
|
||||
Id getTokenId() const;
|
||||
|
||||
LocationType getType() const;
|
||||
void setType(LocationType type);
|
||||
|
||||
TokenLocationLine* getTokenLocationLine() const;
|
||||
TokenLocationFile* getTokenLocationFile() const;
|
||||
|
||||
unsigned int getColumnNumber() const;
|
||||
unsigned int getLineNumber() const;
|
||||
const FilePath& getFilePath() const;
|
||||
|
||||
TokenLocation* getOtherTokenLocation() const;
|
||||
void setOtherTokenLocation(TokenLocation* location);
|
||||
|
||||
TokenLocation* getStartTokenLocation();
|
||||
TokenLocation* getEndTokenLocation();
|
||||
|
||||
const TokenLocation* getStartTokenLocation() const;
|
||||
const TokenLocation* getEndTokenLocation() const;
|
||||
|
||||
bool isStartTokenLocation() const;
|
||||
bool isEndTokenLocation() const;
|
||||
|
||||
bool isScopeTokenLocation() const;
|
||||
bool isFullTextSearchMatch() const;
|
||||
|
||||
private:
|
||||
const Id m_id; // own id
|
||||
const Id m_tokenId;
|
||||
|
||||
LocationType m_type;
|
||||
|
||||
TokenLocationLine* const m_line;
|
||||
const unsigned int m_columnNumber;
|
||||
|
||||
TokenLocation* m_other;
|
||||
const bool m_isStart;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocation& location);
|
||||
|
||||
#endif // TOKEN_LOCATION_H
|
||||
@@ -1,233 +0,0 @@
|
||||
#include "data/location/TokenLocationCollection.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "utility/file/FileSystem.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
|
||||
TokenLocationCollection::TokenLocationCollection()
|
||||
{
|
||||
}
|
||||
|
||||
TokenLocationCollection::~TokenLocationCollection()
|
||||
{
|
||||
}
|
||||
|
||||
const TokenLocationCollection::TokenLocationFileMapType& TokenLocationCollection::getTokenLocationFiles() const
|
||||
{
|
||||
return m_files;
|
||||
}
|
||||
|
||||
const std::map<Id, TokenLocation*>& TokenLocationCollection::getTokenLocations() const
|
||||
{
|
||||
return m_locations;
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenLocationFile> TokenLocationCollection::getTokenLocationFileByPath(const FilePath& filePath) const
|
||||
{
|
||||
std::map<FilePath, std::shared_ptr<TokenLocationFile>>::const_iterator it = m_files.find(filePath);
|
||||
if (it != m_files.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t TokenLocationCollection::getTokenLocationFileCount() const
|
||||
{
|
||||
return m_files.size();
|
||||
}
|
||||
|
||||
size_t TokenLocationCollection::getTokenLocationLineCount() const
|
||||
{
|
||||
size_t count = 0;
|
||||
|
||||
for (const TokenLocationFilePairType& file : m_files)
|
||||
{
|
||||
count += file.second->getTokenLocationLineCount();
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
size_t TokenLocationCollection::getTokenLocationCount() const
|
||||
{
|
||||
return m_locations.size();
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationCollection::addTokenLocation(
|
||||
Id locationId, Id tokenId, const FilePath& filePath,
|
||||
unsigned int startLineNumber, unsigned int startColumnNumber,
|
||||
unsigned int endLineNumber, unsigned int endColumnNumber)
|
||||
{
|
||||
if (startLineNumber > endLineNumber || (startLineNumber == endLineNumber && startColumnNumber > endColumnNumber))
|
||||
{
|
||||
LOG_ERROR_STREAM(<< "TokenLocation has wrong boundaries: "<< filePath.str() << " "
|
||||
<< startLineNumber << ":" << startColumnNumber << " "
|
||||
<< endLineNumber << ":" << endColumnNumber);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TokenLocation* location = findTokenLocationById(locationId);
|
||||
if (location)
|
||||
{
|
||||
return location;
|
||||
}
|
||||
|
||||
TokenLocationFile* file = createTokenLocationFile(filePath);
|
||||
location = file->addTokenLocation(
|
||||
locationId, tokenId, startLineNumber, startColumnNumber, endLineNumber, endColumnNumber);
|
||||
|
||||
m_locations.emplace(location->getId(), location);
|
||||
return location;
|
||||
}
|
||||
|
||||
void TokenLocationCollection::removeTokenLocation(TokenLocation* location)
|
||||
{
|
||||
if (!location || !findTokenLocationById(location->getId()))
|
||||
{
|
||||
LOG_ERROR("TokenLocation is not part of this TokenLocationCollection.");
|
||||
return;
|
||||
}
|
||||
|
||||
m_locations.erase(location->getId());
|
||||
|
||||
TokenLocationFile* file = location->getTokenLocationFile();
|
||||
file->removeTokenLocation(location);
|
||||
|
||||
if (!file->getTokenLocationLineCount())
|
||||
{
|
||||
m_files.erase(file->getFilePath());
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocationFile* TokenLocationCollection::addTokenLocationFile(std::shared_ptr<TokenLocationFile> locationFile)
|
||||
{
|
||||
TokenLocationFile* file = findTokenLocationFileByPath(locationFile->getFilePath());
|
||||
if (file)
|
||||
{
|
||||
LOG_ERROR("TokenLocationFile with same path already exists.");
|
||||
return file;
|
||||
}
|
||||
|
||||
m_files.emplace(locationFile->getFilePath(), locationFile);
|
||||
locationFile->forEachTokenLocation(
|
||||
[this, &file](TokenLocation* tokenLocation) -> void
|
||||
{
|
||||
m_locations.emplace(tokenLocation->getId(), tokenLocation);
|
||||
}
|
||||
);
|
||||
return locationFile.get();
|
||||
}
|
||||
|
||||
void TokenLocationCollection::removeTokenLocationFile(TokenLocationFile* file)
|
||||
{
|
||||
file->forEachTokenLocation(
|
||||
[&](TokenLocation* location)
|
||||
{
|
||||
m_locations.erase(location->getId());
|
||||
}
|
||||
);
|
||||
|
||||
m_files.erase(file->getFilePath());
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationCollection::findTokenLocationById(Id id) const
|
||||
{
|
||||
std::map<Id, TokenLocation*>::const_iterator it = m_locations.find(id);
|
||||
|
||||
if (it != m_locations.end())
|
||||
{
|
||||
return it->second;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TokenLocationFile* TokenLocationCollection::findTokenLocationFileByPath(const FilePath& filePath) const
|
||||
{
|
||||
return getTokenLocationFileByPath(filePath).get();
|
||||
}
|
||||
|
||||
void TokenLocationCollection::forEachTokenLocationFile(
|
||||
std::function<void(std::shared_ptr<TokenLocationFile>)> func) const
|
||||
{
|
||||
for (const TokenLocationFilePairType& file : m_files)
|
||||
{
|
||||
func(file.second);
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationCollection::forEachTokenLocationLine(std::function<void(TokenLocationLine*)> func) const
|
||||
{
|
||||
for (const TokenLocationFilePairType& file : m_files)
|
||||
{
|
||||
file.second->forEachTokenLocationLine(func);
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationCollection::forEachTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationFilePairType& file : m_files)
|
||||
{
|
||||
file.second->forEachTokenLocation(func);
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocationFile* TokenLocationCollection::addTokenLocationFileAsPlainCopy(const TokenLocationFile* locationFile)
|
||||
{
|
||||
TokenLocationFile* file = createTokenLocationFile(locationFile->getFilePath());
|
||||
locationFile->forEachTokenLocation(
|
||||
[this, &file](TokenLocation* tokenLocation) -> void
|
||||
{
|
||||
TokenLocation* copy = file->addTokenLocationAsPlainCopy(tokenLocation);
|
||||
m_locations.emplace(copy->getId(), copy);
|
||||
}
|
||||
);
|
||||
return file;
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationCollection::addTokenLocationAsPlainCopy(const TokenLocation* location)
|
||||
{
|
||||
const FilePath& filePath = location->getTokenLocationLine()->getTokenLocationFile()->getFilePath();
|
||||
TokenLocationFile* file = createTokenLocationFile(filePath);
|
||||
TokenLocation* copy = file->addTokenLocationAsPlainCopy(location);
|
||||
|
||||
m_locations.emplace(copy->getId(), copy);
|
||||
return copy;
|
||||
}
|
||||
|
||||
void TokenLocationCollection::clear()
|
||||
{
|
||||
m_locations.clear();
|
||||
m_files.clear();
|
||||
}
|
||||
|
||||
TokenLocationFile* TokenLocationCollection::createTokenLocationFile(const FilePath& filePath)
|
||||
{
|
||||
TokenLocationFile* file = findTokenLocationFileByPath(filePath);
|
||||
|
||||
if (file)
|
||||
{
|
||||
return file;
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenLocationFile> filePtr = std::make_shared<TokenLocationFile>(filePath);
|
||||
m_files.emplace(filePath, filePtr);
|
||||
return filePtr.get();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocationCollection& base)
|
||||
{
|
||||
ostream << "Locations:\n";
|
||||
base.forEachTokenLocationFile([&ostream](std::shared_ptr<TokenLocationFile> f)
|
||||
{
|
||||
ostream << *(f.get());
|
||||
});
|
||||
return ostream;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
#ifndef TOKEN_LOCATION_COLLECTION_H
|
||||
#define TOKEN_LOCATION_COLLECTION_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class TokenLocation;
|
||||
class TokenLocationFile;
|
||||
class TokenLocationLine;
|
||||
|
||||
class TokenLocationCollection
|
||||
{
|
||||
public:
|
||||
typedef std::map<FilePath, std::shared_ptr<TokenLocationFile> > TokenLocationFileMapType;
|
||||
typedef std::pair<FilePath, std::shared_ptr<TokenLocationFile> > TokenLocationFilePairType;
|
||||
|
||||
TokenLocationCollection();
|
||||
~TokenLocationCollection();
|
||||
|
||||
const TokenLocationFileMapType& getTokenLocationFiles() const;
|
||||
const std::map<Id, TokenLocation*>& getTokenLocations() const;
|
||||
|
||||
std::shared_ptr<TokenLocationFile> getTokenLocationFileByPath(const FilePath& filePath) const;
|
||||
|
||||
size_t getTokenLocationFileCount() const;
|
||||
size_t getTokenLocationLineCount() const;
|
||||
size_t getTokenLocationCount() const;
|
||||
|
||||
TokenLocation* addTokenLocation(
|
||||
Id locationId, Id tokenId, const FilePath& filePath,
|
||||
unsigned int startLineNumber, unsigned int startColumnNumber,
|
||||
unsigned int endLineNumber, unsigned int endColumnNumber);
|
||||
void removeTokenLocation(TokenLocation* location);
|
||||
|
||||
TokenLocationFile* addTokenLocationFile(std::shared_ptr<TokenLocationFile> locationFile);
|
||||
void removeTokenLocationFile(TokenLocationFile* file);
|
||||
|
||||
TokenLocation* findTokenLocationById(Id id) const;
|
||||
TokenLocationFile* findTokenLocationFileByPath(const FilePath& filePath) const;
|
||||
|
||||
void forEachTokenLocationFile(std::function<void(std::shared_ptr<TokenLocationFile>)> func) const;
|
||||
void forEachTokenLocationLine(std::function<void(TokenLocationLine*)> func) const;
|
||||
void forEachTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
|
||||
TokenLocationFile* addTokenLocationFileAsPlainCopy(const TokenLocationFile* locationFile);
|
||||
TokenLocation* addTokenLocationAsPlainCopy(const TokenLocation* location);
|
||||
|
||||
void clear();
|
||||
|
||||
private:
|
||||
TokenLocationFile* createTokenLocationFile(const FilePath& filePath);
|
||||
|
||||
TokenLocationFileMapType m_files;
|
||||
std::map<Id, TokenLocation*> m_locations;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocationCollection& base);
|
||||
|
||||
#endif // TOKEN_LOCATION_COLLECTION_H
|
||||
@@ -1,260 +0,0 @@
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "utility/logging/logging.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
|
||||
TokenLocationFile::TokenLocationFile(const FilePath& filePath)
|
||||
: isWholeCopy(false)
|
||||
, m_filePath(filePath)
|
||||
{
|
||||
}
|
||||
|
||||
TokenLocationFile::~TokenLocationFile()
|
||||
{
|
||||
}
|
||||
|
||||
const TokenLocationFile::TokenLocationLineMapType& TokenLocationFile::getTokenLocationLines() const
|
||||
{
|
||||
return m_lines;
|
||||
}
|
||||
|
||||
size_t TokenLocationFile::getTokenLocationLineCount() const
|
||||
{
|
||||
return m_lines.size();
|
||||
}
|
||||
|
||||
size_t TokenLocationFile::getUnscopedStartTokenLocationCount() const
|
||||
{
|
||||
size_t count = 0;
|
||||
for (const TokenLocationLinePairType& line : m_lines)
|
||||
{
|
||||
line.second->forEachStartTokenLocation(
|
||||
[&count](TokenLocation* location)
|
||||
{
|
||||
if (!location->isScopeTokenLocation())
|
||||
{
|
||||
count++;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
const FilePath& TokenLocationFile::getFilePath() const
|
||||
{
|
||||
return m_filePath;
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationFile::addTokenLocation(
|
||||
Id locationId, Id tokenId,
|
||||
unsigned int startLineNumber, unsigned int startColumnNumber,
|
||||
unsigned int endLineNumber, unsigned int endColumnNumber)
|
||||
{
|
||||
TokenLocationLine* line = createTokenLocationLine(startLineNumber);
|
||||
|
||||
TokenLocation* start = line->addStartTokenLocation(locationId, tokenId, startColumnNumber);
|
||||
|
||||
if (startLineNumber != endLineNumber)
|
||||
{
|
||||
line = createTokenLocationLine(endLineNumber);
|
||||
}
|
||||
|
||||
line->addEndTokenLocation(start, endColumnNumber);
|
||||
|
||||
return start;
|
||||
}
|
||||
|
||||
void TokenLocationFile::removeTokenLocation(TokenLocation* location)
|
||||
{
|
||||
TokenLocationLine* line = location->getTokenLocationLine();
|
||||
|
||||
TokenLocation* otherLocation = location->getOtherTokenLocation();
|
||||
TokenLocationLine* otherLine = otherLocation->getTokenLocationLine();
|
||||
|
||||
line->removeTokenLocation(location);
|
||||
if (!line->getTokenLocationCount())
|
||||
{
|
||||
m_lines.erase(line->getLineNumber());
|
||||
}
|
||||
|
||||
otherLine->removeTokenLocation(otherLocation);
|
||||
if (!otherLine->getTokenLocationCount())
|
||||
{
|
||||
m_lines.erase(otherLine->getLineNumber());
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocationLine* TokenLocationFile::findTokenLocationLineByNumber(unsigned int lineNumber) const
|
||||
{
|
||||
return findTokenLocationLine(lineNumber);
|
||||
}
|
||||
|
||||
void TokenLocationFile::forEachTokenLocationLine(std::function<void(TokenLocationLine*)> func) const
|
||||
{
|
||||
for (const TokenLocationLinePairType& line : m_lines)
|
||||
{
|
||||
func(line.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationFile::forEachTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationLinePairType& line : m_lines)
|
||||
{
|
||||
line.second->forEachTokenLocation(func);
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationFile::forEachStartTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationLinePairType& line : m_lines)
|
||||
{
|
||||
line.second->forEachStartTokenLocation(func);
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationFile::forEachEndTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationLinePairType& line : m_lines)
|
||||
{
|
||||
line.second->forEachEndTokenLocation(func);
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationFile::addTokenLocationAsPlainCopy(const TokenLocation* location)
|
||||
{
|
||||
unsigned int lineNumber = location->getLineNumber();
|
||||
TokenLocationLine* line = createTokenLocationLine(lineNumber);
|
||||
|
||||
// Check whether this location was already added or if the other TokenLocation was added.
|
||||
TokenLocation* otherLocation = line->getTokenLocationById(location->getId());
|
||||
if (otherLocation)
|
||||
{
|
||||
if (otherLocation->isStartTokenLocation() == location->isStartTokenLocation())
|
||||
{
|
||||
// The location was already added.
|
||||
return otherLocation;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Look for the other location in it's line.
|
||||
unsigned int otherLineNumber = location->getOtherTokenLocation()->getLineNumber();
|
||||
if (lineNumber != otherLineNumber)
|
||||
{
|
||||
TokenLocationLine* otherLine = findTokenLocationLine(otherLineNumber);
|
||||
if (otherLine)
|
||||
{
|
||||
otherLocation = otherLine->getTokenLocationById(location->getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocation* copy = line->addTokenLocationAsPlainCopy(location);
|
||||
|
||||
// If the other location was added before, then link them with each other.
|
||||
if (otherLocation)
|
||||
{
|
||||
otherLocation->setOtherTokenLocation(copy);
|
||||
copy->setOtherTokenLocation(otherLocation);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenLocationFile> TokenLocationFile::getFilteredByLines(unsigned int firstLineNumber, unsigned int lastLineNumber) const
|
||||
{
|
||||
std::shared_ptr<TokenLocationFile> ret = std::make_shared<TokenLocationFile>(getFilePath().str());
|
||||
|
||||
if (getTokenLocationLines().size() == 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint endLineNumber = getTokenLocationLines().rbegin()->first;
|
||||
std::set<Id> addedLocationIds;
|
||||
for (uint i = firstLineNumber; i <= endLineNumber; i++)
|
||||
{
|
||||
TokenLocationLine* locationLine = findTokenLocationLineByNumber(i);
|
||||
if (!locationLine)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (locationLine->getLineNumber() <= lastLineNumber)
|
||||
{
|
||||
locationLine->forEachTokenLocation(
|
||||
[&](TokenLocation* tokenLocation) -> void
|
||||
{
|
||||
const Id tokenId = tokenLocation->getId();
|
||||
if (addedLocationIds.find(tokenId) == addedLocationIds.end())
|
||||
{
|
||||
ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation());
|
||||
ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation());
|
||||
addedLocationIds.insert(tokenId);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Save start locations of TokenLocations that span accross the line range.
|
||||
locationLine->forEachTokenLocation(
|
||||
[&](TokenLocation* tokenLocation) -> void
|
||||
{
|
||||
if (tokenLocation->isEndTokenLocation() &&
|
||||
tokenLocation->getStartTokenLocation()->getLineNumber() < firstLineNumber)
|
||||
{
|
||||
ret->addTokenLocationAsPlainCopy(tokenLocation->getStartTokenLocation());
|
||||
ret->addTokenLocationAsPlainCopy(tokenLocation->getEndTokenLocation());
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
TokenLocationLine* TokenLocationFile::findTokenLocationLine(unsigned int lineNumber) const
|
||||
{
|
||||
TokenLocationLineMapType::const_iterator it = m_lines.find(lineNumber);
|
||||
|
||||
if (it != m_lines.end())
|
||||
{
|
||||
return it->second.get();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
TokenLocationLine* TokenLocationFile::createTokenLocationLine(unsigned int lineNumber)
|
||||
{
|
||||
TokenLocationLine* line = findTokenLocationLine(lineNumber);
|
||||
|
||||
if (line)
|
||||
{
|
||||
return line;
|
||||
}
|
||||
|
||||
std::shared_ptr<TokenLocationLine> linePtr = std::make_shared<TokenLocationLine>(this, lineNumber);
|
||||
m_lines.emplace(lineNumber, linePtr);
|
||||
return linePtr.get();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocationFile& file)
|
||||
{
|
||||
ostream << "file \"" << file.getFilePath().str() << "\"\n";
|
||||
file.forEachTokenLocationLine([&ostream](TokenLocationLine* l)
|
||||
{
|
||||
ostream << *l << '\n';
|
||||
});
|
||||
return ostream;
|
||||
}
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
#ifndef TOKEN_LOCATION_FILE_H
|
||||
#define TOKEN_LOCATION_FILE_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class TokenLocation;
|
||||
class TokenLocationLine;
|
||||
|
||||
class TokenLocationFile
|
||||
{
|
||||
public:
|
||||
typedef std::map<unsigned int, std::shared_ptr<TokenLocationLine>> TokenLocationLineMapType;
|
||||
typedef std::pair<unsigned int, std::shared_ptr<TokenLocationLine>> TokenLocationLinePairType;
|
||||
|
||||
TokenLocationFile(const FilePath& filePath);
|
||||
~TokenLocationFile();
|
||||
|
||||
const TokenLocationLineMapType& getTokenLocationLines() const;
|
||||
size_t getTokenLocationLineCount() const;
|
||||
size_t getUnscopedStartTokenLocationCount() const;
|
||||
|
||||
const FilePath& getFilePath() const;
|
||||
|
||||
TokenLocation* addTokenLocation(
|
||||
Id locationId, Id tokenId,
|
||||
unsigned int startLineNumber, unsigned int startColumnNumber,
|
||||
unsigned int endLineNumber, unsigned int endColumnNumber);
|
||||
void removeTokenLocation(TokenLocation* location);
|
||||
|
||||
TokenLocationLine* findTokenLocationLineByNumber(unsigned int lineNumber) const;
|
||||
|
||||
void forEachTokenLocationLine(std::function<void(TokenLocationLine*)> func) const;
|
||||
void forEachTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
void forEachStartTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
void forEachEndTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
|
||||
TokenLocation* addTokenLocationAsPlainCopy(const TokenLocation* location);
|
||||
|
||||
std::shared_ptr<TokenLocationFile> getFilteredByLines(unsigned int firstLineNumber, unsigned int lastLineNumber) const;
|
||||
|
||||
bool isWholeCopy;
|
||||
|
||||
private:
|
||||
TokenLocationLine* findTokenLocationLine(unsigned int lineNumber) const;
|
||||
TokenLocationLine* createTokenLocationLine(unsigned int lineNumber);
|
||||
|
||||
std::map<unsigned int, std::shared_ptr<TokenLocationLine> > m_lines;
|
||||
FilePath m_filePath;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocationFile& file);
|
||||
|
||||
#endif // TOKEN_LOCATION_FILE_H
|
||||
@@ -1,131 +0,0 @@
|
||||
#include "data/location/TokenLocationLine.h"
|
||||
|
||||
#include "data/location/TokenLocation.h"
|
||||
#include "data/location/TokenLocationFile.h"
|
||||
#include "utility/logging/logging.h"
|
||||
|
||||
TokenLocationLine::TokenLocationLine(TokenLocationFile* file, unsigned int lineNumber)
|
||||
: m_file(file)
|
||||
, m_lineNumber(lineNumber)
|
||||
{
|
||||
}
|
||||
|
||||
TokenLocationLine::~TokenLocationLine()
|
||||
{
|
||||
}
|
||||
|
||||
const TokenLocationLine::TokenLocationMapType& TokenLocationLine::getTokenLocations() const
|
||||
{
|
||||
return m_locations;
|
||||
}
|
||||
|
||||
size_t TokenLocationLine::getTokenLocationCount() const
|
||||
{
|
||||
return m_locations.size();
|
||||
}
|
||||
|
||||
TokenLocationFile* TokenLocationLine::getTokenLocationFile() const
|
||||
{
|
||||
return m_file;
|
||||
}
|
||||
|
||||
const FilePath& TokenLocationLine::getFilePath() const
|
||||
{
|
||||
return m_file->getFilePath();
|
||||
}
|
||||
|
||||
unsigned int TokenLocationLine::getLineNumber() const
|
||||
{
|
||||
return m_lineNumber;
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationLine::addStartTokenLocation(Id locationId, Id tokenId, unsigned int columnNumber)
|
||||
{
|
||||
std::shared_ptr<TokenLocation> locationPtr = std::make_shared<TokenLocation>(locationId, tokenId, this, columnNumber, true);
|
||||
m_locations.emplace(columnNumber, locationPtr);
|
||||
return locationPtr.get();
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationLine::addEndTokenLocation(TokenLocation* start, unsigned int columnNumber)
|
||||
{
|
||||
std::shared_ptr<TokenLocation> locationPtr = std::make_shared<TokenLocation>(start, this, columnNumber, false);
|
||||
start->setOtherTokenLocation(locationPtr.get());
|
||||
m_locations.emplace(columnNumber, locationPtr);
|
||||
return locationPtr.get();
|
||||
}
|
||||
|
||||
void TokenLocationLine::removeTokenLocation(TokenLocation* location)
|
||||
{
|
||||
TokenLocationMapType::iterator it = m_locations.find(location->getColumnNumber());
|
||||
|
||||
while (it->first == location->getColumnNumber())
|
||||
{
|
||||
if (it->second.get() == location)
|
||||
{
|
||||
m_locations.erase(it);
|
||||
return;
|
||||
}
|
||||
it++;
|
||||
}
|
||||
|
||||
LOG_ERROR("TokenLocation can't be removed, it's not part of the TokenLocationLine.");
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationLine::getTokenLocationById(Id id) const
|
||||
{
|
||||
for (const TokenLocationPairType& p : m_locations)
|
||||
{
|
||||
if (p.second->getId() == id)
|
||||
{
|
||||
return p.second.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void TokenLocationLine::forEachTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationPairType& location : m_locations)
|
||||
{
|
||||
func(location.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationLine::forEachStartTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationPairType& location : m_locations)
|
||||
{
|
||||
if (location.second->isStartTokenLocation())
|
||||
{
|
||||
func(location.second.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TokenLocationLine::forEachEndTokenLocation(std::function<void(TokenLocation*)> func) const
|
||||
{
|
||||
for (const TokenLocationPairType& location : m_locations)
|
||||
{
|
||||
if (location.second->isEndTokenLocation())
|
||||
{
|
||||
func(location.second.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TokenLocation* TokenLocationLine::addTokenLocationAsPlainCopy(const TokenLocation* location)
|
||||
{
|
||||
std::shared_ptr<TokenLocation> locationPtr = std::make_shared<TokenLocation>(*location, this);
|
||||
m_locations.emplace(location->getColumnNumber(), locationPtr);
|
||||
return locationPtr.get();
|
||||
}
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocationLine& line)
|
||||
{
|
||||
ostream << line.getLineNumber() << ": ";
|
||||
line.forEachTokenLocation([&ostream](TokenLocation* l)
|
||||
{
|
||||
ostream << *l;
|
||||
});
|
||||
return ostream;
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
#ifndef TOKEN_LOCATION_LINE_H
|
||||
#define TOKEN_LOCATION_LINE_H
|
||||
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "utility/file/FilePath.h"
|
||||
#include "utility/types.h"
|
||||
|
||||
class TokenLocation;
|
||||
class TokenLocationFile;
|
||||
|
||||
class TokenLocationLine
|
||||
{
|
||||
public:
|
||||
typedef std::multimap<unsigned int, std::shared_ptr<TokenLocation> > TokenLocationMapType;
|
||||
typedef std::pair<unsigned int, std::shared_ptr<TokenLocation> > TokenLocationPairType;
|
||||
|
||||
TokenLocationLine(TokenLocationFile* file, unsigned int lineNumber);
|
||||
~TokenLocationLine();
|
||||
|
||||
const TokenLocationMapType& getTokenLocations() const;
|
||||
size_t getTokenLocationCount() const;
|
||||
|
||||
TokenLocationFile* getTokenLocationFile() const;
|
||||
const FilePath& getFilePath() const;
|
||||
|
||||
unsigned int getLineNumber() const;
|
||||
|
||||
TokenLocation* addStartTokenLocation(Id locationId, Id tokenId, unsigned int columnNumber);
|
||||
TokenLocation* addEndTokenLocation(TokenLocation* start, unsigned int columnNumber);
|
||||
void removeTokenLocation(TokenLocation* location);
|
||||
|
||||
TokenLocation* getTokenLocationById(Id id) const;
|
||||
|
||||
void forEachTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
void forEachStartTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
void forEachEndTokenLocation(std::function<void(TokenLocation*)> func) const;
|
||||
|
||||
TokenLocation* addTokenLocationAsPlainCopy(const TokenLocation* location);
|
||||
|
||||
private:
|
||||
TokenLocationMapType m_locations;
|
||||
|
||||
TokenLocationFile* const m_file;
|
||||
const unsigned int m_lineNumber;
|
||||
};
|
||||
|
||||
std::ostream& operator<<(std::ostream& ostream, const TokenLocationLine& line);
|
||||
|
||||
#endif // TOKEN_LOCATION_LINE_H
|
||||
Reference in New Issue
Block a user