forked from qt-creator/qt-creator
		
	Merge remote-tracking branch 'origin/3.5'
Conflicts: scripts/deployqtHelper_mac.sh Change-Id: Ia0d5fef8c28e0bfb3b0c703ad3652e2d70d9e7d1
This commit is contained in:
		@@ -31,6 +31,7 @@
 | 
			
		||||
#include "baseeditordocumentparser.h"
 | 
			
		||||
#include "baseeditordocumentprocessor.h"
 | 
			
		||||
 | 
			
		||||
#include "cpptoolsreuse.h"
 | 
			
		||||
#include "editordocumenthandle.h"
 | 
			
		||||
 | 
			
		||||
namespace CppTools {
 | 
			
		||||
@@ -44,15 +45,18 @@ namespace CppTools {
 | 
			
		||||
    It's meant to be used in the C++ editor to get precise results by using
 | 
			
		||||
    the "best" project part for a file.
 | 
			
		||||
 | 
			
		||||
    Derived classes are expected to implement update() by using the protected
 | 
			
		||||
    mutex, updateProjectPart() and by respecting the options set by the client.
 | 
			
		||||
    Derived classes are expected to implement updateHelper() this way:
 | 
			
		||||
 | 
			
		||||
    \list
 | 
			
		||||
        \li Get a copy of the configuration and the last state.
 | 
			
		||||
        \li Work on the data and do whatever is necessary. At least, update
 | 
			
		||||
            the project part with the help of determineProjectPart().
 | 
			
		||||
        \li Ensure the new state is set before updateHelper() returns.
 | 
			
		||||
    \endlist
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
BaseEditorDocumentParser::BaseEditorDocumentParser(const QString &filePath)
 | 
			
		||||
    : m_mutex(QMutex::Recursive)
 | 
			
		||||
    , m_filePath(filePath)
 | 
			
		||||
    , m_usePrecompiledHeaders(false)
 | 
			
		||||
    , m_editorDefinesChangedSinceLastUpdate(false)
 | 
			
		||||
    : m_filePath(filePath)
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -65,44 +69,39 @@ QString BaseEditorDocumentParser::filePath() const
 | 
			
		||||
    return m_filePath;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BaseEditorDocumentParser::Configuration BaseEditorDocumentParser::configuration() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    return m_configuration;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::setConfiguration(const Configuration &configuration)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    m_configuration = configuration;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::update(const InMemoryInfo &info)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_updateIsRunning);
 | 
			
		||||
    updateHelper(info);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BaseEditorDocumentParser::State BaseEditorDocumentParser::state() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    return m_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::setState(const State &state)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    m_state = state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ProjectPart::Ptr BaseEditorDocumentParser::projectPart() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    return m_projectPart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::setProjectPart(ProjectPart::Ptr projectPart)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    m_manuallySetProjectPart = projectPart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BaseEditorDocumentParser::usePrecompiledHeaders() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    return m_usePrecompiledHeaders;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::setUsePrecompiledHeaders(bool usePrecompiledHeaders)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    m_usePrecompiledHeaders = usePrecompiledHeaders;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QByteArray BaseEditorDocumentParser::editorDefines() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    return m_editorDefines;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::setEditorDefines(const QByteArray &editorDefines)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
 | 
			
		||||
    if (editorDefines != m_editorDefines) {
 | 
			
		||||
        m_editorDefines = editorDefines;
 | 
			
		||||
        m_editorDefinesChangedSinceLastUpdate = true;
 | 
			
		||||
    }
 | 
			
		||||
    return state().projectPart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
 | 
			
		||||
@@ -115,43 +114,44 @@ BaseEditorDocumentParser *BaseEditorDocumentParser::get(const QString &filePath)
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::updateProjectPart()
 | 
			
		||||
ProjectPart::Ptr BaseEditorDocumentParser::determineProjectPart(const QString &filePath,
 | 
			
		||||
                                                                const Configuration &config,
 | 
			
		||||
                                                                const State &state)
 | 
			
