Clang: Use completion through backend process

This makes us independent of libclang crashes for completion.
Re-parsing for highlighting still happens in the Qt Creator process.

Run in verbose mode:
    qtc.clangcodemodel.ipc=true

Run tests:
    -test "ClangCodeModel"

Task-number: QTCREATORBUG-14108
Task-number: QTCREATORBUG-12819
Change-Id: Id3e95bd2afdb6508bbd1d35fddc69534a909b905
Reviewed-by: Marco Bubke <marco.bubke@theqtcompany.com>
This commit is contained in:
Nikolai Kosjar
2015-05-08 15:48:17 +02:00
parent 264132da27
commit 23b8a3b2e8
59 changed files with 3820 additions and 634 deletions

View File

@@ -48,6 +48,8 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
QVariant v = s->value(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), PchUse_None);
setPCHUsage(static_cast<PCHUsage>(v.toInt()));
s->endGroup();
emit changed();
}
void CppCodeModelSettings::toSettings(QSettings *s)
@@ -59,6 +61,8 @@ void CppCodeModelSettings::toSettings(QSettings *s)
s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_SUPPORTERS_KEY), QVariant(var));
s->setValue(QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE), pchUsage());
s->endGroup();
emit changed();
}
QStringList CppCodeModelSettings::supportedMimeTypes()
@@ -72,14 +76,20 @@ QStringList CppCodeModelSettings::supportedMimeTypes()
});
}
void CppCodeModelSettings::setModelManagerSupports(const QList<ModelManagerSupport *> &supporters)
void CppCodeModelSettings::emitChanged()
{
m_availableModelManagerSupportersByName.clear();
foreach (ModelManagerSupport *supporter, supporters)
m_availableModelManagerSupportersByName[supporter->displayName()] = supporter->id();
emit changed();
}
QString CppCodeModelSettings::modelManagerSupportId(const QString &mimeType) const
void CppCodeModelSettings::setModelManagerSupportProviders(
const QList<ModelManagerSupportProvider *> &providers)
{
m_modelManagerSupportsByName.clear();
foreach (ModelManagerSupportProvider *provider, providers)
m_modelManagerSupportsByName[provider->displayName()] = provider->id();
}
QString CppCodeModelSettings::modelManagerSupportIdForMimeType(const QString &mimeType) const
{
if (mimeType == cHeaderMimeType)
return m_modelManagerSupportByMimeType.value(cppHeaderMimeType);
@@ -87,13 +97,14 @@ QString CppCodeModelSettings::modelManagerSupportId(const QString &mimeType) con
return m_modelManagerSupportByMimeType.value(mimeType);
}
void CppCodeModelSettings::setModelManagerSupportId(const QString &mimeType,
const QString &supporter)
void CppCodeModelSettings::setModelManagerSupportIdForMimeType(const QString &mimeType,
const QString &id)
{
if (mimeType == cHeaderMimeType)
m_modelManagerSupportByMimeType.insert(cppHeaderMimeType, supporter);
else
m_modelManagerSupportByMimeType.insert(mimeType, supporter);
QString theMimeType = mimeType;
if (theMimeType == cHeaderMimeType)
theMimeType = cppHeaderMimeType;
m_modelManagerSupportByMimeType.insert(theMimeType, id);
}
void CppCodeModelSettings::setIdForMimeType(const QVariant &var, const QString &mimeType)

View File

