void TypeOfExpression::processEnvironment(Document::Ptr doc, Environment *env, QSet<QString> *processed) const { if (doc && ! processed->contains(doc->fileName())) { processed->insert(doc->fileName()); foreach (const Document::Include &incl, doc->includes()) processEnvironment(m_snapshot.document(incl.fileName()), env, processed); foreach (const Macro ¯o, doc->definedMacros()) env->bind(macro); }
void TypeOfExpression::processEnvironment(Snapshot documents, Document::Ptr doc, Environment *env, QSet<QString> *processed) const { if (! doc) return; if (processed->contains(doc->fileName())) return; processed->insert(doc->fileName()); foreach (const Document::Include &incl, doc->includes()) { processEnvironment(documents, documents.value(incl.fileName()), env, processed); } foreach (const Macro ¯o, doc->definedMacros()) env->bind(macro); }
QFuture<TextEditor::HighlightingResult> CppHighlightingSupportInternal::highlightingFuture( const Document::Ptr &doc, const Snapshot &snapshot) const { typedef TextEditor::HighlightingResult Result; QList<Result> macroUses; // Get macro definitions foreach (const CPlusPlus::Macro& macro, doc->definedMacros()) { int line, column; editor()->convertPosition(macro.offset(), &line, &column); ++column; //Highlighting starts at (column-1) --> compensate here Result use(line, column, macro.name().size(), MacroUse); macroUses.append(use); } // Get macro uses foreach (const Document::MacroUse ¯o, doc->macroUses()) { const QString name = QString::fromUtf8(macro.macro().name()); //Filter out QtKeywords if (isQtKeyword(QStringRef(&name))) continue; //Filter out C++ keywords SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); tokenize.setObjCEnabled(false); tokenize.setCxx0xEnabled(true); const QList<Token> tokens = tokenize(name); if (tokens.length() && (tokens.at(0).isKeyword() || tokens.at(0).isObjCAtKeyword())) continue; int line, column; editor()->convertPosition(macro.begin(), &line, &column); ++column; //Highlighting starts at (column-1) --> compensate here Result use(line, column, name.size(), MacroUse); macroUses.append(use); } LookupContext context(doc, snapshot); return CheckSymbols::go(doc, context, macroUses); }
void CppPreprocessor::mergeEnvironment(Document::Ptr doc) { if (!doc) return; const QString fn = doc->fileName(); if (m_processed.contains(fn)) return; m_processed.insert(fn); foreach (const Document::Include &incl, doc->resolvedIncludes()) { const QString includedFile = incl.resolvedFileName(); if (Document::Ptr includedDoc = m_snapshot.document(includedFile)) mergeEnvironment(includedDoc); else if (!m_included.contains(includedFile)) run(includedFile); } m_env.addMacros(doc->definedMacros()); }
void CppPreprocessor::sourceNeeded(unsigned line, const QString &fileName, IncludeType type) { typedef Document::DiagnosticMessage Message; if (fileName.isEmpty()) return; QString absoluteFileName = resolveFile(fileName, type); absoluteFileName = QDir::cleanPath(absoluteFileName); if (m_currentDoc) { m_currentDoc->addIncludeFile(Document::Include(fileName, absoluteFileName, line, type)); if (absoluteFileName.isEmpty()) { const QString text = QCoreApplication::translate( "CppPreprocessor", "%1: No such file or directory").arg(fileName); Message message(Message::Warning, m_currentDoc->fileName(), line, /*column =*/ 0, text); m_currentDoc->addDiagnosticMessage(message); return; } } if (m_included.contains(absoluteFileName)) return; // we've already seen this file. if (absoluteFileName != modelManager()->configurationFileName()) m_included.insert(absoluteFileName); // Already in snapshot? Use it! Document::Ptr doc = m_snapshot.document(absoluteFileName); if (doc) { mergeEnvironment(doc); return; } // Otherwise get file contents unsigned editorRevision = 0; QByteArray contents; const bool gotFileContents = getFileContents(absoluteFileName, &contents, &editorRevision); contents = convertToLatin1(contents); if (m_currentDoc && !gotFileContents) { const QString text = QCoreApplication::translate( "CppPreprocessor", "%1: Could not get file contents").arg(fileName); Message message(Message::Warning, m_currentDoc->fileName(), line, /*column =*/ 0, text); m_currentDoc->addDiagnosticMessage(message); return; } if (m_dumpFileNameWhileParsing) { qDebug() << "Parsing file:" << absoluteFileName << "contents:" << contents.size() << "bytes"; } doc = Document::create(absoluteFileName); doc->setRevision(m_revision); doc->setEditorRevision(editorRevision); const QFileInfo info(absoluteFileName); if (info.exists()) doc->setLastModified(info.lastModified()); const Document::Ptr previousDoc = switchDocument(doc); const QByteArray preprocessedCode = m_preprocess.run(absoluteFileName, contents); // { // QByteArray b(preprocessedCode); // b.replace("\n", "<<<\n"); // qDebug("Preprocessed code for \"%s\": [[%s]]", fileName.toUtf8().constData(), // b.constData()); // } QCryptographicHash hash(QCryptographicHash::Sha1); hash.addData(preprocessedCode); foreach (const Macro ¯o, doc->definedMacros()) { if (macro.isHidden()) { static const QByteArray undef("#undef "); hash.addData(undef); hash.addData(macro.name()); } else { static const QByteArray def("#define "); hash.addData(macro.name()); hash.addData(" ", 1); hash.addData(def); hash.addData(macro.definitionText()); } hash.addData("\n", 1); } doc->setFingerprint(hash.result()); Document::Ptr anotherDoc = m_globalSnapshot.document(absoluteFileName); if (anotherDoc && anotherDoc->fingerprint() == doc->fingerprint()) { switchDocument(previousDoc); mergeEnvironment(anotherDoc); m_snapshot.insert(anotherDoc); m_todo.remove(absoluteFileName); return; } doc->setUtf8Source(preprocessedCode); doc->keepSourceAndAST(); doc->tokenize(); m_snapshot.insert(doc); m_todo.remove(absoluteFileName); Process process(m_modelManager, doc, m_workingCopy); process(); (void) switchDocument(previousDoc); }