		||||
{
 | 
			
		||||
    if (m_manuallySetProjectPart) {
 | 
			
		||||
        m_projectPart = m_manuallySetProjectPart;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    if (config.manuallySetProjectPart)
 | 
			
		||||
        return config.manuallySetProjectPart;
 | 
			
		||||
 | 
			
		||||
    ProjectPart::Ptr projectPart = state.projectPart;
 | 
			
		||||
 | 
			
		||||
    CppModelManager *cmm = CppModelManager::instance();
 | 
			
		||||
    QList<ProjectPart::Ptr> projectParts = cmm->projectPart(m_filePath);
 | 
			
		||||
    QList<ProjectPart::Ptr> projectParts = cmm->projectPart(filePath);
 | 
			
		||||
    if (projectParts.isEmpty()) {
 | 
			
		||||
        if (m_projectPart)
 | 
			
		||||
        if (projectPart)
 | 
			
		||||
            // File is not directly part of any project, but we got one before. We will re-use it,
 | 
			
		||||
            // because re-calculating this can be expensive when the dependency table is big.
 | 
			
		||||
            return;
 | 
			
		||||
            return projectPart;
 | 
			
		||||
 | 
			
		||||
        // Fall-back step 1: Get some parts through the dependency table:
 | 
			
		||||
        projectParts = cmm->projectPartFromDependencies(Utils::FileName::fromString(m_filePath));
 | 
			
		||||
        projectParts = cmm->projectPartFromDependencies(Utils::FileName::fromString(filePath));
 | 
			
		||||
        if (projectParts.isEmpty())
 | 
			
		||||
            // Fall-back step 2: Use fall-back part from the model manager:
 | 
			
		||||
            m_projectPart = cmm->fallbackProjectPart();
 | 
			
		||||
            projectPart = cmm->fallbackProjectPart();
 | 
			
		||||
        else
 | 
			
		||||
            m_projectPart = projectParts.first();
 | 
			
		||||
            projectPart = projectParts.first();
 | 
			
		||||
    } else {
 | 
			
		||||
        if (!projectParts.contains(m_projectPart))
 | 
			
		||||
        if (!projectParts.contains(projectPart))
 | 
			
		||||
            // Apparently the project file changed, so update our project part.
 | 
			
		||||
            m_projectPart = projectParts.first();
 | 
			
		||||
            projectPart = projectParts.first();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return projectPart;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BaseEditorDocumentParser::editorDefinesChanged() const
 | 
			
		||||
BaseEditorDocumentParser::InMemoryInfo::InMemoryInfo(bool withModifiedFiles)
 | 
			
		||||
    : workingCopy(CppTools::CppModelManager::instance()->workingCopy())
 | 
			
		||||
{
 | 
			
		||||
    return m_editorDefinesChangedSinceLastUpdate;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentParser::resetEditorDefinesChanged()
 | 
			
		||||
{
 | 
			
		||||
    m_editorDefinesChangedSinceLastUpdate = false;
 | 
			
		||||
    if (withModifiedFiles)
 | 
			
		||||
        modifiedFiles = CppTools::modifiedFiles();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // namespace CppTools
 | 
			
		||||
 
 | 
			
		||||
@@ -33,6 +33,7 @@
 | 
			
		||||
 | 
			
		||||
#include "cppmodelmanager.h"
 | 
			
		||||
#include "cpptools_global.h"
 | 
			
		||||
#include "cppworkingcopy.h"
 | 
			
		||||
 | 
			
		||||
#include <QObject>
 | 
			
		||||
 | 
			
		||||
@@ -42,45 +43,54 @@ class CPPTOOLS_EXPORT BaseEditorDocumentParser : public QObject
 | 
			
		||||
{
 | 
			
		||||
    Q_OBJECT
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static BaseEditorDocumentParser *get(const QString &filePath);
 | 
			
		||||
 | 
			
		||||
    struct Configuration {
 | 
			
		||||
        bool usePrecompiledHeaders = false;
 | 
			
		||||
        QByteArray editorDefines;
 | 
			
		||||
        ProjectPart::Ptr manuallySetProjectPart;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    BaseEditorDocumentParser(const QString &filePath);
 | 
			
		||||
    virtual ~BaseEditorDocumentParser();
 | 
			
		||||
 | 
			
		||||
    QString filePath() const;
 | 
			
		||||
    Configuration configuration() const;
 | 
			
		||||
    void setConfiguration(const Configuration &configuration);
 | 
			
		||||
 | 
			
		||||
    virtual void update(WorkingCopy workingCopy) = 0;
 | 
			
		||||
    struct CPPTOOLS_EXPORT InMemoryInfo {
 | 
			
		||||
        InMemoryInfo(bool withModifiedFiles);
 | 
			
		||||
 | 
			
		||||
        WorkingCopy workingCopy;
 | 
			
		||||
        Utils::FileNameList modifiedFiles;
 | 
			
		||||
    };
 | 
			
		||||
    void update(const InMemoryInfo &info);
 | 
			
		||||
 | 
			
		||||
    ProjectPart::Ptr projectPart() const;
 | 
			
		||||
    void setProjectPart(ProjectPart::Ptr projectPart);
 | 
			
		||||
 | 
			
		||||
    bool usePrecompiledHeaders() const;
 | 
			
		||||
    void setUsePrecompiledHeaders(bool usePrecompiledHeaders);
 | 
			
		||||
 | 
			
		||||
    QByteArray editorDefines() const;
 | 
			
		||||
    void setEditorDefines(const QByteArray &editorDefines);
 | 
			
		||||
 | 
			
		||||
public:
 | 
			
		||||
    static BaseEditorDocumentParser *get(const QString &filePath);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    void updateProjectPart();
 | 
			
		||||
    struct State {
 | 
			
		||||
        QByteArray editorDefines;
 | 
			
		||||
        ProjectPart::Ptr projectPart;
 | 
			
		||||
    };
 | 
			
		||||
    State state() const;
 | 
			
		||||
    void setState(const State &state);
 | 
			
		||||
 | 
			
		||||
    bool editorDefinesChanged() const;
 | 
			
		||||
    void resetEditorDefinesChanged();
 | 
			
		||||
    static ProjectPart::Ptr determineProjectPart(const QString &filePath,
 | 
			
		||||
                                                 const Configuration &config,
 | 
			
		||||
                                                 const State &state);
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
    mutable QMutex m_mutex;
 | 
			
		||||
    mutable QMutex m_stateAndConfigurationMutex;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    virtual void updateHelper(const InMemoryInfo &inMemoryInfo) = 0;
 | 
			
		||||
 | 
			
		||||
    const QString m_filePath;
 | 
			
		||||
 | 
			
		||||
    ProjectPart::Ptr m_projectPart;
 | 
			
		||||
    ProjectPart::Ptr m_manuallySetProjectPart;
 | 
			
		||||
 | 
			
		||||
    bool m_usePrecompiledHeaders;
 | 
			
		||||
 | 
			
		||||
    QByteArray m_editorDefines;
 | 
			
		||||
    bool m_editorDefinesChangedSinceLastUpdate;
 | 
			
		||||
    Configuration m_configuration;
 | 
			
		||||
    State m_state;
 | 
			
		||||
    mutable QMutex m_updateIsRunning;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace CppTools
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
#include "baseeditordocumentprocessor.h"
 | 
			
		||||
#include "cppworkingcopy.h"
 | 
			
		||||
 | 
			
		||||
#include "cpptoolsreuse.h"
 | 
			
		||||
#include "editordocumenthandle.h"
 | 
			
		||||
 | 
			
		||||
#include <utils/qtcassert.h>
 | 
			
		||||
@@ -118,7 +119,7 @@ QList<QTextEdit::ExtraSelection> BaseEditorDocumentProcessor::toTextEditorSelect
 | 
			
		||||
 | 
			
		||||
void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
 | 
			
		||||
                                            BaseEditorDocumentParser *parser,
 | 
			
		||||
                                            WorkingCopy workingCopy)
 | 
			
		||||
                                            BaseEditorDocumentParser::InMemoryInfo info)
 | 
			
		||||
{
 | 
			
		||||
    future.setProgressRange(0, 1);
 | 
			
		||||
    if (future.isCanceled()) {
 | 
			
		||||
@@ -126,7 +127,7 @@ void BaseEditorDocumentProcessor::runParser(QFutureInterface<void> &future,
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    parser->update(workingCopy);
 | 
			
		||||
    parser->update(info);
 | 
			
		||||
    CppModelManager::instance()
 | 
			
		||||
        ->finishedRefreshingSourceFiles(QSet<QString>() << parser->filePath());
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -86,7 +86,7 @@ protected:
 | 
			
		||||
 | 
			
		||||
    static void runParser(QFutureInterface<void> &future,
 | 
			
		||||
                          CppTools::BaseEditorDocumentParser *parser,
 | 
			
		||||
                          CppTools::WorkingCopy workingCopy);
 | 
			
		||||
                          BaseEditorDocumentParser::InMemoryInfo info);
 | 
			
		||||
 | 
			
		||||
    // Convenience
 | 
			
		||||
    QString filePath() const { return m_baseTextDocument->filePath().toString(); }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,19 +40,22 @@ using namespace CppTools::Internal;
 | 
			
		||||
 | 
			
		||||
BuiltinEditorDocumentParser::BuiltinEditorDocumentParser(const QString &filePath)
 | 
			
		||||
    : BaseEditorDocumentParser(filePath)
 | 
			
		||||
    , m_forceSnapshotInvalidation(false)
 | 
			
		||||
    , m_releaseSourceAndAST(true)
 | 
			
		||||
{
 | 
			
		||||
    qRegisterMetaType<CPlusPlus::Snapshot>("CPlusPlus::Snapshot");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
 | 
			
		||||
void BuiltinEditorDocumentParser::updateHelper(const InMemoryInfo &info)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
 | 
			
		||||
    if (filePath().isEmpty())
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    const Configuration baseConfig = configuration();
 | 
			
		||||
    const bool releaseSourceAndAST_ = releaseSourceAndAST();
 | 
			
		||||
 | 
			
		||||
    State baseState = state();
 | 
			
		||||
    ExtraState state = extraState();
 | 
			
		||||
    WorkingCopy workingCopy = info.workingCopy;
 | 
			
		||||
 | 
			
		||||
    bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged_ = false;
 | 
			
		||||
 | 
			
		||||
    CppModelManager *modelManager = CppModelManager::instance();
 | 
			
		||||
@@ -62,52 +65,52 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
 | 
			
		||||
    QString projectConfigFile;
 | 
			
		||||
    LanguageFeatures features = LanguageFeatures::defaultFeatures();
 | 
			
		||||
 | 
			
		||||
    updateProjectPart();
 | 
			
		||||
    baseState.projectPart = determineProjectPart(filePath(), baseConfig, baseState);
 | 
			
		||||
 | 
			
		||||
    if (m_forceSnapshotInvalidation) {
 | 
			
		||||
    if (state.forceSnapshotInvalidation) {
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
        m_forceSnapshotInvalidation = false;
 | 
			
		||||
        state.forceSnapshotInvalidation = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (const ProjectPart::Ptr part = projectPart()) {
 | 
			
		||||
    if (const ProjectPart::Ptr part = baseState.projectPart) {
 | 
			
		||||
        configFile += part->toolchainDefines;
 | 
			
		||||
        configFile += part->projectDefines;
 | 
			
		||||
        headerPaths = part->headerPaths;
 | 
			
		||||
        projectConfigFile = part->projectConfigFile;
 | 
			
		||||
        if (usePrecompiledHeaders())
 | 
			
		||||
        if (baseConfig.usePrecompiledHeaders)
 | 
			
		||||
            precompiledHeaders = part->precompiledHeaders;
 | 
			
		||||
        features = part->languageFeatures;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (configFile != m_configFile) {
 | 
			
		||||
        m_configFile = configFile;
 | 
			
		||||
    if (configFile != state.configFile) {
 | 
			
		||||
        state.configFile = configFile;
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
        invalidateConfig = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (editorDefinesChanged()) {
 | 
			
		||||
    if (baseConfig.editorDefines != baseState.editorDefines) {
 | 
			
		||||
        baseState.editorDefines = baseConfig.editorDefines;
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
        editorDefinesChanged_ = true;
 | 
			
		||||
        resetEditorDefinesChanged();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (headerPaths != m_headerPaths) {
 | 
			
		||||
        m_headerPaths = headerPaths;
 | 
			
		||||
    if (headerPaths != state.headerPaths) {
 | 
			
		||||
        state.headerPaths = headerPaths;
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (projectConfigFile != m_projectConfigFile) {
 | 
			
		||||
        m_projectConfigFile = projectConfigFile;
 | 
			
		||||
    if (projectConfigFile != state.projectConfigFile) {
 | 
			
		||||
        state.projectConfigFile = projectConfigFile;
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (precompiledHeaders != m_precompiledHeaders) {
 | 
			
		||||
        m_precompiledHeaders = precompiledHeaders;
 | 
			
		||||
    if (precompiledHeaders != state.precompiledHeaders) {
 | 
			
		||||
        state.precompiledHeaders = precompiledHeaders;
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    unsigned rev = 0;
 | 
			
		||||
    if (Document::Ptr doc = document())
 | 
			
		||||
    if (Document::Ptr doc = state.snapshot.document(filePath()))
 | 
			
		||||
        rev = doc->revision();
 | 
			
		||||
    else
 | 
			
		||||
        invalidateSnapshot = true;
 | 
			
		||||
@@ -115,26 +118,26 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
 | 
			
		||||
    Snapshot globalSnapshot = modelManager->snapshot();
 | 
			
		||||
 | 
			
		||||
    if (invalidateSnapshot) {
 | 
			
		||||
        m_snapshot = Snapshot();
 | 
			
		||||
        state.snapshot = Snapshot();
 | 
			
		||||
    } else {
 | 
			
		||||
        // Remove changed files from the snapshot
 | 
			
		||||
        QSet<Utils::FileName> toRemove;
 | 
			
		||||
        foreach (const Document::Ptr &doc, m_snapshot) {
 | 
			
		||||
        foreach (const Document::Ptr &doc, state.snapshot) {
 | 
			
		||||
            const Utils::FileName fileName = Utils::FileName::fromString(doc->fileName());
 | 
			
		||||
            if (workingCopy.contains(fileName)) {
 | 
			
		||||
                if (workingCopy.get(fileName).second != doc->editorRevision())
 | 
			
		||||
                    addFileAndDependencies(&toRemove, fileName);
 | 
			
		||||
                    addFileAndDependencies(&state.snapshot, &toRemove, fileName);
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            Document::Ptr otherDoc = globalSnapshot.document(fileName);
 | 
			
		||||
            if (!otherDoc.isNull() && otherDoc->revision() != doc->revision())
 | 
			
		||||
                addFileAndDependencies(&toRemove, fileName);
 | 
			
		||||
                addFileAndDependencies(&state.snapshot, &toRemove, fileName);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (!toRemove.isEmpty()) {
 | 
			
		||||
            invalidateSnapshot = true;
 | 
			
		||||
            foreach (const Utils::FileName &fileName, toRemove)
 | 
			
		||||
                m_snapshot.remove(fileName);
 | 
			
		||||
                state.snapshot.remove(fileName);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -142,19 +145,19 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
 | 
			
		||||
    if (invalidateSnapshot) {
 | 
			
		||||
        const QString configurationFileName = modelManager->configurationFileName();
 | 
			
		||||
        if (invalidateConfig)
 | 
			
		||||
            m_snapshot.remove(configurationFileName);
 | 
			
		||||
        if (!m_snapshot.contains(configurationFileName))
 | 
			
		||||
            workingCopy.insert(configurationFileName, m_configFile);
 | 
			
		||||
        m_snapshot.remove(filePath());
 | 
			
		||||
            state.snapshot.remove(configurationFileName);
 | 
			
		||||
        if (!state.snapshot.contains(configurationFileName))
 | 
			
		||||
            workingCopy.insert(configurationFileName, state.configFile);
 | 
			
		||||
        state.snapshot.remove(filePath());
 | 
			
		||||
 | 
			
		||||
        static const QString editorDefinesFileName
 | 
			
		||||
            = CppModelManager::editorConfigurationFileName();
 | 
			
		||||
        if (editorDefinesChanged_) {
 | 
			
		||||
            m_snapshot.remove(editorDefinesFileName);
 | 
			
		||||
            workingCopy.insert(editorDefinesFileName, editorDefines());
 | 
			
		||||
            state.snapshot.remove(editorDefinesFileName);
 | 
			
		||||
            workingCopy.insert(editorDefinesFileName, baseState.editorDefines);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        CppSourceProcessor sourceProcessor(m_snapshot, [&](const Document::Ptr &doc) {
 | 
			
		||||
        CppSourceProcessor sourceProcessor(state.snapshot, [&](const Document::Ptr &doc) {
 | 
			
		||||
            const QString fileName = doc->fileName();
 | 
			
		||||
            const bool isInEditor = fileName == filePath();
 | 
			
		||||
            Document::Ptr otherDoc = modelManager->document(fileName);
 | 
			
		||||
@@ -163,68 +166,64 @@ void BuiltinEditorDocumentParser::update(WorkingCopy workingCopy)
 | 
			
		||||
                newRev = qMax(rev + 1, newRev);
 | 
			
		||||
            doc->setRevision(newRev);
 | 
			
		||||
            modelManager->emitDocumentUpdated(doc);
 | 
			
		||||
            if (m_releaseSourceAndAST)
 | 
			
		||||
            if (releaseSourceAndAST_)
 | 
			
		||||
                doc->releaseSourceAndAST();
 | 
			
		||||
        });
 | 
			
		||||
        Snapshot globalSnapshot = modelManager->snapshot();
 | 
			
		||||
        globalSnapshot.remove(filePath());
 | 
			
		||||
        sourceProcessor.setGlobalSnapshot(globalSnapshot);
 | 
			
		||||
        sourceProcessor.setWorkingCopy(workingCopy);
 | 
			
		||||
        sourceProcessor.setHeaderPaths(m_headerPaths);
 | 
			
		||||
        sourceProcessor.setHeaderPaths(state.headerPaths);
 | 
			
		||||
        sourceProcessor.setLanguageFeatures(features);
 | 
			
		||||
        sourceProcessor.run(configurationFileName);
 | 
			
		||||
        if (!m_projectConfigFile.isEmpty())
 | 
			
		||||
            sourceProcessor.run(m_projectConfigFile);
 | 
			
		||||
        if (usePrecompiledHeaders()) {
 | 
			
		||||
            foreach (const QString &precompiledHeader, m_precompiledHeaders)
 | 
			
		||||
        if (!state.projectConfigFile.isEmpty())
 | 
			
		||||
            sourceProcessor.run(state.projectConfigFile);
 | 
			
		||||
        if (baseConfig.usePrecompiledHeaders) {
 | 
			
		||||
            foreach (const QString &precompiledHeader, state.precompiledHeaders)
 | 
			
		||||
                sourceProcessor.run(precompiledHeader);
 | 
			
		||||
        }
 | 
			
		||||
        if (!editorDefines().isEmpty())
 | 
			
		||||
        if (!baseState.editorDefines.isEmpty())
 | 
			
		||||
            sourceProcessor.run(editorDefinesFileName);
 | 
			
		||||
        sourceProcessor.run(filePath(), usePrecompiledHeaders() ? m_precompiledHeaders
 | 
			
		||||
                                                                    : QStringList());
 | 
			
		||||
        m_snapshot = sourceProcessor.snapshot();
 | 
			
		||||
        Snapshot newSnapshot = m_snapshot.simplified(document());
 | 
			
		||||
        for (Snapshot::const_iterator i = m_snapshot.begin(), ei = m_snapshot.end(); i != ei; ++i) {
 | 
			
		||||
        sourceProcessor.run(filePath(), baseConfig.usePrecompiledHeaders ? state.precompiledHeaders
 | 
			
		||||
                                                                         : QStringList());
 | 
			
		||||
        state.snapshot = sourceProcessor.snapshot();
 | 
			
		||||
        Snapshot newSnapshot = state.snapshot.simplified(state.snapshot.document(filePath()));
 | 
			
		||||
        for (Snapshot::const_iterator i = state.snapshot.begin(), ei = state.snapshot.end(); i != ei; ++i) {
 | 
			
		||||
            if (Client::isInjectedFile(i.key().toString()))
 | 
			
		||||
                newSnapshot.insert(i.value());
 | 
			
		||||
        }
 | 
			
		||||
        m_snapshot = newSnapshot;
 | 
			
		||||
        m_snapshot.updateDependencyTable();
 | 
			
		||||
 | 
			
		||||
        emit finished(document(), m_snapshot);
 | 
			
		||||
        state.snapshot = newSnapshot;
 | 
			
		||||
        state.snapshot.updateDependencyTable();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    setState(baseState);
 | 
			
		||||
    setExtraState(state);
 | 
			
		||||
 | 
			
		||||
    if (invalidateSnapshot)
 | 
			
		||||
        emit finished(state.snapshot.document(filePath()), state.snapshot);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentParser::releaseResources()
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    m_snapshot = Snapshot();
 | 
			
		||||
    m_forceSnapshotInvalidation = true;
 | 
			
		||||
    ExtraState s = extraState();
 | 
			
		||||
    s.snapshot = Snapshot();
 | 
			
		||||
    s.forceSnapshotInvalidation = true;
 | 
			
		||||
    setExtraState(s);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Document::Ptr BuiltinEditorDocumentParser::document() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    return m_snapshot.document(filePath());
 | 
			
		||||
    return extraState().snapshot.document(filePath());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Snapshot BuiltinEditorDocumentParser::snapshot() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    return m_snapshot;
 | 
			
		||||
    return extraState().snapshot;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ProjectPart::HeaderPaths BuiltinEditorDocumentParser::headerPaths() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    return m_headerPaths;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentParser::setReleaseSourceAndAST(bool onoff)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_mutex);
 | 
			
		||||
    m_releaseSourceAndAST = onoff;
 | 
			
		||||
    return extraState().headerPaths;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &filePath)
 | 
			
		||||
@@ -234,12 +233,39 @@ BuiltinEditorDocumentParser *BuiltinEditorDocumentParser::get(const QString &fil
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentParser::addFileAndDependencies(QSet<Utils::FileName> *toRemove,
 | 
			
		||||
void BuiltinEditorDocumentParser::addFileAndDependencies(Snapshot *snapshot,
 | 
			
		||||
                                                         QSet<Utils::FileName> *toRemove,
 | 
			
		||||
                                                         const Utils::FileName &fileName) const
 | 
			
		||||
{
 | 
			
		||||
    QTC_ASSERT(snapshot, return);
 | 
			
		||||
 | 
			
		||||
    toRemove->insert(fileName);
 | 
			
		||||
    if (fileName != Utils::FileName::fromString(filePath())) {
 | 
			
		||||
        Utils::FileNameList deps = m_snapshot.filesDependingOn(fileName);
 | 
			
		||||
        Utils::FileNameList deps = snapshot->filesDependingOn(fileName);
 | 
			
		||||
        toRemove->unite(QSet<Utils::FileName>::fromList(deps));
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BuiltinEditorDocumentParser::ExtraState BuiltinEditorDocumentParser::extraState() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    return m_extraState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentParser::setExtraState(const ExtraState &extraState)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    m_extraState = extraState;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool BuiltinEditorDocumentParser::releaseSourceAndAST() const
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    return m_releaseSourceAndAST;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentParser::setReleaseSourceAndAST(bool release)
 | 
			
		||||
{
 | 
			
		||||
    QMutexLocker locker(&m_stateAndConfigurationMutex);
 | 
			
		||||
    m_releaseSourceAndAST = release;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -37,7 +37,6 @@
 | 
			
		||||
 | 
			
		||||
#include <cplusplus/CppDocument.h>
 | 
			
		||||
 | 
			
		||||
#include <QMutex>
 | 
			
		||||
#include <QString>
 | 
			
		||||
 | 
			
		||||
namespace CppTools {
 | 
			
		||||
@@ -49,14 +48,14 @@ class CPPTOOLS_EXPORT BuiltinEditorDocumentParser : public BaseEditorDocumentPar
 | 
			
		||||
public:
 | 
			
		||||
    BuiltinEditorDocumentParser(const QString &filePath);
 | 
			
		||||
 | 
			
		||||
    void update(WorkingCopy workingCopy) override;
 | 
			
		||||
    void releaseResources();
 | 
			
		||||
    bool releaseSourceAndAST() const;
 | 
			
		||||
    void setReleaseSourceAndAST(bool release);
 | 
			
		||||
 | 
			
		||||
    CPlusPlus::Document::Ptr document() const;
 | 
			
		||||
    CPlusPlus::Snapshot snapshot() const;
 | 
			
		||||
    ProjectPart::HeaderPaths headerPaths() const;
 | 
			
		||||
 | 
			
		||||
    void setReleaseSourceAndAST(bool onoff);
 | 
			
		||||
    void releaseResources();
 | 
			
		||||
 | 
			
		||||
signals:
 | 
			
		||||
    void finished(CPlusPlus::Document::Ptr document, CPlusPlus::Snapshot snapshot);
 | 
			
		||||
@@ -65,18 +64,26 @@ public:
 | 
			
		||||
    static BuiltinEditorDocumentParser *get(const QString &filePath);
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void addFileAndDependencies(QSet<Utils::FileName> *toRemove, const Utils::FileName &fileName) const;
 | 
			
		||||
    void updateHelper(const InMemoryInfo &info) override;
 | 
			
		||||
    void addFileAndDependencies(CPlusPlus::Snapshot *snapshot,
 | 
			
		||||
                                QSet<Utils::FileName> *toRemove,
 | 
			
		||||
                                const Utils::FileName &fileName) const;
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    QByteArray m_configFile;
 | 
			
		||||
    struct ExtraState {
 | 
			
		||||
        QByteArray configFile;
 | 
			
		||||
 | 
			
		||||
    ProjectPart::HeaderPaths m_headerPaths;
 | 
			
		||||
    QString m_projectConfigFile;
 | 
			
		||||
    QStringList m_precompiledHeaders;
 | 
			
		||||
        ProjectPart::HeaderPaths headerPaths;
 | 
			
		||||
        QString projectConfigFile;
 | 
			
		||||
        QStringList precompiledHeaders;
 | 
			
		||||
 | 
			
		||||
    CPlusPlus::Snapshot m_snapshot;
 | 
			
		||||
    bool m_forceSnapshotInvalidation;
 | 
			
		||||
    bool m_releaseSourceAndAST;
 | 
			
		||||
        CPlusPlus::Snapshot snapshot;
 | 
			
		||||
        bool forceSnapshotInvalidation = false;
 | 
			
		||||
    };
 | 
			
		||||
    ExtraState extraState() const;
 | 
			
		||||
    void setExtraState(const ExtraState &extraState);
 | 
			
		||||
 | 
			
		||||
    bool m_releaseSourceAndAST = true;
 | 
			
		||||
    ExtraState m_extraState;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
} // namespace CppTools
 | 
			
		||||
 
 | 
			
		||||
@@ -43,8 +43,8 @@
 | 
			
		||||
#include <cplusplus/CppDocument.h>
 | 
			
		||||
#include <cplusplus/SimpleLexer.h>
 | 
			
		||||
 | 
			
		||||
#include <utils/QtConcurrentTools>
 | 
			
		||||
#include <utils/qtcassert.h>
 | 
			
		||||
#include <utils/runextensions.h>
 | 
			
		||||
 | 
			
		||||
#include <QLoggingCategory>
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +134,10 @@ BuiltinEditorDocumentProcessor::BuiltinEditorDocumentProcessor(
 | 
			
		||||
    using namespace Internal;
 | 
			
		||||
 | 
			
		||||
    QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings();
 | 
			
		||||
    m_parser.setUsePrecompiledHeaders(cms->pchUsage() != CppCodeModelSettings::PchUse_None);
 | 
			
		||||
 | 
			
		||||
    BaseEditorDocumentParser::Configuration config = m_parser.configuration();
 | 
			
		||||
    config.usePrecompiledHeaders = cms->pchUsage() != CppCodeModelSettings::PchUse_None;
 | 
			
		||||
    m_parser.setConfiguration(config);
 | 
			
		||||
 | 
			
		||||
    if (m_semanticHighlighter) {
 | 
			
		||||
        m_semanticHighlighter->setHighlightingRunner(
 | 
			
		||||
@@ -163,7 +166,9 @@ BuiltinEditorDocumentProcessor::~BuiltinEditorDocumentProcessor()
 | 
			
		||||
 | 
			
		||||
void BuiltinEditorDocumentProcessor::run()
 | 
			
		||||
{
 | 
			
		||||
    m_parserFuture = QtConcurrent::run(&runParser, parser(), CppTools::CppModelManager::instance()->workingCopy());
 | 
			
		||||
    m_parserFuture = QtConcurrent::run(&runParser,
 | 
			
		||||
                                       parser(),
 | 
			
		||||
                                       BuiltinEditorDocumentParser::InMemoryInfo(false));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
BaseEditorDocumentParser *BuiltinEditorDocumentProcessor::parser()
 | 
			
		||||
 
 | 
			
		||||
@@ -162,7 +162,7 @@ void indexFindErrors(QFutureInterface<void> &future, const ParseParams params)
 | 
			
		||||
        // Parse the file as precisely as possible
 | 
			
		||||
        BuiltinEditorDocumentParser parser(file);
 | 
			
		||||
        parser.setReleaseSourceAndAST(false);
 | 
			
		||||
        parser.update(params.workingCopy);
 | 
			
		||||
        parser.update(BuiltinEditorDocumentParser::InMemoryInfo(false));
 | 
			
		||||
        CPlusPlus::Document::Ptr document = parser.document();
 | 
			
		||||
        QTC_ASSERT(document, return);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -2188,7 +2188,7 @@ void CppCompletionAssistInterface::getCppSpecifics() const
 | 
			
		||||
    m_gotCppSpecifics = true;
 | 
			
		||||
 | 
			
		||||
    if (BuiltinEditorDocumentParser *parser = BuiltinEditorDocumentParser::get(fileName())) {
 | 
			
		||||
        parser->update(m_workingCopy);
 | 
			
		||||
        parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
 | 
			
		||||
        m_snapshot = parser->snapshot();
 | 
			
		||||
        m_headerPaths = parser->headerPaths();
 | 
			
		||||
        if (Document::Ptr document = parser->document())
 | 
			
		||||
 
 | 
			
		||||
@@ -167,13 +167,11 @@ private:
 | 
			
		||||
    const QString &m_filePath;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void waitForProcessedEditorDocument(const QString &filePath)
 | 
			
		||||
ProjectPart::Ptr projectPartOfEditorDocument(const QString &filePath)
 | 
			
		||||
{
 | 
			
		||||
    CppEditorDocumentHandle *editorDocument
 | 
			
		||||
            = CppModelManager::instance()->cppEditorDocument(filePath);
 | 
			
		||||
    QVERIFY(editorDocument);
 | 
			
		||||
    while (editorDocument->processor()->isParserRunning())
 | 
			
		||||
        QCoreApplication::processEvents();
 | 
			
		||||
    auto *editorDocument = CppModelManager::instance()->cppEditorDocument(filePath);
 | 
			
		||||
    QTC_ASSERT(editorDocument, return ProjectPart::Ptr());
 | 
			
		||||
    return editorDocument->processor()->parser()->projectPart();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // anonymous namespace
 | 
			
		||||
@@ -914,8 +912,10 @@ void CppToolsPlugin::test_modelmanager_precompiled_headers()
 | 
			
		||||
 | 
			
		||||
        auto *parser = BuiltinEditorDocumentParser::get(fileName);
 | 
			
		||||
        QVERIFY(parser);
 | 
			
		||||
        parser->setUsePrecompiledHeaders(true);
 | 
			
		||||
        parser->update(mm->workingCopy());
 | 
			
		||||
        BaseEditorDocumentParser::Configuration config = parser->configuration();
 | 
			
		||||
        config.usePrecompiledHeaders = true;
 | 
			
		||||
        parser->setConfiguration(config);
 | 
			
		||||
        parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
 | 
			
		||||
 | 
			
		||||
        // Check if defines from pch are considered
 | 
			
		||||
        Document::Ptr document = mm->document(fileName);
 | 
			
		||||
@@ -995,8 +995,10 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
 | 
			
		||||
 | 
			
		||||
        const QString filePath = editor->document()->filePath().toString();
 | 
			
		||||
        BaseEditorDocumentParser *parser = BaseEditorDocumentParser::get(filePath);
 | 
			
		||||
        parser->setEditorDefines(editorDefines.toUtf8());
 | 
			
		||||
        parser->update(mm->workingCopy());
 | 
			
		||||
        BaseEditorDocumentParser::Configuration config = parser->configuration();
 | 
			
		||||
        config.editorDefines = editorDefines.toUtf8();
 | 
			
		||||
        parser->setConfiguration(config);
 | 
			
		||||
        parser->update(BuiltinEditorDocumentParser::InMemoryInfo(false));
 | 
			
		||||
 | 
			
		||||
        Document::Ptr doc = mm->document(main1File);
 | 
			
		||||
        QCOMPARE(nameOfFirstDeclaration(doc), firstDeclarationName);
 | 
			
		||||
@@ -1006,7 +1008,6 @@ void CppToolsPlugin::test_modelmanager_defines_per_editor()
 | 
			
		||||
void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
 | 
			
		||||
{
 | 
			
		||||
    ModelManagerTestHelper helper;
 | 
			
		||||
    CppModelManager *mm = CppModelManager::instance();
 | 
			
		||||
 | 
			
		||||
    MyTestDataDir testDataDirectory(_("testdata_defines"));
 | 
			
		||||
    const QString fileA = testDataDirectory.file(_("main1.cpp")); // content not relevant
 | 
			
		||||
@@ -1017,10 +1018,8 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
 | 
			
		||||
    QVERIFY(editorA);
 | 
			
		||||
    EditorCloser closerA(editorA);
 | 
			
		||||
    QCOMPARE(Core::DocumentModel::openedDocuments().size(), 1);
 | 
			
		||||
 | 
			
		||||
    CppEditorDocumentHandle *editorDocumentA = mm->cppEditorDocument(fileA);
 | 
			
		||||
    QVERIFY(editorDocumentA);
 | 
			
		||||
    ProjectPart::Ptr documentAProjectPart = editorDocumentA->processor()->parser()->projectPart();
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(fileA));
 | 
			
		||||
    ProjectPart::Ptr documentAProjectPart = projectPartOfEditorDocument(fileA);
 | 
			
		||||
    QVERIFY(!documentAProjectPart->project);
 | 
			
		||||
 | 
			
		||||
    // Open file B in editor
 | 
			
		||||
@@ -1028,10 +1027,8 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
 | 
			
		||||
    QVERIFY(editorB);
 | 
			
		||||
    EditorCloser closerB(editorB);
 | 
			
		||||
    QCOMPARE(Core::DocumentModel::openedDocuments().size(), 2);
 | 
			
		||||
 | 
			
		||||
    CppEditorDocumentHandle *editorDocumentB = mm->cppEditorDocument(fileB);
 | 
			
		||||
    QVERIFY(editorDocumentB);
 | 
			
		||||
    ProjectPart::Ptr documentBProjectPart = editorDocumentB->processor()->parser()->projectPart();
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(fileB));
 | 
			
		||||
    ProjectPart::Ptr documentBProjectPart = projectPartOfEditorDocument(fileB);
 | 
			
		||||
    QVERIFY(!documentBProjectPart->project);
 | 
			
		||||
 | 
			
		||||
    // Switch back to document A
 | 
			
		||||
@@ -1053,16 +1050,14 @@ void CppToolsPlugin::test_modelmanager_updateEditorsAfterProjectUpdate()
 | 
			
		||||
    helper.updateProjectInfo(pi);
 | 
			
		||||
 | 
			
		||||
    // ... and check for updated editor document A
 | 
			
		||||
    while (editorDocumentA->processor()->isParserRunning())
 | 
			
		||||
        QCoreApplication::processEvents();
 | 
			
		||||
    documentAProjectPart = editorDocumentA->processor()->parser()->projectPart();
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(fileA));
 | 
			
		||||
    documentAProjectPart = projectPartOfEditorDocument(fileA);
 | 
			
		||||
    QCOMPARE(documentAProjectPart->project, project);
 | 
			
		||||
 | 
			
		||||
    // Switch back to document B and check if that's updated, too
 | 
			
		||||
    Core::EditorManager::activateEditor(editorB);
 | 
			
		||||
    while (editorDocumentB->processor()->isParserRunning())
 | 
			
		||||
        QCoreApplication::processEvents();
 | 
			
		||||
    documentBProjectPart = editorDocumentB->processor()->parser()->projectPart();
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(fileB));
 | 
			
		||||
    documentBProjectPart = projectPartOfEditorDocument(fileB);
 | 
			
		||||
    QCOMPARE(documentBProjectPart->project, project);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -1131,7 +1126,7 @@ void CppToolsPlugin::test_modelmanager_documentsAndRevisions()
 | 
			
		||||
    TextEditor::BaseTextEditor *editor1;
 | 
			
		||||
    QVERIFY(helper.openBaseTextEditor(filePath1, &editor1));
 | 
			
		||||
    helper.closeEditorAtEndOfTestCase(editor1);
 | 
			
		||||
    waitForProcessedEditorDocument(filePath1);
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(filePath1));
 | 
			
		||||
    VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 2U);
 | 
			
		||||
    VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 1U);
 | 
			
		||||
 | 
			
		||||
@@ -1144,7 +1139,7 @@ void CppToolsPlugin::test_modelmanager_documentsAndRevisions()
 | 
			
		||||
    TextEditor::BaseTextEditor *editor2;
 | 
			
		||||
    QVERIFY(helper.openBaseTextEditor(filePath2, &editor2));
 | 
			
		||||
    helper.closeEditorAtEndOfTestCase(editor2);
 | 
			
		||||
    waitForProcessedEditorDocument(filePath2);
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(filePath2));
 | 
			
		||||
    VERIFY_DOCUMENT_REVISION(modelManager->document(filePath1), 3U);
 | 
			
		||||
    VERIFY_DOCUMENT_REVISION(modelManager->document(filePath2), 3U);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -137,6 +137,7 @@ void CppToolsPlugin::test_cppsourceprocessor_includes_cyclic()
 | 
			
		||||
    const QString filePath = editor->document()->filePath().toString();
 | 
			
		||||
    auto *processor = BaseEditorDocumentProcessor::get(filePath);
 | 
			
		||||
    QVERIFY(processor);
 | 
			
		||||
    QVERIFY(TestCase::waitForProcessedEditorDocument(filePath));
 | 
			
		||||
    Snapshot snapshot = processor->snapshot();
 | 
			
		||||
    QCOMPARE(snapshot.size(), 3); // Configuration file included
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@
 | 
			
		||||
 | 
			
		||||
#include "cpptoolsplugin.h"
 | 
			
		||||
 | 
			
		||||
#include <coreplugin/documentmanager.h>
 | 
			
		||||
#include <coreplugin/editormanager/editormanager.h>
 | 
			
		||||
#include <coreplugin/idocument.h>
 | 
			
		||||
#include <texteditor/convenience.h>
 | 
			
		||||
@@ -287,4 +288,13 @@ bool skipFileDueToSizeLimit(const QFileInfo &fileInfo, int limitInMB)
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Utils::FileNameList modifiedFiles()
 | 
			
		||||
{
 | 
			
		||||
    Utils::FileNameList files;
 | 
			
		||||
    foreach (Core::IDocument *doc, Core::DocumentManager::modifiedDocuments())
 | 
			
		||||
        files.append(doc->filePath());
 | 
			
		||||
    files.removeDuplicates();
 | 
			
		||||
    return files;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
} // CppTools
 | 
			
		||||
 
 | 
			
		||||
@@ -44,6 +44,10 @@ class QStringRef;
 | 
			
		||||
class QTextCursor;
 | 
			
		||||
QT_END_NAMESPACE
 | 
			
		||||
 | 
			
		||||
namespace Utils {
 | 
			
		||||
class FileNameList;
 | 
			
		||||
} // namespace Utils
 | 
			
		||||
 | 
			
		||||
namespace CPlusPlus {
 | 
			
		||||
class Macro;
 | 
			
		||||
class Symbol;
 | 
			
		||||
@@ -52,6 +56,8 @@ class LookupContext;
 | 
			
		||||
 | 
			
		||||
namespace CppTools {
 | 
			
		||||
 | 
			
		||||
Utils::FileNameList CPPTOOLS_EXPORT modifiedFiles();
 | 
			
		||||
 | 
			
		||||
void CPPTOOLS_EXPORT moveCursorToEndOfIdentifier(QTextCursor *tc);
 | 
			
		||||
void CPPTOOLS_EXPORT moveCursorToStartOfIdentifier(QTextCursor *tc);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -29,6 +29,10 @@
 | 
			
		||||
****************************************************************************/
 | 
			
		||||
 | 
			
		||||
#include "cpptoolstestcase.h"
 | 
			
		||||
 | 
			
		||||
#include "baseeditordocumentparser.h"
 | 
			
		||||
#include "baseeditordocumentprocessor.h"
 | 
			
		||||
#include "editordocumenthandle.h"
 | 
			
		||||
#include "cppmodelmanager.h"
 | 
			
		||||
#include "cppworkingcopy.h"
 | 
			
		||||
 | 
			
		||||
@@ -140,6 +144,31 @@ bool TestCase::garbageCollectGlobalSnapshot()
 | 
			
		||||
    return globalSnapshot().isEmpty();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool waitForProcessedEditorDocument_internal(CppEditorDocumentHandle *editorDocument,
 | 
			
		||||
                                                    int timeOutInMs)
 | 
			
		||||
{
 | 
			
		||||
    QTC_ASSERT(editorDocument, return false);
 | 
			
		||||
 | 
			
		||||
    QTime timer;
 | 
			
		||||
    timer.start();
 | 
			
		||||
 | 
			
		||||
    forever {
 | 
			
		||||
        if (!editorDocument->processor()->isParserRunning())
 | 
			
		||||
            return true;
 | 
			
		||||
        if (timer.elapsed() > timeOutInMs)
 | 
			
		||||
            return false;
 | 
			
		||||
 | 
			
		||||
        QCoreApplication::processEvents();
 | 
			
		||||
        QThread::msleep(20);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TestCase::waitForProcessedEditorDocument(const QString &filePath, int timeOutInMs)
 | 
			
		||||
{
 | 
			
		||||
    auto *editorDocument = CppModelManager::instance()->cppEditorDocument(filePath);
 | 
			
		||||
    return waitForProcessedEditorDocument_internal(editorDocument, timeOutInMs);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool TestCase::parseFiles(const QSet<QString> &filePaths)
 | 
			
		||||
{
 | 
			
		||||
    CppModelManager::instance()->updateSourceFiles(filePaths).waitForFinished();
 | 
			
		||||
 
 | 
			
		||||
@@ -95,6 +95,8 @@ public:
 | 
			
		||||
    static CPlusPlus::Snapshot globalSnapshot();
 | 
			
		||||
    static bool garbageCollectGlobalSnapshot();
 | 
			
		||||
 | 
			
		||||
    static bool waitForProcessedEditorDocument(const QString &filePath, int timeOutInMs = 5000);
 | 
			
		||||
 | 
			
		||||
    enum { defaultTimeOutInMs = 30 * 1000 /*= 30 secs*/ };
 | 
			
		||||
    static bool waitUntilCppModelManagerIsAwareOf(
 | 
			
		||||
            ProjectExplorer::Project *project,
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user