From 4e0c418fa647164142cbe90b700aa5b5ea2ea0a0 Mon Sep 17 00:00:00 2001
From: dt <qtc-committer@nokia.com>
Date: Mon, 4 May 2009 18:22:40 +0200
Subject: [PATCH] Add per file information on the inlucde paths and defines to
 qt4projects

This is a step towards fixing Task: 243747
---
 src/plugins/projectexplorer/project.cpp      |  15 +++
 src/plugins/projectexplorer/project.h        |   6 +
 src/plugins/qt4projectmanager/qt4project.cpp | 114 ++++++++++++++++---
 src/plugins/qt4projectmanager/qt4project.h   |  18 ++-
 4 files changed, 134 insertions(+), 19 deletions(-)

diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 0d990a02e34..459f8114acf 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -505,3 +505,18 @@ void Project::setDisplayNameFor(const QString &buildConfiguration, const QString
     }
     emit buildConfigurationDisplayNameChanged(buildConfiguration);
 }
+
+QByteArray Project::predefinedMacros(const QString &fileName) const
+{
+    return QByteArray();
+}
+
+QStringList Project::includePaths(const QString &fileName) const
+{
+    return QStringList();
+}
+
+QStringList Project::frameworkPaths(const QString &fileName) const
+{
+    return QStringList();
+}
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index b4be7fa0c1c..e876db67557 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -136,6 +136,12 @@ public:
     enum FilesMode { AllFiles, ExcludeGeneratedFiles };
     virtual QStringList files(FilesMode fileMode) const = 0;
 
+    // C++ specific
+    // TODO do a C++ project as a base ?
+    virtual QByteArray predefinedMacros(const QString &fileName) const;
+    virtual QStringList includePaths(const QString &fileName) const;
+    virtual QStringList frameworkPaths(const QString &fileName) const;
+
 signals:
     void fileListChanged();
     void activeBuildConfigurationChanged();
diff --git a/src/plugins/qt4projectmanager/qt4project.cpp b/src/plugins/qt4projectmanager/qt4project.cpp
index 0f08672ebe1..87a75f31bf3 100644
--- a/src/plugins/qt4projectmanager/qt4project.cpp
+++ b/src/plugins/qt4projectmanager/qt4project.cpp
@@ -46,7 +46,6 @@
 #include <coreplugin/icore.h>
 #include <coreplugin/messagemanager.h>
 #include <coreplugin/coreconstants.h>
-#include <cpptools/cppmodelmanagerinterface.h>
 #include <extensionsystem/pluginmanager.h>
 #include <projectexplorer/nodesvisitor.h>
 #include <projectexplorer/project.h>
@@ -308,7 +307,7 @@ void Qt4Project::restoreSettingsImpl(PersistentSettingsReader &settingsReader)
     connect(m_nodesWatcher, SIGNAL(filesAdded()), this, SLOT(updateFileList()));
     connect(m_nodesWatcher, SIGNAL(filesRemoved()), this, SLOT(updateFileList()));
     connect(m_nodesWatcher, SIGNAL(proFileUpdated(Qt4ProjectManager::Internal::Qt4ProFileNode *)),
-            this, SLOT(scheduleUpdateCodeModel()));
+            this, SLOT(scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *)));
 
     update();
 
@@ -398,9 +397,10 @@ void Qt4Project::addUiFiles()
     m_uiFilesToAdd.clear();
 }
 
-void Qt4Project::scheduleUpdateCodeModel()
+void Qt4Project::scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *pro)
 {
     m_updateCodeModelTimer.start();
+    m_proFilesForCodeModelUpdate.append(pro);
 }
 
 QString Qt4Project::makeCommand(const QString &buildConfiguration) const
@@ -469,15 +469,11 @@ void Qt4Project::updateCodeModel()
     if (!modelmanager)
         return;
 
-    QStringList allIncludePaths;
-    QStringList allFrameworkPaths;
-
-    const QHash<QString, QString> versionInfo = qtVersion(activeBuildConfiguration())->versionInfo();
-    const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS"));
-    const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
+    QStringList predefinedIncludePaths;
+    QStringList predefinedFrameworkPaths;
+    QByteArray predefinedMacros;
 
     ToolChain *tc = toolChain(activeBuildConfiguration());
