Files
Sourcetrail/src/lib/data/location/TokenLocationFile.cpp
T
Eberhard Graether 9bcf7d2f0f data: cleaned up TokenLocation classes
* removed self assiged locationId
* show errors after parse again
2015-08-27 22:14:12 +02:00

184 lines
4.7 KiB
C++

#include "data/location/TokenLocationFile.h"
#include "utility/logging/logging.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();
}
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->getTokenLocationLine()->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()->getTokenLocationLine()->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;
}
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;
}