forked from qt-creator/qt-creator
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:
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
namespace CppTools {
|
||||
|
||||
CppCompletionAssistProcessor::CppCompletionAssistProcessor()
|
||||
: m_startPosition(-1)
|
||||
: m_positionForProposal(-1)
|
||||
, m_preprocessorCompletions(QStringList()
|
||||
<< QLatin1String("define")
|
||||
<< QLatin1String("error")
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user