void DirectoryFilter::refresh(QFutureInterface<void> &future)
{
    QStringList directories;
    {
        QMutexLocker locker(&m_lock);
        if (m_directories.count() < 1) {
            files().clear();
            generateFileNames();
            future.setProgressRange(0, 1);
            future.setProgressValueAndText(1, tr("%1 filter update: 0 files").arg(displayName()));
            return;
        }
        directories = m_directories;
    }
    Utils::SubDirFileIterator it(directories, m_filters);
    future.setProgressRange(0, it.maxProgress());
    QStringList filesFound;
    while (!future.isCanceled() && it.hasNext()) {
        filesFound << it.next();
        if (future.isProgressUpdateNeeded()
                || future.progressValue() == 0 /*workaround for regression in Qt*/) {
            future.setProgressValueAndText(it.currentProgress(),
                                           tr("%1 filter update: %n files", 0, filesFound.size()).arg(displayName()));
        }
    }

    if (!future.isCanceled()) {
        QMutexLocker locker(&m_lock);
        files() = filesFound;
        generateFileNames();
        future.setProgressValue(it.maxProgress());
    } else {
        future.setProgressValueAndText(it.currentProgress(), tr("%1 filter update: canceled").arg(displayName()));
    }
}
Пример #2
0
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);
}
Пример #3
0
void DirectoryFilter::refresh(QFutureInterface<void> &future)
{
    QStringList directories;
    {
        QMutexLocker locker(&m_lock);
        if (m_directories.count() < 1) {
            m_files.clear();
            QTimer::singleShot(0, this, SLOT(updateFileIterator()));
            future.setProgressRange(0, 1);
            future.setProgressValueAndText(1, tr("%1 filter update: 0 files").arg(displayName()));
            return;
        }
        directories = m_directories;
    }
    Utils::SubDirFileIterator subDirIterator(directories, m_filters);
    future.setProgressRange(0, subDirIterator.maxProgress());
    QStringList filesFound;
    auto end = subDirIterator.end();
    for (auto it = subDirIterator.begin(); it != end; ++it) {
        if (future.isCanceled())
            break;
        filesFound << (*it).filePath;
        if (future.isProgressUpdateNeeded()
                || future.progressValue() == 0 /*workaround for regression in Qt*/) {
            future.setProgressValueAndText(subDirIterator.currentProgress(),
                                           tr("%1 filter update: %n files", 0, filesFound.size()).arg(displayName()));
        }
    }

    if (!future.isCanceled()) {
        QMutexLocker locker(&m_lock);
        m_files = filesFound;
        QTimer::singleShot(0, this, SLOT(updateFileIterator()));
        future.setProgressValue(subDirIterator.maxProgress());
    } else {
        future.setProgressValueAndText(subDirIterator.currentProgress(), tr("%1 filter update: canceled").arg(displayName()));
    }
}
Пример #4
0
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);
}
Пример #5
0
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) {