-    QByteArray predefinedMacros;
     QList<HeaderPath> allHeaderPaths;
     if (tc) {
         predefinedMacros = tc->predefinedMacros();
@@ -491,17 +487,21 @@ void Qt4Project::updateCodeModel()
     }
     foreach (HeaderPath headerPath, allHeaderPaths) {
         if (headerPath.kind() == HeaderPath::FrameworkHeaderPath)
-            allFrameworkPaths.append(headerPath.path());
+            predefinedFrameworkPaths.append(headerPath.path());
         else
-            allIncludePaths.append(headerPath.path());
+            predefinedIncludePaths.append(headerPath.path());
     }
 
-    allIncludePaths.append(newQtIncludePath);
+    const QHash<QString, QString> versionInfo = qtVersion(activeBuildConfiguration())->versionInfo();
+    const QString newQtIncludePath = versionInfo.value(QLatin1String("QT_INSTALL_HEADERS"));
+    const QString newQtLibsPath = versionInfo.value(QLatin1String("QT_INSTALL_LIBS"));
+
+    predefinedIncludePaths.append(newQtIncludePath);
     QDir dir(newQtIncludePath);
     foreach (QFileInfo info, dir.entryInfoList(QDir::Dirs)) {
         if (! info.fileName().startsWith(QLatin1String("Qt")))
             continue;
-        allIncludePaths.append(info.absoluteFilePath());
+        predefinedIncludePaths.append(info.absoluteFilePath());
     }
 
 #ifdef Q_OS_MAC
@@ -517,15 +517,26 @@ void Qt4Project::updateCodeModel()
 
     FindQt4ProFiles findQt4ProFiles;
     QList<Qt4ProFileNode *> proFiles = findQt4ProFiles(rootProjectNode());
-    QByteArray definedMacros;
+    QByteArray definedMacros = predefinedMacros;
+    QStringList allIncludePaths = predefinedIncludePaths;
+    QStringList allFrameworkPaths = predefinedFrameworkPaths;
 
     foreach (Qt4ProFileNode *pro, proFiles) {
+        Internal::CodeModelInfo info;
+        info.defines = predefinedMacros;
+        info.includes = predefinedIncludePaths;
+        info.frameworkPaths = predefinedFrameworkPaths;
+
+        // Add custom defines
         foreach (const QString def, pro->variableValue(DefinesVar)) {
             definedMacros += "#define ";
+            info.defines += "#define ";
             const int index = def.indexOf(QLatin1Char('='));
             if (index == -1) {
                 definedMacros += def.toLatin1();
                 definedMacros += " 1\n";
+                info.defines += def.toLatin1();
+                info.defines += " 1\n";
             } else {
                 const QString name = def.left(index);
                 const QString value = def.mid(index + 1);
@@ -533,21 +544,48 @@ void Qt4Project::updateCodeModel()
                 definedMacros += ' ';
                 definedMacros += value.toLocal8Bit();
                 definedMacros += '\n';
+                info.defines += name.toLatin1();
+                info.defines += ' ';
+                info.defines += value.toLocal8Bit();
+                info.defines += '\n';
             }
         }
 
         const QStringList proIncludePaths = pro->variableValue(IncludePathVar);
         foreach (QString includePath, proIncludePaths) {
-            if (allIncludePaths.contains(includePath))
-                continue;
+            if (!allIncludePaths.contains(includePath))
+                allIncludePaths.append(includePath);
+            if (!info.includes.contains(includePath))
+                info.includes.append(includePath);
+        }
 
-            allIncludePaths.append(includePath);
+        // Add mkspec directory
+        info.includes.append(qtVersion(activeBuildConfiguration())->mkspecPath());
+
+        info.frameworkPaths = allFrameworkPaths;
+
+        foreach (FileNode *fileNode, pro->fileNodes()) {
+            const QString path = fileNode->path();
+            const int type = fileNode->fileType();
+            if (type == HeaderType || type == SourceType) {
+                m_codeModelInfo.insert(path, info);
+            }
         }
     }
 
     // Add mkspec directory
     allIncludePaths.append(qtVersion(activeBuildConfiguration())->mkspecPath());
 
+    // Dump things out
+    // This is debugging output...
+//    qDebug()<<"CodeModel stuff:";
+//    QMap<QString, CodeModelInfo>::const_iterator it, end;
+//    end = m_codeModelInfo.constEnd();
+//    for(it = m_codeModelInfo.constBegin(); it != end; ++it) {
+//        qDebug()<<"File: "<<it.key()<<"\nIncludes:"<<it.value().includes<<"\nDefines"<<it.value().defines<<"\n";
+//    }
+//    qDebug()<<"----------------------------";
+
     QStringList files;
     files += m_projectFiles->files[HeaderType];
     files += m_projectFiles->generatedFiles[HeaderType];