@@ -40,10 +40,12 @@
namespace CppTools {
class ModelManagerSupport;
class ModelManagerSupportProvider;
class CPPTOOLS_EXPORT CppCodeModelSettings
class CPPTOOLS_EXPORT CppCodeModelSettings : public QObject
{
Q_OBJECT
public:
enum PCHUsage {
PchUse_None = 1,
@@ -56,13 +58,13 @@ public:
void fromSettings(QSettings *s);
void toSettings(QSettings *s);
void setModelManagerSupports(const QList<ModelManagerSupport *> &supporters);
void setModelManagerSupportProviders(const QList<ModelManagerSupportProvider *> &supporters);
QString modelManagerSupportId(const QString &mimeType) const;
void setModelManagerSupportId(const QString &mimeType, const QString &supporter);
QString modelManagerSupportIdForMimeType(const QString &mimeType) const;
void setModelManagerSupportIdForMimeType(const QString &mimeType, const QString &id);
const QHash<QString, QString> &availableModelManagerSupportersByName() const
{ return m_availableModelManagerSupportersByName; }
const QHash<QString, QString> &availableModelManagerSupportProvidersByName() const
{ return m_modelManagerSupportsByName; }
QString defaultId() const
{ return m_defaultId; }
@@ -75,12 +77,18 @@ public:
static QStringList supportedMimeTypes();
public: // for tests
void emitChanged();
signals:
void changed();
private:
void setIdForMimeType(const QVariant &var, const QString &mimeType);
private:
QHash<QString, QString> m_modelManagerSupportByMimeType;
QHash<QString, QString> m_availableModelManagerSupportersByName;
QHash<QString, QString> m_modelManagerSupportsByName;
QString m_defaultId;
PCHUsage m_pchUsage;
};

View File

@@ -71,12 +71,12 @@ void CppCodeModelSettingsWidget::applyToWidget(QComboBox *chooser, const QString
{
chooser->clear();
QStringList names = m_settings->availableModelManagerSupportersByName().keys();
QStringList names = m_settings->availableModelManagerSupportProvidersByName().keys();
Utils::sort(names);
foreach (const QString &name, names) {
const QString &id = m_settings->availableModelManagerSupportersByName()[name];
const QString &id = m_settings->availableModelManagerSupportProvidersByName()[name];
chooser->addItem(name, id);
if (id == m_settings->modelManagerSupportId(mimeType))
if (id == m_settings->modelManagerSupportIdForMimeType(mimeType))
chooser->setCurrentIndex(chooser->count() - 1);
}
chooser->setEnabled(names.size() > 1);
@@ -109,11 +109,11 @@ void CppCodeModelSettingsWidget::applyToSettings() const
bool CppCodeModelSettingsWidget::applyToSettings(QComboBox *chooser, const QString &mimeType) const
{
QString newId = chooser->itemData(chooser->currentIndex()).toString();
QString currentId = m_settings->modelManagerSupportId(mimeType);
QString currentId = m_settings->modelManagerSupportIdForMimeType(mimeType);
if (newId == currentId)
return false;
m_settings->setModelManagerSupportId(mimeType, newId);
m_settings->setModelManagerSupportIdForMimeType(mimeType, newId);
return true;
}

View File

@@ -418,13 +418,20 @@ IAssistProcessor *InternalCompletionAssistProvider::createProcessor() const
}
AssistInterface *InternalCompletionAssistProvider::createAssistInterface(
const QString &filePath, QTextDocument *document,
const LanguageFeatures &languageFeatures, int position, AssistReason reason) const
const QString &filePath,
const TextEditorWidget *textEditorWidget,
const LanguageFeatures &languageFeatures,
int position,
AssistReason reason) const
{
QTC_ASSERT(document, return 0);
QTC_ASSERT(textEditorWidget, return 0);
CppModelManager *modelManager = CppModelManager::instance();
return new CppCompletionAssistInterface(filePath, document, languageFeatures, position, reason,
return new CppCompletionAssistInterface(filePath,
textEditorWidget,
languageFeatures,
position,
reason,
modelManager->workingCopy());
}
@@ -913,7 +920,7 @@ IAssistProposal *InternalCppCompletionAssistProcessor::createContentProposal()
}
m_model->loadContent(m_completions);
return new CppAssistProposal(m_startPosition, m_model.take());
return new CppAssistProposal(m_positionForProposal, m_model.take());
}
IAssistProposal *InternalCppCompletionAssistProcessor::createHintProposal(
@@ -921,7 +928,7 @@ IAssistProposal *InternalCppCompletionAssistProcessor::createHintProposal(
{
IFunctionHintProposalModel *model =
new CppFunctionHintModel(functionSymbols, m_model->m_typeOfExpression);
IAssistProposal *proposal = new FunctionHintProposal(m_startPosition, model);
IAssistProposal *proposal = new FunctionHintProposal(m_positionForProposal, model);
return proposal;
}
@@ -1058,14 +1065,14 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
{
if (m_interface->languageFeatures().objCEnabled) {
if (tryObjCCompletion())
return m_startPosition;
return m_positionForProposal;
}
const int startOfName = findStartOfName();
m_startPosition = startOfName;
m_positionForProposal = startOfName;
m_model->m_completionOperator = T_EOF_SYMBOL;
int endOfOperator = m_startPosition;
int endOfOperator = m_positionForProposal;
// Skip whitespace preceding this position
while (m_interface->characterAt(endOfOperator - 1).isSpace())
@@ -1078,14 +1085,14 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
if (m_model->m_completionOperator == T_DOXY_COMMENT) {
for (int i = 1; i < T_DOXY_LAST_TAG; ++i)
addCompletionItem(QString::fromLatin1(doxygenTagSpell(i)), m_icons.keywordIcon());
return m_startPosition;
return m_positionForProposal;
}
// Pre-processor completion
if (m_model->m_completionOperator == T_POUND) {
completePreprocessor();
m_startPosition = startOfName;
return m_startPosition;
m_positionForProposal = startOfName;
return m_positionForProposal;
}
// Include completion
@@ -1096,8 +1103,8 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
QTextCursor c(m_interface->textDocument());
c.setPosition(endOfExpression);
if (completeInclude(c))
m_startPosition = endOfExpression + 1;
return m_startPosition;
m_positionForProposal = endOfExpression + 1;
return m_positionForProposal;
}
ExpressionUnderCursor expressionUnderCursor(m_interface->languageFeatures());
@@ -1112,7 +1119,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
}
endOfExpression = start;
m_startPosition = start + 1;
m_positionForProposal = start + 1;
m_model->m_completionOperator = T_LPAREN;
}
@@ -1133,7 +1140,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
beforeExpression)) {
m_model->m_completionOperator = CompleteQt5SignalOrSlotClassNameTrigger;
} else { // Ensure global completion
startOfExpression = endOfExpression = m_startPosition;
startOfExpression = endOfExpression = m_positionForProposal;
expression.clear();
m_model->m_completionOperator = T_EOF_SYMBOL;
}
@@ -1155,7 +1162,7 @@ int InternalCppCompletionAssistProcessor::startCompletionHelper()
// We don't want a function completion when the cursor isn't at the opening brace
expression.clear();
m_model->m_completionOperator = T_EOF_SYMBOL;
m_startPosition = startOfName;
m_positionForProposal = startOfName;
startOfExpression = m_interface->position();
}
}
@@ -1226,7 +1233,7 @@ bool InternalCppCompletionAssistProcessor::tryObjCCompletion()
if (m_completions.isEmpty())
return false;
m_startPosition = m_interface->position();
m_positionForProposal = m_interface->position();
return true;
}
@@ -1413,7 +1420,7 @@ int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString
if (expression.isEmpty()) {
if (m_model->m_completionOperator == T_EOF_SYMBOL || m_model->m_completionOperator == T_COLON_COLON) {
(void) (*m_model->m_typeOfExpression)(expression.toUtf8(), scope);
return globalCompletion(scope) ? m_startPosition : -1;
return globalCompletion(scope) ? m_positionForProposal : -1;
}
if (m_model->m_completionOperator == T_SIGNAL || m_model->m_completionOperator == T_SLOT) {
@@ -1458,7 +1465,7 @@ int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString
foreach (const LookupItem &result, results) {
if (result.type()->isClassType()) {
if (completeConstructorOrFunction(results, endOfExpression, true))
return m_startPosition;
return m_positionForProposal;
break;
}
@@ -1467,7 +1474,7 @@ int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString
} else if (m_model->m_completionOperator == CompleteQt5SignalOrSlotClassNameTrigger) {
// Fallback to global completion if we could not lookup sender/receiver object.
return globalCompletion(scope) ? m_startPosition : -1;
return globalCompletion(scope) ? m_positionForProposal : -1;
} else {
return -1; // nothing to do.
@@ -1477,45 +1484,45 @@ int InternalCppCompletionAssistProcessor::startCompletionInternal(const QString
switch (m_model->m_completionOperator) {
case T_LPAREN:
if (completeConstructorOrFunction(results, endOfExpression, false))
return m_startPosition;
return m_positionForProposal;
break;
case T_DOT:
case T_ARROW:
if (completeMember(results))
return m_startPosition;
return m_positionForProposal;
break;
case T_COLON_COLON:
if (completeScope(results))
return m_startPosition;
return m_positionForProposal;
break;
case T_SIGNAL:
if (completeQtMethod(results, CompleteQt4Signals))
return m_startPosition;
return m_positionForProposal;
break;
case T_SLOT:
if (completeQtMethod(results, CompleteQt4Slots))
return m_startPosition;
return m_positionForProposal;
break;
case CompleteQt5SignalOrSlotClassNameTrigger:
if (completeQtMethodClassName(results, scope) || globalCompletion(scope))
return m_startPosition;
return m_positionForProposal;
break;
case CompleteQt5SignalTrigger:
// Fallback to scope completion if "X::" is a namespace and not a class.
if (completeQtMethod(results, CompleteQt5Signals) || completeScope(results))
return m_startPosition;
return m_positionForProposal;
break;
case CompleteQt5SlotTrigger:
// Fallback to scope completion if "X::" is a namespace and not a class.
if (completeQtMethod(results, CompleteQt5Slots) || completeScope(results))
return m_startPosition;
return m_positionForProposal;
break;
default:

View File

@@ -91,7 +91,7 @@ public:
TextEditor::AssistInterface *createAssistInterface(
const QString &filePath,
QTextDocument *document,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,
int position,
TextEditor::AssistReason reason) const override;
@@ -170,12 +170,12 @@ class CppCompletionAssistInterface : public TextEditor::AssistInterface
{
public:
CppCompletionAssistInterface(const QString &filePath,
QTextDocument *textDocument,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,
int position,
TextEditor::AssistReason reason,
const WorkingCopy &workingCopy)
: TextEditor::AssistInterface(textDocument, position, filePath, reason)
: TextEditor::AssistInterface(textEditorWidget->document(), position, filePath, reason)
, m_gotCppSpecifics(false)
, m_workingCopy(workingCopy)
, m_languageFeatures(languageFeatures)

View File

@@ -35,7 +35,7 @@
namespace CppTools {
CppCompletionAssistProcessor::CppCompletionAssistProcessor()
: m_startPosition(-1)
: m_positionForProposal(-1)
, m_preprocessorCompletions(QStringList()
<< QLatin1String("define")
<< QLatin1String("error")

View File

@@ -48,7 +48,7 @@ public:
protected:
void addSnippets();
int m_startPosition;
int m_positionForProposal;
QList<TextEditor::AssistProposalItem *> m_completions;
QStringList m_preprocessorCompletions;
TextEditor::IAssistProposal *m_hintProposal;

View File

@@ -43,7 +43,7 @@ QT_END_NAMESPACE
namespace CPlusPlus { struct LanguageFeatures; }
namespace TextEditor {
class BaseTextEditor;
class TextEditorWidget;
class AssistInterface;
}
@@ -61,7 +61,7 @@ public:
virtual TextEditor::AssistInterface *createAssistInterface(
const QString &filePath,
QTextDocument *document,
const TextEditor::TextEditorWidget *textEditorWidget,
const CPlusPlus::LanguageFeatures &languageFeatures,
int position,
TextEditor::AssistReason reason) const = 0;

View File

@@ -150,8 +150,10 @@ public:
QSet<AbstractEditorSupport *> m_extraEditorSupports;
// Completion & highlighting
QHash<QString, ModelManagerSupport *> m_idTocodeModelSupporter;
QScopedPointer<ModelManagerSupport> m_modelManagerSupportFallback;
ModelManagerSupportProviderInternal m_modelManagerSupportInternalProvider;
ModelManagerSupport::Ptr m_modelManagerSupportInternal;
QHash<QString, ModelManagerSupportProvider *> m_availableModelManagerSupports;
QHash<QString, ModelManagerSupport::Ptr> m_activeModelManagerSupports;
// Indexing
CppIndexingSupport *m_indexingSupporter;
@@ -329,10 +331,17 @@ CppModelManager::CppModelManager(QObject *parent)
qRegisterMetaType<QList<Document::DiagnosticMessage>>(
"QList<CPlusPlus::Document::DiagnosticMessage>");
d->m_modelManagerSupportFallback.reset(new ModelManagerSupportInternal);
CppToolsPlugin::instance()->codeModelSettings()->setDefaultId(
d->m_modelManagerSupportFallback->id());
addModelManagerSupport(d->m_modelManagerSupportFallback.data());
QSharedPointer<CppCodeModelSettings> codeModelSettings
= CppToolsPlugin::instance()->codeModelSettings();
codeModelSettings->setDefaultId(d->m_modelManagerSupportInternalProvider.id());
connect(codeModelSettings.data(), &CppCodeModelSettings::changed,
this, &CppModelManager::onCodeModelSettingsChanged);
d->m_modelManagerSupportInternal
= d->m_modelManagerSupportInternalProvider.createModelManagerSupport();
d->m_activeModelManagerSupports.insert(d->m_modelManagerSupportInternalProvider.id(),
d->m_modelManagerSupportInternal);
addModelManagerSupportProvider(&d->m_modelManagerSupportInternalProvider);
d->m_internalIndexingSupport = new BuiltinIndexingSupport;
}
@@ -466,6 +475,11 @@ void CppModelManager::dumpModelManagerConfiguration(const QString &logFileId)
dumper.dumpMergedEntities(d->m_headerPaths, d->m_definedMacros);
}
QSet<AbstractEditorSupport *> CppModelManager::abstractEditorSupports() const
{
return d->m_extraEditorSupports;
}
void CppModelManager::addExtraEditorSupport(AbstractEditorSupport *editorSupport)
{
d->m_extraEditorSupports.insert(editorSupport);
@@ -648,6 +662,39 @@ void CppModelManager::removeProjectInfoFilesAndIncludesFromSnapshot(const Projec
}
}
void CppModelManager::handleAddedModelManagerSupports(const QSet<QString> &supportIds)
{
foreach (const QString &id, supportIds) {
ModelManagerSupportProvider * const provider = d->m_availableModelManagerSupports.value(id);
if (provider) {
QTC_CHECK(!d->m_activeModelManagerSupports.contains(id));
d->m_activeModelManagerSupports.insert(id, provider->createModelManagerSupport());
}
}
}
QList<ModelManagerSupport::Ptr> CppModelManager::handleRemovedModelManagerSupports(
const QSet<QString> &supportIds)
{
QList<ModelManagerSupport::Ptr> removed;
foreach (const QString &id, supportIds) {
const ModelManagerSupport::Ptr support = d->m_activeModelManagerSupports.value(id);
d->m_activeModelManagerSupports.remove(id);
removed << support;
}
return removed;
}
void CppModelManager::closeCppEditorDocuments()
{
QList<Core::IDocument *> cppDocumentsToClose;
foreach (CppEditorDocumentHandle *cppDocument, cppEditorDocuments())
cppDocumentsToClose << cppDocument->processor()->baseTextDocument();
QTC_CHECK(Core::EditorManager::closeDocuments(cppDocumentsToClose));
}
QList<CppEditorDocumentHandle *> CppModelManager::cppEditorDocuments() const
{
QMutexLocker locker(&d->m_cppEditorDocumentsMutex);
@@ -663,6 +710,15 @@ void CppModelManager::removeFilesFromSnapshot(const QSet<QString> &filesToRemove
d->m_snapshot.remove(i.next());
}
static QStringList projectFilePaths(const QSet<ProjectPart::Ptr> &projectParts)
{
QStringList result;
QSetIterator<ProjectPart::Ptr> it(projectParts);
while (it.hasNext())
result << it.next()->projectFile;
return result;
}
class ProjectInfoComparer
{
public:
@@ -692,6 +748,13 @@ public:
return removedFilesSet;
}
QStringList removedProjectParts()
{
QSet<ProjectPart::Ptr> removed = m_old.projectParts().toSet();
removed.subtract(m_new.projectParts().toSet());
return projectFilePaths(removed);
}
/// Returns a list of common files that have a changed timestamp.
QSet<QString> timeStampModifiedFiles(const Snapshot &snapshot) const
{
@@ -809,6 +872,9 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
}
}
// Announce removed project parts
emit projectPartsRemoved(comparer.removedProjectParts());
// A new project was opened/created, do a full indexing
} else {
d->m_dirty = true;
@@ -829,6 +895,7 @@ QFuture<void> CppModelManager::updateProjectInfo(const ProjectInfo &newProjectIn
if (filesRemoved)
GC();
// Announce added project parts
emit projectPartsUpdated(newProjectInfo.project().data());
// Ideally, we would update all the editor documents that depend on the 'filesToReindex'.
@@ -903,14 +970,32 @@ void CppModelManager::delayedGC()
d->m_delayedGcTimer.start(500);
}
static QStringList pathsOfAllProjectParts(const ProjectInfo &projectInfo)
{
QStringList projectPaths;
foreach (const ProjectPart::Ptr &part, projectInfo.projectParts())
projectPaths << part->projectFile;
return projectPaths;
}
void CppModelManager::onAboutToRemoveProject(ProjectExplorer::Project *project)
{
do {
QStringList projectFilePaths;
{
QMutexLocker locker(&d->m_projectMutex);
d->m_dirty = true;
// Save paths
const ProjectInfo projectInfo = d->m_projectToProjectsInfo.value(project, ProjectInfo());
QTC_CHECK(projectInfo.isValid());
projectFilePaths = pathsOfAllProjectParts(projectInfo);
d->m_projectToProjectsInfo.remove(project);
recalculateFileToProjectParts();
} while (0);
}
emit projectPartsRemoved(projectFilePaths);
delayedGC();
}
@@ -937,6 +1022,45 @@ void CppModelManager::onCurrentEditorChanged(Core::IEditor *editor)
}
}
static const QSet<QString> activeModelManagerSupportsFromSettings()
{
QSet<QString> result;
QSharedPointer<CppCodeModelSettings> codeModelSettings
= CppToolsPlugin::instance()->codeModelSettings();
const QStringList mimeTypes = codeModelSettings->supportedMimeTypes();
foreach (const QString &mimeType, mimeTypes) {
const QString id = codeModelSettings->modelManagerSupportIdForMimeType(mimeType);
if (!id.isEmpty())
result << id;
}
return result;
}
void CppModelManager::onCodeModelSettingsChanged()
{
const QSet<QString> currentCodeModelSupporters = d->m_activeModelManagerSupports.keys().toSet();
const QSet<QString> newCodeModelSupporters = activeModelManagerSupportsFromSettings();
QSet<QString> added = newCodeModelSupporters;
added.subtract(currentCodeModelSupporters);
added.remove(d->m_modelManagerSupportInternalProvider.id());
handleAddedModelManagerSupports(added);
QSet<QString> removed = currentCodeModelSupporters;
removed.subtract(newCodeModelSupporters);
removed.remove(d->m_modelManagerSupportInternalProvider.id());
const QList<ModelManagerSupport::Ptr> supportsToDelete
= handleRemovedModelManagerSupports(removed);
QTC_CHECK(removed.size() == supportsToDelete.size());
if (!added.isEmpty() || !removed.isEmpty())
closeCppEditorDocuments();
// supportsToDelete goes out of scope and deletes the supports
}
void CppModelManager::onAboutToLoadSession()
{
if (d->m_delayedGcTimer.isActive())
@@ -999,11 +1123,8 @@ void CppModelManager::GC()
foreach (const CppEditorDocumentHandle *editorDocument, cppEditorDocuments())
filesInEditorSupports << editorDocument->filePath();
QSetIterator<AbstractEditorSupport *> jt(d->m_extraEditorSupports);
while (jt.hasNext()) {
AbstractEditorSupport *abstractEditorSupport = jt.next();
foreach (AbstractEditorSupport *abstractEditorSupport, abstractEditorSupports())
filesInEditorSupports << abstractEditorSupport->fileName();
}
Snapshot currentSnapshot = snapshot();
QSet<Utils::FileName> reachableFiles;
@@ -1049,27 +1170,33 @@ void CppModelManager::finishedRefreshingSourceFiles(const QSet<QString> &files)
emit sourceFilesRefreshed(files);
}
void CppModelManager::addModelManagerSupport(ModelManagerSupport *modelManagerSupport)
void CppModelManager::addModelManagerSupportProvider(
ModelManagerSupportProvider *modelManagerSupportProvider)
{
Q_ASSERT(modelManagerSupport);
d->m_idTocodeModelSupporter[modelManagerSupport->id()] = modelManagerSupport;
QTC_ASSERT(modelManagerSupportProvider, return);
d->m_availableModelManagerSupports[modelManagerSupportProvider->id()]
= modelManagerSupportProvider;
QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings();
cms->setModelManagerSupports(d->m_idTocodeModelSupporter.values());
cms->setModelManagerSupportProviders(d->m_availableModelManagerSupports.values());
onCodeModelSettingsChanged();
}
ModelManagerSupport *CppModelManager::modelManagerSupportForMimeType(const QString &mimeType) const
ModelManagerSupport::Ptr CppModelManager::modelManagerSupportForMimeType(
const QString &mimeType) const
{
QSharedPointer<CppCodeModelSettings> cms = CppToolsPlugin::instance()->codeModelSettings();
const QString &id = cms->modelManagerSupportId(mimeType);
return d->m_idTocodeModelSupporter.value(id, d->m_modelManagerSupportFallback.data());
const QString &id = cms->modelManagerSupportIdForMimeType(mimeType);
return d->m_activeModelManagerSupports.value(id, d->m_modelManagerSupportInternal);
}
CppCompletionAssistProvider *CppModelManager::completionAssistProvider(const QString &mimeType) const
CppCompletionAssistProvider *CppModelManager::completionAssistProvider(
const QString &mimeType) const
{
if (mimeType.isEmpty())
return 0;
ModelManagerSupport *cms = modelManagerSupportForMimeType(mimeType);
ModelManagerSupport::Ptr cms = modelManagerSupportForMimeType(mimeType);
QTC_ASSERT(cms, return 0);
return cms->completionAssistProvider();
}
@@ -1078,7 +1205,7 @@ BaseEditorDocumentProcessor *CppModelManager::editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) const
{
QTC_ASSERT(baseTextDocument, return 0);
ModelManagerSupport *cms = modelManagerSupportForMimeType(baseTextDocument->mimeType());
ModelManagerSupport::Ptr cms = modelManagerSupportForMimeType(baseTextDocument->mimeType());
QTC_ASSERT(cms, return 0);
return cms->editorDocumentProcessor(baseTextDocument);
}

View File

@@ -33,6 +33,7 @@
#include "cpptools_global.h"
#include "cppmodelmanagersupport.h"
#include "cppprojects.h"
#include <cplusplus/cppmodelmanagerbase.h>
@@ -53,7 +54,6 @@ class BaseEditorDocumentProcessor;
class CppCompletionAssistProvider;
class CppEditorDocumentHandle;
class CppIndexingSupport;
class ModelManagerSupport;
class WorkingCopy;
namespace Internal {
@@ -114,9 +114,11 @@ public:
bool isCppEditor(Core::IEditor *editor) const;
QSet<AbstractEditorSupport*> abstractEditorSupports() const;
void addExtraEditorSupport(AbstractEditorSupport *editorSupport);
void removeExtraEditorSupport(AbstractEditorSupport *editorSupport);
QList<CppEditorDocumentHandle *> cppEditorDocuments() const;
CppEditorDocumentHandle *cppEditorDocument(const QString &filePath) const;
void registerCppEditorDocument(CppEditorDocumentHandle *cppEditorDocument);
void unregisterCppEditorDocument(const QString &filePath);
@@ -132,8 +134,7 @@ public:
void finishedRefreshingSourceFiles(const QSet<QString> &files);
void addModelManagerSupport(ModelManagerSupport *modelManagerSupport);
ModelManagerSupport *modelManagerSupportForMimeType(const QString &mimeType) const;
void addModelManagerSupportProvider(ModelManagerSupportProvider *modelManagerSupportProvider);
CppCompletionAssistProvider *completionAssistProvider(const QString &mimeType) const;
BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) const;
@@ -165,10 +166,8 @@ signals:
void documentUpdated(CPlusPlus::Document::Ptr doc);
void sourceFilesRefreshed(const QSet<QString> &files);
/// \brief Emitted after updateProjectInfo function is called on the model-manager.
///
/// Other classes can use this to get notified when the \c ProjectExplorer has updated the parts.
void projectPartsUpdated(ProjectExplorer::Project *project);
void projectPartsRemoved(const QStringList &projectFiles);
void globalSnapshotChanged();
@@ -188,6 +187,7 @@ private slots:
void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onSourceFilesRefreshed() const;
void onCurrentEditorChanged(Core::IEditor *editor);
void onCodeModelSettingsChanged();
void onCoreAboutToClose();
private:
@@ -199,7 +199,12 @@ private:
void removeFilesFromSnapshot(const QSet<QString> &removedFiles);
void removeProjectInfoFilesAndIncludesFromSnapshot(const ProjectInfo &projectInfo);
QList<CppEditorDocumentHandle *> cppEditorDocuments() const;
void handleAddedModelManagerSupports(const QSet<QString> &supportIds);
QList<ModelManagerSupport::Ptr> handleRemovedModelManagerSupports(
const QSet<QString> &supportIds);
void closeCppEditorDocuments();
ModelManagerSupport::Ptr modelManagerSupportForMimeType(const QString &mimeType) const;
WorkingCopy buildWorkingCopyList();

View File

@@ -33,6 +33,7 @@
#include "cpptools_global.h"
#include <QSharedPointer>
#include <QString>
namespace TextEditor { class TextDocument; }
@@ -45,16 +46,27 @@ class CppCompletionAssistProvider;
class CPPTOOLS_EXPORT ModelManagerSupport
{
public:
virtual ~ModelManagerSupport() = 0;
using Ptr = QSharedPointer<ModelManagerSupport>;
virtual QString id() const = 0;
virtual QString displayName() const = 0;
public:
virtual ~ModelManagerSupport() = 0;
virtual CppCompletionAssistProvider *completionAssistProvider() = 0;
virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument) = 0;
};
class CPPTOOLS_EXPORT ModelManagerSupportProvider
{
public:
virtual ~ModelManagerSupportProvider() {}
virtual QString id() const = 0;
virtual QString displayName() const = 0;
virtual ModelManagerSupport::Ptr createModelManagerSupport() = 0;
};
} // CppTools namespace
#endif // CPPTOOLS_CPPMODELMANAGERSUPPORT_H

View File

@@ -37,6 +37,22 @@
using namespace CppTools;
using namespace CppTools::Internal;
QString ModelManagerSupportProviderInternal::id() const
{
return QLatin1String("CppTools.BuiltinCodeModel");
}
QString ModelManagerSupportProviderInternal::displayName() const
{
return QCoreApplication::translate("ModelManagerSupportInternal::displayName",
"Qt Creator Built-in");
}
ModelManagerSupport::Ptr ModelManagerSupportProviderInternal::createModelManagerSupport()
{
return ModelManagerSupport::Ptr(new ModelManagerSupportInternal);
}
ModelManagerSupportInternal::ModelManagerSupportInternal()
: m_completionAssistProvider(new InternalCompletionAssistProvider)
{
@@ -46,17 +62,6 @@ ModelManagerSupportInternal::~ModelManagerSupportInternal()
{
}
QString ModelManagerSupportInternal::id() const
{
return QLatin1String("CppTools.BuiltinCodeModel");
}
QString ModelManagerSupportInternal::displayName() const
{
return QCoreApplication::translate("ModelManagerSupportInternal::displayName",
"Qt Creator Built-in");
}
BaseEditorDocumentProcessor *ModelManagerSupportInternal::editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument)
{

View File

@@ -46,9 +46,6 @@ public:
ModelManagerSupportInternal();
virtual ~ModelManagerSupportInternal();
virtual QString id() const;
virtual QString displayName() const;
virtual CppCompletionAssistProvider *completionAssistProvider();
virtual BaseEditorDocumentProcessor *editorDocumentProcessor(
TextEditor::TextDocument *baseTextDocument);
@@ -57,6 +54,15 @@ private:
QScopedPointer<CppCompletionAssistProvider> m_completionAssistProvider;
};
class ModelManagerSupportProviderInternal : public ModelManagerSupportProvider
{
public:
QString id() const override;
QString displayName() const override;
CppTools::ModelManagerSupport::Ptr createModelManagerSupport() override;
};
} // Internal namespace
} // CppTools namespace

