forked from qt-creator/qt-creator
C++: add code-model support for defines-per-editor.
The UI side will come in another commit. Change-Id: I1038a438587fe4cef70408f7f627d08837fc192d Reviewed-by: Nikolai Kosjar <nikolai.kosjar@digia.com>
This commit is contained in:
@@ -970,3 +970,99 @@ void CppToolsPlugin::test_modelmanager_defines_per_project_pch()
|
||||
QCOMPARE(decl->name()->identifier()->chars(), "two");
|
||||
}
|
||||
}
|
||||
|
||||
void CppToolsPlugin::test_modelmanager_defines_per_editor()
|
||||
{
|
||||
ModelManagerTestHelper helper;
|
||||
|
||||
MyTestDataDir testDataDirectory(QLatin1String("testdata_defines"));
|
||||
const QString main1File = testDataDirectory.file(QLatin1String("main1.cpp"));
|
||||
const QString main2File = testDataDirectory.file(QLatin1String("main2.cpp"));
|
||||
const QString header = testDataDirectory.file(QLatin1String("header.h"));
|
||||
|
||||
CppModelManager *mm = CppModelManager::instance();
|
||||
|
||||
Project *project = helper.createProject(
|
||||
QLatin1String("test_modelmanager_defines_per_editor"));
|
||||
|
||||
ProjectPart::Ptr part1(new ProjectPart);
|
||||
part1->files.append(ProjectFile(main1File, ProjectFile::CXXSource));
|
||||
part1->files.append(ProjectFile(header, ProjectFile::CXXHeader));
|
||||
part1->cxxVersion = ProjectPart::CXX11;
|
||||
part1->qtVersion = ProjectPart::NoQt;
|
||||
part1->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
|
||||
ProjectPart::Ptr part2(new ProjectPart);
|
||||
part2->files.append(ProjectFile(main2File, ProjectFile::CXXSource));
|
||||
part2->files.append(ProjectFile(header, ProjectFile::CXXHeader));
|
||||
part2->cxxVersion = ProjectPart::CXX11;
|
||||
part2->qtVersion = ProjectPart::NoQt;
|
||||
part2->includePaths = QStringList() << testDataDirectory.includeDir(false);
|
||||
|
||||
ProjectInfo pi = mm->projectInfo(project);
|
||||
pi.appendProjectPart(part1);
|
||||
pi.appendProjectPart(part2);
|
||||
|
||||
mm->updateProjectInfo(pi);
|
||||
|
||||
helper.waitForRefreshedSourceFiles();
|
||||
|
||||
QCOMPARE(mm->snapshot().size(), 4);
|
||||
|
||||
// Open a file in the editor
|
||||
QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 0);
|
||||
|
||||
{
|
||||
Core::IEditor *editor = Core::EditorManager::openEditor(main1File);
|
||||
EditorCloser closer(editor);
|
||||
QVERIFY(editor);
|
||||
QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 1);
|
||||
QVERIFY(mm->isCppEditor(editor));
|
||||
|
||||
CppEditorSupport *sup = mm->cppEditorSupport(
|
||||
qobject_cast<TextEditor::BaseTextEditor *>(editor));
|
||||
while (sup->lastSemanticInfoDocument().isNull())
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
sup->snapshotUpdater()->setEditorDefines(QByteArray("#define SUB1\n"));
|
||||
sup->snapshotUpdater()->update(mm->workingCopy());
|
||||
|
||||
Document::Ptr doc = mm->snapshot().document(main1File);
|
||||
QVERIFY(doc);
|
||||
QVERIFY(doc->globalNamespace());
|
||||
QCOMPARE(doc->globalSymbolCount(), 1U);
|
||||
CPlusPlus::Symbol *s = doc->globalSymbolAt(0);
|
||||
QVERIFY(s);
|
||||
CPlusPlus::Declaration *decl = s->asDeclaration();
|
||||
QVERIFY(decl);
|
||||
QVERIFY(decl->type()->isIntegerType());
|
||||
QCOMPARE(decl->name()->identifier()->chars(), "one");
|
||||
}
|
||||
|
||||
{
|
||||
Core::IEditor *editor = Core::EditorManager::openEditor(main2File);
|
||||
EditorCloser closer(editor);
|
||||
QVERIFY(editor);
|
||||
QCOMPARE(Core::EditorManager::documentModel()->openedDocuments().size(), 1);
|
||||
QVERIFY(mm->isCppEditor(editor));
|
||||
|
||||
CppEditorSupport *sup = mm->cppEditorSupport(
|
||||
qobject_cast<TextEditor::BaseTextEditor *>(editor));
|
||||
while (sup->lastSemanticInfoDocument().isNull())
|
||||
QCoreApplication::processEvents();
|
||||
|
||||
sup->snapshotUpdater()->setEditorDefines(QByteArray("#define SUB2\n"));
|
||||
sup->snapshotUpdater()->update(mm->workingCopy());
|
||||
|
||||
Document::Ptr doc = mm->snapshot().document(main2File);
|
||||
QVERIFY(doc);
|
||||
QVERIFY(doc->globalNamespace());
|
||||
QCOMPARE(doc->globalSymbolCount(), 1U);
|
||||
CPlusPlus::Symbol *s = doc->globalSymbolAt(0);
|
||||
QVERIFY(s);
|
||||
CPlusPlus::Declaration *decl = s->asDeclaration();
|
||||
QVERIFY(decl);
|
||||
QVERIFY(decl->type()->isIntegerType());
|
||||
QCOMPARE(decl->name()->identifier()->chars(), "two");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -223,10 +223,15 @@ QString CppPreprocessor::cleanPath(const QString &path)
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline bool isInjectedFile(const QString &fileName)
|
||||
{
|
||||
return fileName.startsWith(QLatin1Char('<')) && fileName.endsWith(QLatin1Char('>'));
|
||||
}
|
||||
|
||||
QString CppPreprocessor::resolveFile_helper(const QString &fileName, IncludeType type)
|
||||
{
|
||||
const QFileInfo fileInfo(fileName);
|
||||
if (fileName == Preprocessor::configurationFileName || fileInfo.isAbsolute())
|
||||
if (isInjectedFile(fileName) || fileInfo.isAbsolute())
|
||||
return fileName;
|
||||
|
||||
if (type == IncludeLocal && m_currentDoc) {
|
||||
|
||||
@@ -39,6 +39,7 @@ using namespace CppTools::Internal;
|
||||
SnapshotUpdater::SnapshotUpdater(const QString &fileInEditor)
|
||||
: m_mutex(QMutex::Recursive)
|
||||
, m_fileInEditor(fileInEditor)
|
||||
, m_editorDefinesChangedSinceLastUpdate(false)
|
||||
, m_usePrecompiledHeaders(false)
|
||||
{
|
||||
}
|
||||
@@ -50,7 +51,7 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
if (m_fileInEditor.isEmpty())
|
||||
return;
|
||||
|
||||
bool invalidateSnapshot = false, invalidateConfig = false;
|
||||
bool invalidateSnapshot = false, invalidateConfig = false, editorDefinesChanged = false;
|
||||
|
||||
CppModelManager *modelManager
|
||||
= dynamic_cast<CppModelManager *>(CppModelManagerInterface::instance());
|
||||
@@ -75,6 +76,12 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
invalidateConfig = true;
|
||||
}
|
||||
|
||||
if (m_editorDefinesChangedSinceLastUpdate) {
|
||||
invalidateSnapshot = true;
|
||||
editorDefinesChanged = true;
|
||||
m_editorDefinesChangedSinceLastUpdate = false;
|
||||
}
|
||||
|
||||
if (includePaths != m_includePaths) {
|
||||
m_includePaths = includePaths;
|
||||
invalidateSnapshot = true;
|
||||
@@ -131,6 +138,12 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
workingCopy.insert(configurationFileName, m_configFile);
|
||||
m_snapshot.remove(m_fileInEditor);
|
||||
|
||||
static const QString editorDefinesFileName = QLatin1String("<per-editor-defines>");
|
||||
if (editorDefinesChanged) {
|
||||
m_snapshot.remove(editorDefinesFileName);
|
||||
workingCopy.insert(editorDefinesFileName, m_editorDefines);
|
||||
}
|
||||
|
||||
CppPreprocessor preproc(modelManager, m_snapshot);
|
||||
Snapshot globalSnapshot = modelManager->snapshot();
|
||||
globalSnapshot.remove(fileInEditor());
|
||||
@@ -142,6 +155,8 @@ void SnapshotUpdater::update(CppModelManager::WorkingCopy workingCopy)
|
||||
if (m_usePrecompiledHeaders)
|
||||
foreach (const QString &precompiledHeader, m_precompiledHeaders)
|
||||
preproc.run(precompiledHeader);
|
||||
if (!m_editorDefines.isEmpty())
|
||||
preproc.run(editorDefinesFileName);
|
||||
preproc.run(m_fileInEditor);
|
||||
|
||||
m_snapshot = preproc.snapshot();
|
||||
@@ -178,6 +193,16 @@ void SnapshotUpdater::setUsePrecompiledHeaders(bool usePrecompiledHeaders)
|
||||
m_usePrecompiledHeaders = usePrecompiledHeaders;
|
||||
}
|
||||
|
||||
void SnapshotUpdater::setEditorDefines(const QByteArray &editorDefines)
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
|
||||
if (editorDefines != m_editorDefines) {
|
||||
m_editorDefines = editorDefines;
|
||||
m_editorDefinesChangedSinceLastUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
void SnapshotUpdater::updateProjectPart()
|
||||
{
|
||||
CppModelManager *cmm = dynamic_cast<CppModelManager *>(CppModelManagerInterface::instance());
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
{ return m_frameworkPaths; }
|
||||
|
||||
void setUsePrecompiledHeaders(bool usePrecompiledHeaders);
|
||||
void setEditorDefines(const QByteArray &editorDefines);
|
||||
|
||||
private:
|
||||
void updateProjectPart();
|
||||
@@ -75,6 +76,8 @@ private:
|
||||
QString m_fileInEditor;
|
||||
ProjectPart::Ptr m_projectPart;
|
||||
QByteArray m_configFile;
|
||||
bool m_editorDefinesChangedSinceLastUpdate;
|
||||
QByteArray m_editorDefines;
|
||||
QStringList m_includePaths;
|
||||
QStringList m_frameworkPaths;
|
||||
QStringList m_precompiledHeaders;
|
||||
|
||||
@@ -213,6 +213,7 @@ private slots:
|
||||
void test_modelmanager_dont_gc_opened_files();
|
||||
void test_modelmanager_defines_per_project();
|
||||
void test_modelmanager_defines_per_project_pch();
|
||||
void test_modelmanager_defines_per_editor();
|
||||
|
||||
void test_cpplocatorfilters_CppLocatorFilter();
|
||||
void test_cpplocatorfilters_CppLocatorFilter_data();
|
||||
|
||||
Reference in New Issue
Block a user