void CppEditorSupport::onDocumentUpdated(Document::Ptr doc) { if (doc.isNull()) return; if (doc->fileName() != fileName()) return; // some other document got updated if (doc->editorRevision() != editorRevision()) return; // outdated content, wait for a new document to be parsed // Update the ifdeffed-out blocks: if (m_highlightingSupport && !m_highlightingSupport->hightlighterHandlesIfdefedOutBlocks()) { QList<Document::Block> skippedBlocks = doc->skippedBlocks(); QList<BlockRange> ifdefedOutBlocks; ifdefedOutBlocks.reserve(skippedBlocks.size()); foreach (const Document::Block &block, skippedBlocks) ifdefedOutBlocks.append(BlockRange(block.begin(), block.end())); setIfdefedOutBlocks(ifdefedOutBlocks); }
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()); }
/*! Should insert at line 4, column 1, with "protected\n" as prefix and "\n" suffix. */ void CppToolsPlugin::test_codegen_protected_between_public_and_private() { const QByteArray src = "\n" "class Foo\n" // line 1 "{\n" "public:\n" // line 3 "private:\n" // line 4 "};\n" // line 5 "\n"; Document::Ptr doc = Document::create(QLatin1String("protected_betwee_public_and_private")); doc->setUtf8Source(src); doc->parse(); doc->check(); QCOMPARE(doc->diagnosticMessages().size(), 0); QCOMPARE(doc->globalSymbolCount(), 1U); Class *foo = doc->globalSymbolAt(0)->asClass(); QVERIFY(foo); QCOMPARE(foo->line(), 1U); QCOMPARE(foo->column(), 7U); Snapshot snapshot; snapshot.insert(doc); CppRefactoringChanges changes(snapshot); InsertionPointLocator find(changes); InsertionLocation loc = find.methodDeclarationInClass( doc->fileName(), foo, InsertionPointLocator::Protected); QVERIFY(loc.isValid()); QCOMPARE(loc.prefix(), QLatin1String("protected:\n")); QCOMPARE(loc.suffix(), QLatin1String("\n")); QCOMPARE(loc.column(), 1U); QCOMPARE(loc.line(), 4U); }
void CppToolsPlugin::test_codegen_definition_member_specific_file() { const QByteArray srcText = "\n" "class Foo\n" // line 1 "{\n" "void foo();\n" // line 3 "void bar();\n" // line 4 "void baz();\n" // line 5 "};\n" "\n" "void Foo::bar()\n" "{\n" "\n" "}\n"; const QByteArray dstText = QString::fromLatin1( "\n" "#include \"%1/file.h\"\n" // line 1 "int x;\n" "\n" "void Foo::foo()\n" // line 4 "{\n" "\n" "}\n" // line 7 "\n" "int y;\n").arg(QDir::tempPath()).toLatin1(); Document::Ptr src = Document::create(QDir::tempPath() + QLatin1String("/file.h")); Utils::FileSaver srcSaver(src->fileName()); srcSaver.write(srcText); srcSaver.finalize(); src->setUtf8Source(srcText); src->parse(); src->check(); QCOMPARE(src->diagnosticMessages().size(), 0); QCOMPARE(src->globalSymbolCount(), 2U); Document::Ptr dst = Document::create(QDir::tempPath() + QLatin1String("/file.cpp")); dst->addIncludeFile(Document::Include(QLatin1String("file.h"), src->fileName(), 1, Client::IncludeLocal)); Utils::FileSaver dstSaver(dst->fileName()); dstSaver.write(dstText); dstSaver.finalize(); dst->setUtf8Source(dstText); dst->parse(); dst->check(); QCOMPARE(dst->diagnosticMessages().size(), 0); QCOMPARE(dst->globalSymbolCount(), 3U); Snapshot snapshot; snapshot.insert(src); snapshot.insert(dst); Class *foo = src->globalSymbolAt(0)->asClass(); QVERIFY(foo); QCOMPARE(foo->line(), 1U); QCOMPARE(foo->column(), 7U); QCOMPARE(foo->memberCount(), 3U); Declaration *decl = foo->memberAt(2)->asDeclaration(); QVERIFY(decl); QCOMPARE(decl->line(), 5U); QCOMPARE(decl->column(), 6U); CppRefactoringChanges changes(snapshot); InsertionPointLocator find(changes); QList<InsertionLocation> locList = find.methodDefinition(decl, true, dst->fileName()); QVERIFY(locList.size() == 1); InsertionLocation loc = locList.first(); QCOMPARE(loc.fileName(), dst->fileName()); QCOMPARE(loc.line(), 7U); QCOMPARE(loc.column(), 2U); QCOMPARE(loc.prefix(), QLatin1String("\n\n")); QCOMPARE(loc.suffix(), QString()); }
void LocatorData::onDocumentUpdated(const Document::Ptr &doc) { QList<Entry> entries = FunctionFinder().run(doc); QMutexLocker l(&m_mutex); m_entries.insert(doc->fileName(), entries); }
void CppCurrentDocumentFilter::onDocumentUpdated(Document::Ptr doc) { if (m_currentFileName == doc->fileName()) m_itemsOfCurrentDoc.clear(); }
bool QtCreatorIntegration::navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames, QString *errorMessage) { typedef QMap<int, Document::Ptr> DocumentMap; const Utils::FileName currentUiFile = FormEditorW::activeEditor()->document()->filePath(); #if 0 return Designer::Internal::navigateToSlot(currentUiFile.toString(), objectName, signalSignature, parameterNames, errorMessage); #endif // TODO: we should pass to findDocumentsIncluding an absolute path to generated .h file from ui. // Currently we are guessing the name of ui_<>.h file and pass the file name only to the findDocumentsIncluding(). // The idea is that the .pro file knows if the .ui files is inside, and the .pro file knows it will // be generating the ui_<>.h file for it, and the .pro file knows what the generated file's name and its absolute path will be. // So we should somehow get that info from project manager (?) const QFileInfo fi = currentUiFile.toFileInfo(); const QString uiFolder = fi.absolutePath(); const QString uicedName = "ui_" + fi.completeBaseName() + ".h"; // Retrieve code model snapshot restricted to project of ui file or the working copy. Snapshot docTable = CppTools::CppModelManager::instance()->snapshot(); Snapshot newDocTable; const Project *uiProject = SessionManager::projectForFile(currentUiFile); if (uiProject) { for (Snapshot::const_iterator i = docTable.begin(), ei = docTable.end(); i != ei; ++i) { const Project *project = SessionManager::projectForFile(i.key()); if (project == uiProject) newDocTable.insert(i.value()); } } else { const CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const Utils::FileName configFileName = Utils::FileName::fromString(CppTools::CppModelManager::configurationFileName()); QHashIterator<Utils::FileName, QPair<QByteArray, unsigned> > it = workingCopy.iterator(); while (it.hasNext()) { it.next(); const Utils::FileName &fileName = it.key(); if (fileName != configFileName) newDocTable.insert(docTable.document(fileName)); } } docTable = newDocTable; // take all docs, find the ones that include the ui_xx.h. // Sort into a map, putting the ones whose path closely matches the ui-folder path // first in case there are project subdirectories that contain identical file names. const QList<Document::Ptr> docList = findDocumentsIncluding(docTable, uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file DocumentMap docMap; for (const Document::Ptr &d : docList) { const QFileInfo docFi(d->fileName()); docMap.insert(qAbs(docFi.absolutePath().compare(uiFolder, Qt::CaseInsensitive)), d); } if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size(); if (docMap.isEmpty()) { *errorMessage = tr("No documents matching \"%1\" could be found.\nRebuilding the project might help.").arg(uicedName); return false; } QDesignerFormWindowInterface *fwi = FormEditorW::activeWidgetHost()->formWindow(); const QString uiClass = uiClassName(fwi->mainContainer()->objectName()); if (Designer::Constants::Internal::debug) qDebug() << "Checking docs for " << uiClass; // Find the class definition (ui class defined as member or base class) // in the file itself or in the directly included files (order 1). QString namespaceName; const Class *cl = 0; Document::Ptr doc; for (const Document::Ptr &d : qAsConst(docMap)) { LookupContext context(d, docTable); const ClassDocumentPtrPair cd = findClassRecursively(context, uiClass, 1u , &namespaceName); if (cd.first) { cl = cd.first; doc = cd.second; break; } } if (!cl) { *errorMessage = msgClassNotFound(uiClass, docList); return false; } Overview o; const QString className = namespaceName + o.prettyName(cl->name()); if (Designer::Constants::Internal::debug) qDebug() << "Found class " << className << doc->fileName(); const QString functionName = "on_" + objectName + '_' + signalSignature; const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames); if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << "Found " << uiClass << doc->fileName() << " checking " << functionName << functionNameWithParameterNames; int line = 0; Document::Ptr sourceDoc; if (Function *fun = findDeclaration(cl, functionName)) { sourceDoc = findDefinition(fun, &line); if (!sourceDoc) { // add function definition to cpp file sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line); } } else { // add function declaration to cl CppTools::WorkingCopy workingCopy = CppTools::CppModelManager::instance()->workingCopy(); const QString fileName = doc->fileName(); getParsedDocument(fileName, workingCopy, docTable); addDeclaration(docTable, fileName, cl, functionNameWithParameterNames); // add function definition to cpp file sourceDoc = addDefinition(docTable, fileName, className, functionNameWithParameterNames, &line); } if (!sourceDoc) { *errorMessage = tr("Unable to add the method definition."); return false; } // jump to function definition, position within code Core::EditorManager::openEditorAt(sourceDoc->fileName(), line + 2, indentation); return true; }
bool QtCreatorIntegration::navigateToSlot(const QString &objectName, const QString &signalSignature, const QStringList ¶meterNames, QString *errorMessage) { const EditorData ed = m_few->activeEditor(); QTC_ASSERT(ed, return false) const QString currentUiFile = ed.formWindowEditor->file()->fileName(); #if 0 return Designer::Internal::navigateToSlot(currentUiFile, objectName, signalSignature, parameterNames, errorMessage); #endif // TODO: we should pass to findDocumentsIncluding an absolute path to generated .h file from ui. // Currently we are guessing the name of ui_<>.h file and pass the file name only to the findDocumentsIncluding(). // The idea is that the .pro file knows if the .ui files is inside, and the .pro file knows it will // be generating the ui_<>.h file for it, and the .pro file knows what the generated file's name and its absolute path will be. // So we should somehow get that info from project manager (?) const QFileInfo fi(currentUiFile); const QString uicedName = QLatin1String("ui_") + fi.completeBaseName() + QLatin1String(".h"); // Retrieve code model snapshot restricted to project of ui file. const ProjectExplorer::Project *uiProject = ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projectForFile(currentUiFile); if (!uiProject) { *errorMessage = tr("Internal error: No project could be found for %1.").arg(currentUiFile); return false; } CPlusPlus::Snapshot docTable = CppModelManagerInterface::instance()->snapshot(); CPlusPlus::Snapshot newDocTable; for (CPlusPlus::Snapshot::iterator it = docTable.begin(); it != docTable.end(); ++it) { const ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::instance()->session()->projectForFile(it.key()); if (project == uiProject) newDocTable.insert(it.value()); } docTable = newDocTable; // take all docs, find the ones that include the ui_xx.h. QList<Document::Ptr> docList = findDocumentsIncluding(docTable, uicedName, true); // change to false when we know the absolute path to generated ui_<>.h file if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << objectName << signalSignature << "Looking for " << uicedName << " returned " << docList.size(); if (docList.isEmpty()) { *errorMessage = tr("No documents matching '%1' could be found.\nRebuilding the project might help.").arg(uicedName); return false; } QDesignerFormWindowInterface *fwi = ed.widgetHost->formWindow(); const QString uiClass = uiClassName(fwi->mainContainer()->objectName()); if (Designer::Constants::Internal::debug) qDebug() << "Checking docs for " << uiClass; // Find the class definition (ui class defined as member or base class) // in the file itself or in the directly included files (order 1). QString namespaceName; const Class *cl = 0; Document::Ptr doc; foreach (const Document::Ptr &d, docList) { const ClassDocumentPtrPair cd = findClassRecursively(docTable, d, uiClass, 1u , &namespaceName); if (cd.first) { cl = cd.first; doc = cd.second; break; } } if (!cl) { *errorMessage = msgClassNotFound(uiClass, docList); return false; } Overview o; const QString className = namespaceName + o.prettyName(cl->name()); if (Designer::Constants::Internal::debug) qDebug() << "Found class " << className << doc->fileName(); const QString functionName = QLatin1String("on_") + objectName + QLatin1Char('_') + signalSignature; const QString functionNameWithParameterNames = addParameterNames(functionName, parameterNames); if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << "Found " << uiClass << doc->fileName() << " checking " << functionName << functionNameWithParameterNames; int line = 0; Document::Ptr sourceDoc; if (Function *fun = findDeclaration(cl, functionName)) { sourceDoc = findDefinition(fun, &line); if (!sourceDoc) { // add function definition to cpp file sourceDoc = addDefinition(docTable, doc->fileName(), className, functionNameWithParameterNames, &line); } } else { // add function declaration to cl CppModelManagerInterface::WorkingCopy workingCopy = CppModelManagerInterface::instance()->workingCopy(); const QString fileName = doc->fileName(); getParsedDocument(fileName, workingCopy, docTable); addDeclaration(docTable, fileName, cl, functionNameWithParameterNames); // add function definition to cpp file sourceDoc = addDefinition(docTable, fileName, className, functionNameWithParameterNames, &line); } if (!sourceDoc) { *errorMessage = tr("Unable to add the method definition."); return false; } // jump to function definition, position within code TextEditor::BaseTextEditorWidget::openEditorAt(sourceDoc->fileName(), line + 2, indentation); return true; }
void Snapshot::insert(Document::Ptr doc) { if (doc) _documents.insert(doc->fileName(), doc); }
QmlJSRefactoringFile::QmlJSRefactoringFile(TextEditor::TextEditorWidget *editor, Document::Ptr document) : RefactoringFile(editor) , m_qmljsDocument(document) { m_fileName = document->fileName(); }
void CppCurrentDocumentFilter::onDocumentUpdated(Document::Ptr doc) { QMutexLocker locker(&m_mutex); if (m_currentFileName == doc->fileName()) m_itemsOfCurrentDoc.clear(); }