View File

@@ -136,7 +136,6 @@ const QStringList &CppToolsPlugin::sourcePrefixes()
return m_instance->m_fileSettings->sourcePrefixes;
}
bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
{
Q_UNUSED(arguments)
@@ -153,6 +152,8 @@ bool CppToolsPlugin::initialize(const QStringList &arguments, QString *error)
modelManager->updateSourceFiles(files.toSet());
});
m_codeModelSettings->fromSettings(ICore::settings());
JsExpander::registerQObjectForJs(QLatin1String("Cpp"), new CppToolsJsExtension);
CppLocatorData *locatorData = new CppLocatorData;
@@ -218,7 +219,6 @@ void CppToolsPlugin::extensionsInitialized()
m_fileSettings->fromSettings(ICore::settings());
if (!m_fileSettings->applySuffixesToMimeDB())
qWarning("Unable to apply cpp suffixes to mime database (cpp mime types not found).\n");
m_codeModelSettings->fromSettings(ICore::settings());
}
ExtensionSystem::IPlugin::ShutdownFlag CppToolsPlugin::aboutToShutdown()

View File

@@ -51,7 +51,9 @@ public:
virtual unsigned revision() const = 0;
// For updating if new project info is set
virtual BaseEditorDocumentProcessor *processor() = 0;
virtual BaseEditorDocumentProcessor *processor() const = 0;
virtual void resetProcessor() = 0;
private:
bool m_needsRefresh;