@@ -562,6 +600,13 @@ void Qt4Project::updateCodeModel()
             pinfo.sourceFiles == files) {
         modelmanager->updateProjectInfo(pinfo);
     } else {
+        if (pinfo.defines != predefinedMacros         ||
+            pinfo.includePaths != allIncludePaths     ||
+            pinfo.frameworkPaths != allFrameworkPaths) {
+            pinfo.sourceFiles.append(QLatin1String("<configuration>"));
+        }
+
+
         pinfo.defines = predefinedMacros;
         // pinfo->defines += definedMacros;   // ### FIXME: me
         pinfo.includePaths = allIncludePaths;
@@ -571,8 +616,41 @@ void Qt4Project::updateCodeModel()
         modelmanager->updateProjectInfo(pinfo);
         modelmanager->updateSourceFiles(pinfo.sourceFiles);
     }
+
+    // TODO use this information
+    // These are the pro files that were actually changed
+    // if the list is empty we are at the initial stage
+    // TODO check that this also works if pro files get added
+    // and removed
+    m_proFilesForCodeModelUpdate.clear();
+}
+
+QByteArray Qt4Project::predefinedMacros(const QString &fileName) const
+{
+    QMap<QString, CodeModelInfo>::const_iterator it = m_codeModelInfo.constFind(fileName);
+    if (it == m_codeModelInfo.constEnd())
+        return QByteArray();
+    else
+        return (*it).defines;
 }
 
+QStringList Qt4Project::includePaths(const QString &fileName) const
+{
+    QMap<QString, CodeModelInfo>::const_iterator it = m_codeModelInfo.constFind(fileName);
+    if (it == m_codeModelInfo.constEnd())
+        return QStringList();
+    else
+        return (*it).includes;
+}
+
+QStringList Qt4Project::frameworkPaths(const QString &fileName) const
+{
+    QMap<QString, CodeModelInfo>::const_iterator it = m_codeModelInfo.constFind(fileName);
+    if (it == m_codeModelInfo.constEnd())
+        return QStringList();
+    else
+        return (*it).frameworkPaths;
+}
 
 ///*!
 //  Updates complete project
diff --git a/src/plugins/qt4projectmanager/qt4project.h b/src/plugins/qt4projectmanager/qt4project.h
index fc1feac3f29..7a8ae6d67a2 100644
--- a/src/plugins/qt4projectmanager/qt4project.h
+++ b/src/plugins/qt4projectmanager/qt4project.h
@@ -39,6 +39,7 @@
 #include <projectexplorer/applicationrunconfiguration.h>
 #include <projectexplorer/projectnodes.h>
 #include <projectexplorer/toolchain.h>
+#include <cpptools/cppmodelmanagerinterface.h>
 
 #include <QtCore/QObject>
 #include <QtCore/QList>
@@ -69,6 +70,14 @@ namespace Internal {
     class Qt4RunConfiguration;
     class GCCPreprocessor;
     struct Qt4ProjectFiles;
+
+    class CodeModelInfo
+    {
+    public:
+        QByteArray defines;
+        QStringList includes;
+        QStringList frameworkPaths;
+    };
 }
 
 class QMakeStep;
@@ -185,10 +194,14 @@ public:
     // the Qt4RunConfigurations will update as soon as asked
     void invalidateCachedTargetInformation();
 
+    virtual QByteArray predefinedMacros(const QString &fileName) const;
+    virtual QStringList includePaths(const QString &fileName) const;
+    virtual QStringList frameworkPaths(const QString &fileName) const;
+
 public slots:
     void update();
     void proFileParseError(const QString &errorMessage);
-    void scheduleUpdateCodeModel();
+    void scheduleUpdateCodeModel(Qt4ProjectManager::Internal::Qt4ProFileNode *);
 
 private slots:
     void updateCodeModel();
@@ -242,6 +255,9 @@ private:
     QTimer m_updateCodeModelTimer;
     QTimer m_addUiFilesTimer;
     QStringList m_uiFilesToAdd;
+    QList<Qt4ProjectManager::Internal::Qt4ProFileNode *> m_proFilesForCodeModelUpdate;
+
+    QMap<QString, Internal::CodeModelInfo> m_codeModelInfo;
 
     friend class Qt4ProjectFile;
 };
-- 
GitLab