Commit 82e34709 authored by Erik Verbruggen's avatar Erik Verbruggen Committed by Nikolai Kosjar

C++: Untangle include file resolving from loading.

Change-Id: Iacf8cb12dd623c908538d80ee2595297a9bdde71
Reviewed-by: default avatarNikolai Kosjar <nikolai.kosjar@digia.com>
parent 857457e0
......@@ -62,7 +62,7 @@ QByteArray FastPreprocessor::run(Document::Ptr newDoc, const QString &source)
return preprocessed;
}
void FastPreprocessor::sourceNeeded(unsigned line, QString &fileName, IncludeType)
void FastPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType)
{
Q_ASSERT(_currentDoc);
// CHECKME: Is that cleanName needed?
......
......@@ -57,7 +57,7 @@ public:
QByteArray run(Document::Ptr newDoc, const QString &source);
// CPlusPlus::Client
virtual void sourceNeeded(unsigned line, QString &fileName, IncludeType);
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType);
virtual void macroAdded(const Macro &);
......
......@@ -98,7 +98,7 @@ public:
virtual void startSkippingBlocks(unsigned offset) = 0;
virtual void stopSkippingBlocks(unsigned offset) = 0;
virtual void sourceNeeded(unsigned line, QString &fileName, IncludeType mode) = 0;
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType mode) = 0;
};
} // namespace CPlusPlus
......
......@@ -315,8 +315,7 @@ public:
void CppPreprocessor::run(const QString &fileName)
{
QString absoluteFilePath = fileName;
sourceNeeded(0, absoluteFilePath, IncludeGlobal);
sourceNeeded(0, fileName, IncludeGlobal);
}
void CppPreprocessor::removeFromCache(const QString &fileName)
......@@ -330,60 +329,60 @@ void CppPreprocessor::resetEnvironment()
m_processed.clear();
}
bool CppPreprocessor::includeFile(const QString &absoluteFilePath, QString *result, unsigned *revision)
void CppPreprocessor::getFileContents(const QString &absoluteFilePath,
QString *contents,
unsigned *revision) const
{
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath))
return true;
if (absoluteFilePath.isEmpty())
return;
if (m_workingCopy.contains(absoluteFilePath)) {
m_included.insert(absoluteFilePath);
const QPair<QString, unsigned> r = m_workingCopy.get(absoluteFilePath);
*result = r.first;
*revision = r.second;
return true;
QPair<QString, unsigned> entry = m_workingCopy.get(absoluteFilePath);
if (contents)
*contents = entry.first;
if (revision)
*revision = entry.second;
return;
}
QFileInfo fileInfo(absoluteFilePath);
if (! fileInfo.isFile())
return false;
QFile file(absoluteFilePath);
if (file.open(QFile::ReadOnly | QFile::Text)) {
m_included.insert(absoluteFilePath);
QTextCodec *defaultCodec = Core::EditorManager::instance()->defaultTextCodec();
QTextStream stream(&file);
stream.setCodec(defaultCodec);
if (result)
*result = stream.readAll();
if (contents)
*contents = stream.readAll();
if (revision)
*revision = 0;
file.close();
return true;
}
return false;
}
QString CppPreprocessor::tryIncludeFile(QString &fileName, IncludeType type, unsigned *revision)
bool CppPreprocessor::checkFile(const QString &absoluteFilePath) const
{
if (type == IncludeGlobal) {
const QString fn = m_fileNameCache.value(fileName);
if (absoluteFilePath.isEmpty() || m_included.contains(absoluteFilePath))
return true;
if (! fn.isEmpty()) {
fileName = fn;
QFileInfo fileInfo(absoluteFilePath);
return fileInfo.isFile() && fileInfo.isReadable();
}
if (revision)
*revision = 0;
/// Resolve the given file name to its absolute path w.r.t. the include type.
QString CppPreprocessor::resolveFile(const QString &fileName, IncludeType type)
{
if (type == IncludeGlobal) {
QString fn = m_fileNameCache.value(fileName);
return QString();
}
if (! fn.isEmpty())
return fn;
const QString originalFileName = fileName;
const QString contents = tryIncludeFile_helper(fileName, type, revision);
m_fileNameCache.insert(originalFileName, fileName);
return contents;
fn = resolveFile_helper(fileName, type);
m_fileNameCache.insert(fileName, fn);
return fn;
}
// IncludeLocal, IncludeNext
return tryIncludeFile_helper(fileName, type, revision);
return resolveFile_helper(fileName, type);
}
QString CppPreprocessor::cleanPath(const QString &path)
......@@ -395,32 +394,23 @@ QString CppPreprocessor::cleanPath(const QString &path)
return result;
}
QString CppPreprocessor::tryIncludeFile_helper(QString &fileName, IncludeType type, unsigned *revision)
QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType type)
{
QFileInfo fileInfo(fileName);
if (fileName == Preprocessor::configurationFileName || fileInfo.isAbsolute()) {
QString contents;
includeFile(fileName, &contents, revision);
return contents;
}
if (fileName == Preprocessor::configurationFileName || fileInfo.isAbsolute())
return fileName;
if (type == IncludeLocal && m_currentDoc) {
QFileInfo currentFileInfo(m_currentDoc->fileName());
QString path = cleanPath(currentFileInfo.absolutePath()) + fileName;
QString contents;
if (includeFile(path, &contents, revision)) {
fileName = path;
return contents;
}
if (checkFile(path))
return path;
}
foreach (const QString &includePath, m_includePaths) {
QString path = includePath + fileName;
QString contents;
if (includeFile(path, &contents, revision)) {
fileName = path;
return contents;
}
if (checkFile(path))
return path;
}
int index = fileName.indexOf(QLatin1Char('/'));
......@@ -430,11 +420,8 @@ QString CppPreprocessor::tryIncludeFile_helper(QString &fileName, IncludeType ty
foreach (const QString &frameworkPath, m_frameworkPaths) {
QString path = frameworkPath + name;
QString contents;
if (includeFile(path, &contents, revision)) {
fileName = path;
return contents;
}
if (checkFile(path))
return path;
}
}
......@@ -547,18 +534,24 @@ void CppPreprocessor::stopSkippingBlocks(unsigned offset)
m_currentDoc->stopSkippingBlocks(offset);
}
void CppPreprocessor::sourceNeeded(unsigned line, QString &fileName, IncludeType type)
void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type)
{
if (fileName.isEmpty())
return;
QString absoluteFileName = resolveFile(fileName, type);
if (m_included.contains(absoluteFileName))
return; // we've already seen this file.
m_included.insert(absoluteFileName);
absoluteFileName = QDir::cleanPath(absoluteFileName);
unsigned editorRevision = 0;
QString contents = tryIncludeFile(fileName, type, &editorRevision);
fileName = QDir::cleanPath(fileName);
QString contents;
getFileContents(absoluteFileName, &contents, &editorRevision);
if (m_currentDoc) {
m_currentDoc->addIncludeFile(fileName, line);
m_currentDoc->addIncludeFile(absoluteFileName, line);
if (contents.isEmpty() && ! QFileInfo(fileName).isAbsolute()) {
if (contents.isEmpty() && ! QFileInfo(absoluteFileName).isAbsolute()) {
QString msg = QCoreApplication::translate(
"CppPreprocessor", "%1: No such file or directory").arg(fileName);
......@@ -570,32 +563,34 @@ void CppPreprocessor::sourceNeeded(unsigned line, QString &fileName, IncludeType
m_currentDoc->addDiagnosticMessage(d);
//qWarning() << "file not found:" << fileName << m_currentDoc->fileName() << env.current_line;
return;
}
}
if (m_dumpFileNameWhileParsing) {
qDebug() << "Parsing file:" << fileName
qDebug() << "Parsing file:" << absoluteFileName
// << "contents:" << contents.size()
;
}
Document::Ptr doc = m_snapshot.document(fileName);
Document::Ptr doc = m_snapshot.document(absoluteFileName);
if (doc) {
mergeEnvironment(doc);
return;
}
doc = Document::create(fileName);
doc = Document::create(absoluteFileName);
doc->setRevision(m_revision);
doc->setEditorRevision(editorRevision);
QFileInfo info(fileName);
QFileInfo info(absoluteFileName);
if (info.exists())
doc->setLastModified(info.lastModified());
Document::Ptr previousDoc = switchDocument(doc);
const QByteArray preprocessedCode = m_preprocess.run(fileName, contents);
const QByteArray preprocessedCode = m_preprocess.run(absoluteFileName, contents);
// { QByteArray b(preprocessedCode); b.replace("\n", "<<<\n"); qDebug("Preprocessed code for \"%s\": [[%s]]", fileName.toUtf8().constData(), b.constData()); }
......@@ -604,7 +599,7 @@ void CppPreprocessor::sourceNeeded(unsigned line, QString &fileName, IncludeType
doc->tokenize();
m_snapshot.insert(doc);
m_todo.remove(fileName);
m_todo.remove(absoluteFileName);
Process process(m_modelManager, doc, m_workingCopy);
process();
......
......@@ -281,9 +281,10 @@ public:
protected:
CPlusPlus::Document::Ptr switchDocument(CPlusPlus::Document::Ptr doc);
bool includeFile(const QString &absoluteFilePath, QString *result, unsigned *revision);
QString tryIncludeFile(QString &fileName, IncludeType type, unsigned *revision);
QString tryIncludeFile_helper(QString &fileName, IncludeType type, unsigned *revision);
void getFileContents(const QString &absoluteFilePath, QString *contents, unsigned *revision) const;
bool checkFile(const QString &absoluteFilePath) const;
QString resolveFile(const QString &fileName, IncludeType type);
QString resolveFile_helper(const QString &fileName, IncludeType type);
void mergeEnvironment(CPlusPlus::Document::Ptr doc);
......@@ -301,7 +302,7 @@ protected:
virtual void markAsIncludeGuard(const QByteArray &macroName);
virtual void startSkippingBlocks(unsigned offset);
virtual void stopSkippingBlocks(unsigned offset);
virtual void sourceNeeded(unsigned line, QString &fileName, IncludeType type);
virtual void sourceNeeded(unsigned line, const QString &fileName, IncludeType type);
private:
CPlusPlus::Snapshot m_snapshot;
......
......@@ -143,7 +143,7 @@ public:
virtual void stopSkippingBlocks(unsigned offset)
{ m_skippedBlocks.last().end = offset; }
virtual void sourceNeeded(unsigned line, QString &includedFileName, IncludeType mode)
virtual void sourceNeeded(unsigned line, const QString &includedFileName, IncludeType mode)
{
#if 1
m_recordedIncludes.append(Include(includedFileName, mode, line));
......
......@@ -67,7 +67,7 @@ public:
void addInclude(const QString &absoluteFilePath)
{ included.append(absoluteFilePath); }
virtual void sourceNeeded(QString &fileName, IncludeType mode, unsigned)
virtual void sourceNeeded(const QString &fileName, IncludeType mode, unsigned)
{
const QString currentFile = env->currentFile;
......@@ -122,7 +122,7 @@ public:
virtual void stopSkippingBlocks(unsigned)
{ }
virtual void sourceNeeded(unsigned, QString &, IncludeType)
virtual void sourceNeeded(unsigned, const QString &, IncludeType)
{ }
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment