QList<Locator::FilterEntry> CppCurrentDocumentFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString & origEntry) { QString entry = trimWildcards(origEntry); QList<Locator::FilterEntry> goodEntries; QList<Locator::FilterEntry> betterEntries; QStringMatcher matcher(entry, Qt::CaseInsensitive); const QChar asterisk = QLatin1Char('*'); const QRegExp regexp(asterisk + entry + asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) return goodEntries; bool hasWildcard = (entry.contains(asterisk) || entry.contains('?')); if (m_currentFileName.isEmpty()) return goodEntries; if (m_itemsOfCurrentDoc.isEmpty()) { Snapshot snapshot = m_modelManager->snapshot(); Document::Ptr thisDocument = snapshot.document(m_currentFileName); if (thisDocument) m_itemsOfCurrentDoc = search(thisDocument); } foreach (const ModelItemInfo & info, m_itemsOfCurrentDoc) { if (future.isCanceled()) break; if ((hasWildcard && regexp.exactMatch(info.symbolName)) || (!hasWildcard && matcher.indexIn(info.symbolName) != -1)) { QString symbolName = info.symbolName;// + (info.type == ModelItemInfo::Declaration ? ";" : " {...}"); QVariant id = qVariantFromValue(info); Locator::FilterEntry filterEntry(this, symbolName, id, info.icon); filterEntry.extraInfo = info.symbolType; if (info.symbolName.startsWith(entry)) betterEntries.append(filterEntry); else goodEntries.append(filterEntry); } } // entries are unsorted by design! betterEntries += goodEntries; return betterEntries; }
QList<Locator::FilterEntry> FunctionFilter::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &origEntry) { QString entry = trimWildcards(origEntry); QList<Locator::FilterEntry> goodEntries; QList<Locator::FilterEntry> betterEntries; const QChar asterisk = QLatin1Char('*'); QStringMatcher matcher(entry, Qt::CaseInsensitive); QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) return goodEntries; bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?'))); const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry); QHashIterator<QString, QList<LocatorData::Entry> > it(m_data->entries()); while (it.hasNext()) { if (future.isCanceled()) break; it.next(); const QList<LocatorData::Entry> items = it.value(); foreach (const LocatorData::Entry &info, items) { if (info.type != LocatorData::Function) continue; if ((hasWildcard && regexp.exactMatch(info.symbolName)) || (!hasWildcard && matcher.indexIn(info.symbolName) != -1)) { QVariant id = qVariantFromValue(info); Locator::FilterEntry filterEntry(this, info.displayName, id/*, info.icon*/); filterEntry.extraInfo = info.extraInfo; if (info.symbolName.startsWith(entry, caseSensitivityForPrefix)) betterEntries.append(filterEntry); else goodEntries.append(filterEntry); } } } if (goodEntries.size() < 1000) qSort(goodEntries.begin(), goodEntries.end(), compareLexigraphically); if (betterEntries.size() < 1000) qSort(betterEntries.begin(), betterEntries.end(), compareLexigraphically); betterEntries += goodEntries; return betterEntries; }
void ManagerProcessor::process(QFutureInterface<Manager::RegisterData> &future) { future.setProgressRange(0, kMaxProgress); Manager::RegisterData data; // iterate through paths in order, high priority > low priority foreach (const QString &path, m_definitionsPaths) { if (path.isEmpty()) continue; QDir definitionsDir(path); QStringList filter(QLatin1String("*.xml")); definitionsDir.setNameFilters(filter); foreach (const QFileInfo &fileInfo, definitionsDir.entryInfoList()) { if (future.isCanceled()) return; if (future.progressValue() < kMaxProgress - 1) future.setProgressValue(future.progressValue() + 1); const DefinitionMetaDataPtr &metaData = Manager::parseMetadata(fileInfo); // skip failing or already existing definitions if (!metaData.isNull() && !data.m_idByName.contains(metaData->name)) { const QString id = metaData->id; data.m_idByName.insert(metaData->name, id); data.m_definitionsMetaData.insert(id, metaData); foreach (const QString &mt, metaData->mimeTypes) { bool insert = true; // check if there is already a definition registered with higher priority const QString existingDefinition = data.m_idByMimeType.value(mt); if (!existingDefinition.isEmpty()) { // check priorities DefinitionMetaDataPtr existingMetaData = data.m_definitionsMetaData.value(existingDefinition); if (!existingMetaData.isNull() && existingMetaData->priority > metaData->priority) insert = false; } if (insert) data.m_idByMimeType.insert(mt, id); } } } } future.reportResult(data); }
QList<LocatorFilterEntry> HelpIndexFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &entry) { QStringList keywords; if (entry.length() < 2) keywords = Core::HelpManager::findKeywords(entry, caseSensitivity(entry), 200); else keywords = Core::HelpManager::findKeywords(entry, caseSensitivity(entry)); QList<LocatorFilterEntry> entries; foreach (const QString &keyword, keywords) { if (future.isCanceled()) break; entries.append(LocatorFilterEntry(this, keyword, QVariant(), m_icon)); } return entries; }
QList<Core::LocatorFilterEntry> CppLocatorFilter::matchesFor( QFutureInterface<Core::LocatorFilterEntry> &future, const QString &origEntry) { QString entry = trimWildcards(origEntry); QList<Core::LocatorFilterEntry> goodEntries; QList<Core::LocatorFilterEntry> betterEntries; const QChar asterisk = QLatin1Char('*'); QStringMatcher matcher(entry, Qt::CaseInsensitive); QRegExp regexp(asterisk + entry+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) return goodEntries; bool hasWildcard = (entry.contains(asterisk) || entry.contains(QLatin1Char('?'))); bool hasColonColon = entry.contains(QLatin1String("::")); const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry); const IndexItem::ItemType wanted = matchTypes(); m_data->filterAllFiles([&](const IndexItem::Ptr &info) -> IndexItem::VisitorResult { if (future.isCanceled()) return IndexItem::Break; if (info->type() & wanted) { const QString matchString = hasColonColon ? info->scopedSymbolName() : info->symbolName(); if ((hasWildcard && regexp.exactMatch(matchString)) || (!hasWildcard && matcher.indexIn(matchString) != -1)) { const Core::LocatorFilterEntry filterEntry = filterEntryFromIndexItem(info); if (matchString.startsWith(entry, caseSensitivityForPrefix)) betterEntries.append(filterEntry); else goodEntries.append(filterEntry); } } if (info->type() & IndexItem::Enum) return IndexItem::Continue; else return IndexItem::Recurse; }); if (goodEntries.size() < 1000) std::stable_sort(goodEntries.begin(), goodEntries.end(), compareLexigraphically); if (betterEntries.size() < 1000) std::stable_sort(betterEntries.begin(), betterEntries.end(), compareLexigraphically); betterEntries += goodEntries; return betterEntries; }
void Locator::Internal::runSearch(QFutureInterface<Locator::FilterEntry> &entries, QList<ILocatorFilter *> filters, QString searchText) { QSet<FilterEntry> alreadyAdded; const bool checkDuplicates = (filters.size() > 1); foreach (ILocatorFilter *filter, filters) { if (entries.isCanceled()) break; foreach (const FilterEntry &entry, filter->matchesFor(entries, searchText)) { if (checkDuplicates && alreadyAdded.contains(entry)) continue; entries.reportResult(entry); if (checkDuplicates) alreadyAdded.insert(entry); } } }
void QmlTaskManager::collectMessages( QFutureInterface<FileErrorMessages> &future, Snapshot snapshot, QList<ModelManagerInterface::ProjectInfo> projectInfos, ViewerContext vContext, bool updateSemantic) { foreach (const ModelManagerInterface::ProjectInfo &info, projectInfos) { QHash<QString, QList<DiagnosticMessage> > linkMessages; ContextPtr context; if (updateSemantic) { Link link(snapshot, vContext, snapshot.libraryInfo(info.qtImportsPath)); context = link(&linkMessages); } foreach (const QString &fileName, info.sourceFiles) { Document::Ptr document = snapshot.document(fileName); if (!document) continue; FileErrorMessages result; result.fileName = fileName; if (Document::isFullySupportedLanguage(document->language())) { result.tasks = convertToTasks(document->diagnosticMessages(), Utils::FileName::fromString(fileName), Core::Id(Constants::TASK_CATEGORY_QML)); if (updateSemantic) { result.tasks += convertToTasks(linkMessages.value(fileName), Utils::FileName::fromString(fileName), Core::Id(Constants::TASK_CATEGORY_QML_ANALYSIS)); Check checker(document, context); result.tasks += convertToTasks(checker(), Utils::FileName::fromString(fileName), Core::Id(Constants::TASK_CATEGORY_QML_ANALYSIS)); } } if (!result.tasks.isEmpty()) future.reportResult(result); if (future.isCanceled()) break; } }
QList<LocatorFilterEntry> ExecuteFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry) { QList<LocatorFilterEntry> value; if (!entry.isEmpty()) // avoid empty entry value.append(LocatorFilterEntry(this, entry, QVariant())); QList<LocatorFilterEntry> others; const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(entry); foreach (const QString &i, m_commandHistory) { if (future.isCanceled()) break; if (i == entry) // avoid repeated entry continue; if (i.startsWith(entry, caseSensitivityForPrefix)) value.append(LocatorFilterEntry(this, i, QVariant())); else others.append(LocatorFilterEntry(this, i, QVariant())); } value.append(others); return value; }
QList<Locator::FilterEntry> CommandLocator::matchesFor(QFutureInterface<Locator::FilterEntry> &future, const QString &entry) { QList<FilterEntry> filters; // Get active, enabled actions matching text, store in list. // Reference via index in extraInfo. const QChar ampersand = QLatin1Char('&'); const int count = d->commands.size(); for (int i = 0; i < count; i++) { if (future.isCanceled()) break; if (d->commands.at(i)->isActive()) { if (QAction *action = d->commands.at(i)->action()) if (action->isEnabled()) { QString text = action->text(); text.remove(ampersand); if (text.contains(entry, Qt::CaseInsensitive)) filters.append(FilterEntry(this, text, QVariant(i))); } } } return filters; }
void Core::Internal::runSearch(QFutureInterface<Core::LocatorFilterEntry> &future, const QList<ILocatorFilter *> &filters, const QString &searchText) { QSet<LocatorFilterEntry> alreadyAdded; const bool checkDuplicates = (filters.size() > 1); foreach (ILocatorFilter *filter, filters) { if (future.isCanceled()) break; QList<LocatorFilterEntry> filterResults = filter->matchesFor(future, searchText); QVector<LocatorFilterEntry> uniqueFilterResults; uniqueFilterResults.reserve(filterResults.size()); foreach (const LocatorFilterEntry &entry, filterResults) { if (checkDuplicates && alreadyAdded.contains(entry)) continue; uniqueFilterResults.append(entry); if (checkDuplicates) alreadyAdded.insert(entry); } if (!uniqueFilterResults.isEmpty()) future.reportResults(uniqueFilterResults); } }
void SpellCheckProcessor::process(QFutureInterface<WordList> &future) { #ifdef BENCH_TIME QElapsedTimer timer; timer.start(); #endif /* BENCH_TIME */ WordListConstIter misspelledIter; WordListConstIter prevMisspelledIter; Word misspelledWord; WordList misspelledWords; WordList words = d_wordList; WordListConstIter wordIter = words.constBegin(); bool spellingMistake; future.setProgressRange(0, words.count() + 1); while(wordIter != d_wordList.constEnd()) { /* Get the word at the current iterator position. * After this is done, move the iterator to the next position and * increment the progress value. This is done so that one can call * 'continue' anywhere after this in the loop without having to worry * about advancing the iterator since this will already be done and * correct for the next iteration. */ misspelledWord = (*wordIter); ++wordIter; future.setProgressValue(future.progressValue() + 1); /* Check if the future was cancelled */ if(future.isCanceled() == true) { return; } spellingMistake = d_spellChecker->isSpellingMistake(misspelledWord.text); /* Check to see if the char after the word is a period. If it is, * add the period to the word an see if it passes the checker. */ if((spellingMistake == true) && (misspelledWord.charAfter == QLatin1Char('.'))) { /* Recheck the word with the period added */ spellingMistake = d_spellChecker->isSpellingMistake(misspelledWord.text + QLatin1Char('.')); } if(spellingMistake == true) { /* The word is a spelling mistake, check if the word was a mistake * the previous time that this file was processed. If it was the * suggestions can be reused without having to get the suggestions * through the spell checker since this is slow compared to the rest * of the processing. */ prevMisspelledIter = d_previousMistakes.find(misspelledWord.text); if(prevMisspelledIter != d_previousMistakes.constEnd()) { misspelledWord.suggestions = (*prevMisspelledIter).suggestions; misspelledWords.append(misspelledWord); continue; } /* The word was not in the previous iteration, search for the word * in the list of words that were already checked in this iteration * and identified as spelling mistakes. If there are words that are * repeated and misspelled, this can reduce the time to process * the file since the time to get suggestions is rather slow. * If there are no repeating mistakes then this might add unneeded * overhead. */ misspelledIter = misspelledWords.find(misspelledWord.text); if(misspelledIter != misspelledWords.constEnd()) { misspelledWord.suggestions = (*misspelledIter).suggestions; /* Add the word to the local list of misspelled words. */ misspelledWords.append(misspelledWord); continue; } /* At this point the word is a mistake for the first time. It was neither * a mistake in the previous pass of the file nor did the word occur previously * in this file, use the spell checker to get the suggestions for the word. */ d_spellChecker->getSuggestionsForWord(misspelledWord.text, misspelledWord.suggestions); /* Add the word to the local list of misspelled words. */ misspelledWords.append(misspelledWord); } } #ifdef BENCH_TIME qDebug() << "File: " << d_fileName << "\n - time : " << timer.elapsed() << "\n - count: " << misspelledWords.size(); #endif /* BENCH_TIME */ future.reportResult(misspelledWords); }
QList<LocatorFilterEntry> BaseFileFilter::matchesFor(QFutureInterface<LocatorFilterEntry> &future, const QString &origEntry) { QList<LocatorFilterEntry> betterEntries; QList<LocatorFilterEntry> goodEntries; QString needle = trimWildcards(QDir::fromNativeSeparators(origEntry)); const QString lineNoSuffix = EditorManager::splitLineNumber(&needle); QStringMatcher matcher(needle, Qt::CaseInsensitive); const QChar asterisk = QLatin1Char('*'); QRegExp regexp(asterisk + needle+ asterisk, Qt::CaseInsensitive, QRegExp::Wildcard); if (!regexp.isValid()) { d->m_current.clear(); // free memory return betterEntries; } const QChar pathSeparator(QLatin1Char('/')); const bool hasPathSeparator = needle.contains(pathSeparator); const bool hasWildcard = needle.contains(asterisk) || needle.contains(QLatin1Char('?')); const bool containsPreviousEntry = !d->m_current.previousEntry.isEmpty() && needle.contains(d->m_current.previousEntry); const bool pathSeparatorAdded = !d->m_current.previousEntry.contains(pathSeparator) && needle.contains(pathSeparator); const bool searchInPreviousResults = !d->m_current.forceNewSearchList && containsPreviousEntry && !pathSeparatorAdded; if (searchInPreviousResults) d->m_current.iterator.reset(new ListIterator(d->m_current.previousResultPaths, d->m_current.previousResultNames)); QTC_ASSERT(d->m_current.iterator.data(), return QList<LocatorFilterEntry>()); d->m_current.previousResultPaths.clear(); d->m_current.previousResultNames.clear(); d->m_current.previousEntry = needle; const Qt::CaseSensitivity caseSensitivityForPrefix = caseSensitivity(needle); d->m_current.iterator->toFront(); bool canceled = false; while (d->m_current.iterator->hasNext()) { if (future.isCanceled()) { canceled = true; break; } d->m_current.iterator->next(); QString path = d->m_current.iterator->filePath(); QString name = d->m_current.iterator->fileName(); QString matchText = hasPathSeparator ? path : name; if ((hasWildcard && regexp.exactMatch(matchText)) || (!hasWildcard && matcher.indexIn(matchText) != -1)) { QFileInfo fi(path); LocatorFilterEntry entry(this, fi.fileName(), QString(path + lineNoSuffix)); entry.extraInfo = FileUtils::shortNativePath(FileName(fi)); entry.fileName = path; if (matchText.startsWith(needle, caseSensitivityForPrefix)) betterEntries.append(entry); else goodEntries.append(entry); d->m_current.previousResultPaths.append(path); d->m_current.previousResultNames.append(name); } } betterEntries.append(goodEntries); if (canceled) { // we keep the old list of previous search results if this search was canceled // so a later search without foreNewSearchList will use that previous list instead of an // incomplete list of a canceled search d->m_current.clear(); // free memory } else { d->m_current.iterator.clear(); QTimer::singleShot(0, this, SLOT(updatePreviousResultData())); } return betterEntries; }
AndroidDeployQtStep::DeployResult AndroidDeployQtStep::runDeploy(QFutureInterface<bool> &fi) { m_installOk = true; QString args; if (m_useAndroiddeployqt) { args = m_androiddeployqtArgs; if (m_uninstallPreviousPackageRun) Utils::QtcProcess::addArg(&args, QLatin1String("--install")); else Utils::QtcProcess::addArg(&args, QLatin1String("--reinstall")); if (!m_serialNumber.isEmpty() && !m_serialNumber.startsWith(QLatin1String("????"))) { Utils::QtcProcess::addArg(&args, QLatin1String("--device")); Utils::QtcProcess::addArg(&args, m_serialNumber); } } else { if (m_uninstallPreviousPackageRun) { const QString packageName = AndroidManager::packageName(m_manifestName); if (packageName.isEmpty()) { emit addOutput(tr("Cannot find the package name."), ErrorOutput); return Failure; } emit addOutput(tr("Uninstall previous package %1.").arg(packageName), MessageOutput); runCommand(m_adbPath, AndroidDeviceInfo::adbSelector(m_serialNumber) << QLatin1String("uninstall") << packageName); } foreach (const QString &arg, AndroidDeviceInfo::adbSelector(m_serialNumber)) Utils::QtcProcess::addArg(&args, arg); Utils::QtcProcess::addArg(&args, QLatin1String("install")); Utils::QtcProcess::addArg(&args, QLatin1String("-r")); Utils::QtcProcess::addArg(&args, m_apkPath); } m_process = new Utils::QtcProcess; m_process->setCommand(m_command, args); m_process->setWorkingDirectory(m_workingDirectory); m_process->setEnvironment(m_environment); if (Utils::HostOsInfo::isWindowsHost()) m_process->setUseCtrlCStub(true); connect(m_process, &Utils::QtcProcess::readyReadStandardOutput, this, &AndroidDeployQtStep::processReadyReadStdOutput, Qt::DirectConnection); connect(m_process, &Utils::QtcProcess::readyReadStandardError, this, &AndroidDeployQtStep::processReadyReadStdError, Qt::DirectConnection); m_process->start(); emit addOutput(tr("Starting: \"%1\" %2") .arg(QDir::toNativeSeparators(m_command), args), BuildStep::MessageOutput); while (!m_process->waitForFinished(200)) { if (fi.isCanceled()) { m_process->kill(); m_process->waitForFinished(); } } QString line = QString::fromLocal8Bit(m_process->readAllStandardError()); if (!line.isEmpty()) stdError(line); line = QString::fromLocal8Bit(m_process->readAllStandardOutput()); if (!line.isEmpty()) stdOutput(line); QProcess::ExitStatus exitStatus = m_process->exitStatus(); int exitCode = m_process->exitCode(); delete m_process; m_process = 0; if (exitStatus == QProcess::NormalExit && exitCode == 0) { emit addOutput(tr("The process \"%1\" exited normally.").arg(m_command), BuildStep::MessageOutput); } else if (exitStatus == QProcess::NormalExit) { emit addOutput(tr("The process \"%1\" exited with code %2.") .arg(m_command, QString::number(exitCode)), BuildStep::ErrorMessageOutput); } else { emit addOutput(tr("The process \"%1\" crashed.").arg(m_command), BuildStep::ErrorMessageOutput); } if (exitCode == 0 && exitStatus == QProcess::NormalExit) { if (!m_installOk) { if (!m_uninstallPreviousPackageRun) return AskUinstall; else return Failure; } return Success; } return Failure; }
void tst_QFuture::cancel() { { QFuture<void> f; QFutureInterface<void> result; result.reportStarted(); f = result.future(); QVERIFY(!f.isCanceled()); result.reportCanceled(); QVERIFY(f.isCanceled()); result.reportFinished(); QVERIFY(f.isCanceled()); f.waitForFinished(); QVERIFY(f.isCanceled()); } // Cancel from the QFuture side and test if the result // interface detects it. { QFutureInterface<void> result; QFuture<void> f; QVERIFY(f.isStarted()); result.reportStarted(); f = result.future(); QVERIFY(f.isStarted()); QVERIFY(!result.isCanceled()); f.cancel(); QVERIFY(result.isCanceled()); result.reportFinished(); } // Test that finished futures can be canceled. { QFutureInterface<void> result; QFuture<void> f; QVERIFY(f.isStarted()); result.reportStarted(); f = result.future(); QVERIFY(f.isStarted()); result.reportFinished(); f.cancel(); QVERIFY(result.isCanceled()); QVERIFY(f.isCanceled()); } // Results reported after canceled is called should not be propagated. { QFutureInterface<int> futureInterface; futureInterface.reportStarted(); QFuture<int> f = futureInterface.future(); int result = 0; futureInterface.reportResult(&result); result = 1; futureInterface.reportResult(&result); f.cancel(); result = 2; futureInterface.reportResult(&result); result = 3; futureInterface.reportResult(&result); futureInterface.reportFinished(); QCOMPARE(f.results(), QList<int>()); } }
QList<LocatorFilterEntry> FileSystemFilter::matchesFor(QFutureInterface<Core::LocatorFilterEntry> &future, const QString &entry) { QList<LocatorFilterEntry> goodEntries; QList<LocatorFilterEntry> betterEntries; QFileInfo entryInfo(entry); QString name = entryInfo.fileName(); QString directory = entryInfo.path(); QString filePath = entryInfo.filePath(); if (entryInfo.isRelative()) { if (filePath.startsWith(QLatin1String("~/"))) { directory.replace(0, 1, QDir::homePath()); } else { IDocument *document= EditorManager::currentDocument(); if (document && !document->filePath().isEmpty()) { QFileInfo info(document->filePath()); directory.prepend(info.absolutePath() + QLatin1Char('/')); } } } QDir dirInfo(directory); QDir::Filters dirFilter = QDir::Dirs|QDir::Drives|QDir::NoDot; QDir::Filters fileFilter = QDir::Files; if (m_includeHidden) { dirFilter |= QDir::Hidden; fileFilter |= QDir::Hidden; } // use only 'name' for case sensitivity decision, because we need to make the path // match the case on the file system for case-sensitive file systems const Qt::CaseSensitivity caseSensitivity_ = caseSensitivity(name); QStringList dirs = dirInfo.entryList(dirFilter, QDir::Name|QDir::IgnoreCase|QDir::LocaleAware); QStringList files = dirInfo.entryList(fileFilter, QDir::Name|QDir::IgnoreCase|QDir::LocaleAware); foreach (const QString &dir, dirs) { if (future.isCanceled()) break; if (QList<LocatorFilterEntry> *category = categorize(name, dir, caseSensitivity_, &betterEntries, &goodEntries)) { const QString fullPath = dirInfo.filePath(dir); LocatorFilterEntry filterEntry(this, dir, QVariant()); filterEntry.fileName = fullPath; category->append(filterEntry); } } // file names can match with +linenumber or :linenumber name = entry; const QString lineNoSuffix = EditorManager::splitLineNumber(&name); name = QFileInfo(name).fileName(); foreach (const QString &file, files) { if (future.isCanceled()) break; if (QList<LocatorFilterEntry> *category = categorize(name, file, caseSensitivity_, &betterEntries, &goodEntries)) { const QString fullPath = dirInfo.filePath(file); LocatorFilterEntry filterEntry(this, file, QString(fullPath + lineNoSuffix)); filterEntry.fileName = fullPath; category->append(filterEntry); } } betterEntries.append(goodEntries); // "create and open" functionality const QString fullFilePath = dirInfo.filePath(name); if (!QFileInfo(fullFilePath).exists() && dirInfo.exists()) { LocatorFilterEntry createAndOpen(this, tr("Create and Open \"%1\"").arg(entry), fullFilePath); createAndOpen.extraInfo = Utils::FileUtils::shortNativePath( Utils::FileName::fromString(dirInfo.absolutePath())); betterEntries.append(createAndOpen); } return betterEntries; }
void PchManager::doPchInfoUpdate(QFutureInterface<void> &future, ClangProjectSettings::PchUsage pchUsage, const QString customPchFile, const QList<ProjectPart::Ptr> projectParts) { PchManager *pchManager = PchManager::instance(); // qDebug() << "switching to" << pchUsage; if (pchUsage == ClangProjectSettings::PchUse_None || (pchUsage == ClangProjectSettings::PchUse_Custom && customPchFile.isEmpty())) { future.setProgressRange(0, 2); Core::MessageManager::write(QLatin1String("updatePchInfo: switching to none"), Core::MessageManager::Silent); PchInfo::Ptr emptyPch = PchInfo::createEmpty(); pchManager->setPCHInfo(projectParts, emptyPch, qMakePair(true, QStringList())); future.setProgressValue(1); } else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Fuzzy) { Core::MessageManager::write( QLatin1String("updatePchInfo: switching to build system (fuzzy)"), Core::MessageManager::Silent); QHash<QString, QSet<QString> > includes, frameworks; QHash<QString, QSet<QByteArray> > definesPerPCH; QHash<QString, bool> objc; QHash<QString, bool> cplusplus; QHash<QString, ProjectPart::QtVersion> qtVersions; QHash<QString, ProjectPart::CVersion> cVersions; QHash<QString, ProjectPart::CXXVersion> cxxVersions; QHash<QString, ProjectPart::CXXExtensions> cxxExtensionsMap; QHash<QString, QList<ProjectPart::Ptr> > inputToParts; foreach (const ProjectPart::Ptr &projectPart, projectParts) { if (projectPart->precompiledHeaders.isEmpty()) continue; const QString &pch = projectPart->precompiledHeaders.first(); // TODO: support more than 1 PCH file. if (!QFile(pch).exists()) continue; inputToParts[pch].append(projectPart); includes[pch].unite(QSet<QString>::fromList(projectPart->includePaths)); frameworks[pch].unite(QSet<QString>::fromList(projectPart->frameworkPaths)); cVersions[pch] = std::max(cVersions.value(pch, ProjectPart::C89), projectPart->cVersion); cxxVersions[pch] = std::max(cxxVersions.value(pch, ProjectPart::CXX98), projectPart->cxxVersion); cxxExtensionsMap[pch] = cxxExtensionsMap[pch] | projectPart->cxxExtensions; if (hasObjCFiles(projectPart)) objc[pch] = true; if (hasCppFiles(projectPart)) cplusplus[pch] = true; QSet<QByteArray> projectDefines = QSet<QByteArray>::fromList(projectPart->toolchainDefines.split('\n')); QMutableSetIterator<QByteArray> iter(projectDefines); while (iter.hasNext()){ QByteArray v = iter.next(); if (v.startsWith("#define _") || v.isEmpty()) // TODO: see ProjectPart::createClangOptions iter.remove(); } projectDefines.unite(QSet<QByteArray>::fromList(projectPart->projectDefines.split('\n'))); if (definesPerPCH.contains(pch)) { definesPerPCH[pch].intersect(projectDefines); } else { definesPerPCH[pch] = projectDefines; } qtVersions[pch] = projectPart->qtVersion; } future.setProgressRange(0, definesPerPCH.size() + 1); future.setProgressValue(0); foreach (const QString &pch, inputToParts.keys()) { if (future.isCanceled()) return; ProjectPart::Ptr projectPart(new ProjectPart); projectPart->qtVersion = qtVersions[pch]; projectPart->cVersion = cVersions[pch]; projectPart->cxxVersion = cxxVersions[pch]; projectPart->cxxExtensions = cxxExtensionsMap[pch]; projectPart->includePaths = includes[pch].toList(); projectPart->frameworkPaths = frameworks[pch].toList(); QList<QByteArray> defines = definesPerPCH[pch].toList(); if (!defines.isEmpty()) { projectPart->projectDefines = defines[0]; for (int i = 1; i < defines.size(); ++i) { projectPart->projectDefines += '\n'; projectPart->projectDefines += defines[i]; } } CppTools::ProjectFile::Kind prefixFileKind = getPrefixFileKind(objc.value(pch, false), cplusplus.value(pch, false)); QStringList options = Utils::createClangOptions(projectPart, prefixFileKind); projectPart.reset(); PchInfo::Ptr pchInfo = pchManager->findMatchingPCH(pch, options, true); QPair<bool, QStringList> msgs = qMakePair(true, QStringList()); if (pchInfo.isNull()) { pchInfo = PchInfo::createWithFileName(pch, options, objc[pch]); msgs = precompile(pchInfo); } pchManager->setPCHInfo(inputToParts[pch], pchInfo, msgs); future.setProgressValue(future.progressValue() + 1); } } else if (pchUsage == ClangProjectSettings::PchUse_BuildSystem_Exact) {