static Function *findDeclaration(const Class *cl, const QString &functionName) { const QString funName = QString::fromUtf8(QMetaObject::normalizedSignature(functionName.toUtf8())); const unsigned mCount = cl->memberCount(); // we are interested only in declarations (can be decl of function or of a field) // we are only interested in declarations of functions const Overview overview; for (unsigned j = 0; j < mCount; ++j) { // go through all members if (Declaration *decl = cl->memberAt(j)->asDeclaration()) if (Function *fun = decl->type()->asFunctionType()) { // Format signature QString memberFunction = overview.prettyName(fun->name()); memberFunction += '('; const uint aCount = fun->argumentCount(); for (uint i = 0; i < aCount; i++) { // we build argument types string const Argument *arg = fun->argumentAt(i)->asArgument(); if (i > 0) memberFunction += ','; memberFunction += overview.prettyType(arg->type()); } memberFunction += ')'; // we compare normalized signatures memberFunction = QString::fromUtf8(QMetaObject::normalizedSignature(memberFunction.toUtf8())); if (memberFunction == funName) // we match function names and argument lists return fun; } } return 0; }
static QByteArray typeId(Symbol *symbol) { if (symbol->asEnum()) { return QByteArray("e"); } else if (symbol->asFunction()) { return QByteArray("f"); } else if (symbol->asNamespace()) { return QByteArray("n"); } else if (symbol->asTemplate()) { return QByteArray("t"); } else if (symbol->asNamespaceAlias()) { return QByteArray("na"); } else if (symbol->asClass()) { return QByteArray("c"); } else if (symbol->asBlock()) { return QByteArray("b"); } else if (symbol->asUsingNamespaceDirective()) { return QByteArray("u"); } else if (symbol->asUsingDeclaration()) { return QByteArray("ud"); } else if (symbol->asDeclaration()) { QByteArray temp("d,"); Overview pretty; temp.append(pretty.prettyType(symbol->type()).toUtf8()); return temp; } else if (symbol->asArgument()) { return QByteArray("a"); } else if (symbol->asTypenameArgument()) { return QByteArray("ta"); } else if (symbol->asBaseClass()) { return QByteArray("bc"); } else if (symbol->asForwardClassDeclaration()) { return QByteArray("fcd"); } else if (symbol->asQtPropertyDeclaration()) { return QByteArray("qpd"); } else if (symbol->asQtEnum()) { return QByteArray("qe"); } else if (symbol->asObjCBaseClass()) { return QByteArray("ocbc"); } else if (symbol->asObjCBaseProtocol()) { return QByteArray("ocbp"); } else if (symbol->asObjCClass()) { return QByteArray("occ"); } else if (symbol->asObjCForwardClassDeclaration()) { return QByteArray("ocfd"); } else if (symbol->asObjCProtocol()) { return QByteArray("ocp"); } else if (symbol->asObjCForwardProtocolDeclaration()) { return QByteArray("ocfpd"); } else if (symbol->asObjCMethod()) { return QByteArray("ocm"); } else if (symbol->asObjCPropertyDeclaration()) { return QByteArray("ocpd"); } return QByteArray("unknown"); }
void tst_TypePrettyPrinter::basic() { QFETCH(FullySpecifiedType, type); QFETCH(QString, name); QFETCH(QString, result); Overview o; o.setShowReturnTypes(true); TypePrettyPrinter pp(&o); QCOMPARE(pp(type, name), result); }
void Frame::SwitchPanels(){ if(panel_login->IsShown()){ //Switch from login to overview SetSize(1400,850); panel_login->Hide(); panel_overview->Show(); SetMenuBar(menubar_overview); } else { //Switch from overview back to login SetSize(700,500); panel_overview->Hide(); panel_login->Show(); SetMenuBar(menubar_login); } Layout(); }//SwithPanels
// Find class definition in namespace (that is, the outer class // containing a member of the desired class type) or inheriting the desired class // in case of forms using the Multiple Inheritance approach static const Class *findClass(const Namespace *parentNameSpace, const LookupContext &context, const QString &className, QString *namespaceName) { if (Designer::Constants::Internal::debug) qDebug() << Q_FUNC_INFO << className; const Overview o; const unsigned namespaceMemberCount = parentNameSpace->memberCount(); for (unsigned i = 0; i < namespaceMemberCount; ++i) { // we go through all namespace members const Symbol *sym = parentNameSpace->memberAt(i); // we have found a class - we are interested in classes only if (const Class *cl = sym->asClass()) { // 1) we go through class members const unsigned classMemberCount = cl->memberCount(); for (unsigned j = 0; j < classMemberCount; ++j) if (Declaration *decl = cl->memberAt(j)->asDeclaration()) { // we want to know if the class contains a member (so we look into // a declaration) of uiClassName type QString nameToMatch; if (const NamedType *nt = decl->type()->asNamedType()) { nameToMatch = fullyQualifiedName(context, nt->name(), decl->enclosingScope()); // handle pointers to member variables } else if (PointerType *pt = decl->type()->asPointerType()) { if (NamedType *nt = pt->elementType()->asNamedType()) { nameToMatch = fullyQualifiedName(context, nt->name(), decl->enclosingScope()); } } if (!nameToMatch.isEmpty() && className == nameToMatch) return cl; } // decl // 2) does it inherit the desired class if (inherits(o, cl, className)) return cl; } else { // Check namespaces if (const Namespace *ns = sym->asNamespace()) { QString tempNS = *namespaceName; tempNS += o.prettyName(ns->name()); tempNS += "::"; if (const Class *cl = findClass(ns, context, className, &tempNS)) { *namespaceName = tempNS; return cl; } } // member is namespave } // member is no class } // for members return 0; }
void Frame::OnNewCourse(wxCommandEvent&){ CourseCreator cc(this, panel_overview->getCourses()); while (cc.ShowModal() == wxID_OK){ std::vector<wxString> data = cc.getData(); int ret = panel_overview->addNewCourse(data); if(ret >= 0){ SetStatusText(wxString("Succesfully added new course") << ret); return; } else if(ret == -1){ cc.DisplayError(ERROR_COURSE_ALREADY_EXISTS); } } SetStatusText(""); }//OnNewCourse
static void debugCppSymbolRecursion(QTextStream &str, const Overview &o, const Symbol &s, bool doRecurse = true, int recursion = 0) { for (int i = 0; i < recursion; i++) str << " "; str << "Symbol: " << o.prettyName(s.name()) << " at line " << s.line(); if (s.isFunction()) str << " function"; if (s.isClass()) str << " class"; if (s.isDeclaration()) str << " declaration"; if (s.isBlock()) str << " block"; if (doRecurse && s.isScope()) { const Scope *scoped = s.asScope(); const int size = scoped->memberCount(); str << " scoped symbol of " << size << '\n'; for (int m = 0; m < size; m++) debugCppSymbolRecursion(str, o, *scoped->memberAt(m), true, recursion + 1); } else { str << '\n'; } }
// Does klass inherit baseClass? static bool inherits(const Overview &o, const Class *klass, const QString &baseClass) { const unsigned int baseClassCount = klass->baseClassCount(); for (unsigned int b = 0; b < baseClassCount; ++b) if (o.prettyName(klass->baseClassAt(b)->name()) == baseClass) return true; return false; }
void Frame::OnExport(wxCommandEvent&){ SetStatusText("Exporting database..."); const char* dbname = panel_overview->getDatabaseFile(); std::string msg; bool exported = server_com->uploadDatabase(dbname, msg); if(exported) SetStatusText("Database exported"); else SetStatusText(wxString("Failed to export database: ") << msg); }//OnExport
CppDeclarableElement::CppDeclarableElement(Symbol *declaration) : CppElement() { icon = Icons().iconForSymbol(declaration); Overview overview; overview.showArgumentNames = true; overview.showReturnTypes = true; name = overview.prettyName(declaration->name()); if (declaration->enclosingScope()->isClass() || declaration->enclosingScope()->isNamespace() || declaration->enclosingScope()->isEnum()) { qualifiedName = overview.prettyName(LookupContext::fullyQualifiedName(declaration)); helpIdCandidates = stripName(qualifiedName); } else { qualifiedName = name; helpIdCandidates.append(name); } tooltip = overview.prettyType(declaration->type(), qualifiedName); link = CPPEditorWidget::linkToSymbol(declaration); helpMark = name; }
bool isOwnershipRAIIType(Symbol *symbol, const LookupContext &context) { if (!symbol) return false; // This is not a "real" comparison of types. What we do is to resolve the symbol // in question and then try to match its name with already known ones. if (symbol->isDeclaration()) { Declaration *declaration = symbol->asDeclaration(); const NamedType *namedType = declaration->type()->asNamedType(); if (namedType) { LookupScope *clazz = context.lookupType(namedType->name(), declaration->enclosingScope()); if (clazz && !clazz->symbols().isEmpty()) { Overview overview; Symbol *symbol = clazz->symbols().at(0); return isOwnershipRAIIName(overview.prettyName(symbol->name())); } } } return false; }
void Frame::OnNewCurriculum(wxCommandEvent&){ CurriculumCreator cc(this); while(cc.ShowModal() == wxID_OK){ std::vector<wxString> data = cc.getData(); int ret = panel_overview->addNewCurriculum(data); if(ret >= 0){ SetStatusText("Succesfully added new study program"); return; } else if(ret == -1){ cc.DisplayError(ERROR_CURRICULUM_ALREADY_EXISTS); } } SetStatusText(""); }//OnNewCurriculum
CppDeclarableElement::CppDeclarableElement(Symbol *declaration) : CppElement() { m_icon = Icons().iconForSymbol(declaration); Overview overview; overview.setShowArgumentNames(true); overview.setShowReturnTypes(true); m_name = overview.prettyName(declaration->name()); if (declaration->enclosingScope()->isClass() || declaration->enclosingScope()->isNamespace() || declaration->enclosingScope()->isEnum()) { m_qualifiedName = overview.prettyName(LookupContext::fullyQualifiedName(declaration)); setHelpIdCandidates(stripName(m_qualifiedName)); } else { m_qualifiedName = m_name; setHelpIdCandidates(QStringList(m_name)); } setTooltip(overview.prettyType(declaration->type(), m_qualifiedName)); setLink(CPPEditorWidget::linkToSymbol(declaration)); setHelpMark(m_name); }
QString CPlusPlus::toString(const Name *name, QString id) { Overview oo; return QString::fromLatin1("%0: %1").arg(id, name ? oo.prettyName(name) : QLatin1String("(null)")); }
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 TypePrettyPrinter::visit(Function *type) { if (_overview->showReturnTypes()) _text += _overview->prettyType(type->returnType()); if (! _ptrOperators.isEmpty()) { _text += QLatin1Char('('); applyPtrOperators(false); if (! _name.isEmpty()) { _text += _name; _name.clear(); } _text += QLatin1Char(')'); } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) { space(); _text += _name; _name.clear(); } if (_overview->showFunctionSignatures()) { Overview argumentText; argumentText.setShowReturnTypes(true); argumentText.setShowArgumentNames(false); argumentText.setShowFunctionSignatures(true); _text += QLatin1Char('('); for (unsigned index = 0; index < type->argumentCount(); ++index) { if (index != 0) _text += QLatin1String(", "); if (Argument *arg = type->argumentAt(index)->asArgument()) { if (index + 1 == _overview->markedArgument()) const_cast<Overview*>(_overview)->setMarkedArgumentBegin(_text.length()); const Name *name = 0; if (_overview->showArgumentNames()) name = arg->name(); _text += argumentText(arg->type(), name); if (const StringLiteral *initializer = arg->initializer()) { _text += QLatin1String(" ="); _text += QString::fromUtf8(initializer->chars(), initializer->size()); } if (index + 1 == _overview->markedArgument()) const_cast<Overview*>(_overview)->setMarkedArgumentEnd(_text.length()); } } if (type->isVariadic()) _text += QLatin1String("..."); _text += QLatin1Char(')'); if (type->isConst() && type->isVolatile()) { space(); _text += "const volatile"; } else if (type->isConst()) { space(); _text += "const"; } else if (type->isVolatile()) { space(); _text += "volatile"; } } }
void Frame::OnDeleteYear(wxCommandEvent&){ panel_overview->OnDeleteYear(this); }//OnDeleteYear
void TypePrettyPrinter::visit(Function *type) { if (_needsParens) { _text.prepend(QLatin1Char('(')); if (! _name.isEmpty()) { appendSpace(); _text.append(_name); _name.clear(); } _text.append(QLatin1Char(')')); _needsParens = false; } else if (! _name.isEmpty() && _overview->showFunctionSignatures) { appendSpace(); _text.append(_name); _name.clear(); } if (_overview->showReturnTypes) { const QString returnType = _overview->prettyType(type->returnType()); if (!returnType.isEmpty()) { if (!endsWithPtrOrRef(returnType)) _text.prepend(QLatin1Char(' ')); _text.prepend(returnType); } } if (_overview->showFunctionSignatures) { Overview argumentText; argumentText.showReturnTypes = true; argumentText.showArgumentNames = false; argumentText.showFunctionSignatures = true; _text += QLatin1Char('('); for (unsigned index = 0; index < type->argumentCount(); ++index) { if (index != 0) _text += QLatin1String(", "); if (Argument *arg = type->argumentAt(index)->asArgument()) { if (index + 1 == _overview->markedArgument) const_cast<Overview*>(_overview)->markedArgumentBegin = _text.length(); const Name *name = 0; if (_overview->showArgumentNames) name = arg->name(); _text += argumentText.prettyType(arg->type(), name); if (_overview->showDefaultArguments) { if (const StringLiteral *initializer = arg->initializer()) { _text += QLatin1String(" ="); _text += QString::fromUtf8(initializer->chars(), initializer->size()); } } if (index + 1 == _overview->markedArgument) const_cast<Overview*>(_overview)->markedArgumentEnd = _text.length(); } } if (type->isVariadic()) _text += QLatin1String("..."); _text += QLatin1Char(')'); if (type->isConst()) { appendSpace(); _text += "const"; } if (type->isVolatile()) { appendSpace(); _text += "volatile"; } } }
void TypePrettyPrinter::visit(Function *type) { if (_overview->showReturnTypes()) out(_overview->prettyType(type->returnType())); if (! _ptrOperators.isEmpty()) { out(QLatin1Char('(')); applyPtrOperators(false); if (! _name.isEmpty()) { _text += _name; _name.clear(); } out(QLatin1Char(')')); } else if (! _name.isEmpty() && _overview->showFunctionSignatures()) { space(); out(_name); _name.clear(); } if (_overview->showFunctionSignatures()) { Overview argumentText; argumentText.setShowReturnTypes(true); argumentText.setShowArgumentNames(false); argumentText.setShowFunctionSignatures(true); out(QLatin1Char('(')); for (unsigned index = 0; index < type->argumentCount(); ++index) { if (index != 0) out(QLatin1String(", ")); if (Argument *arg = type->argumentAt(index)->asArgument()) { if (index + 1 == _overview->markArgument()) out(QLatin1String("<b>")); Name *name = 0; if (_overview->showArgumentNames()) name = arg->name(); out(argumentText(arg->type(), name)); if (index + 1 == _overview->markArgument()) out(QLatin1String("</b>")); } } if (type->isVariadic()) out(QLatin1String("...")); out(QLatin1Char(')')); if (type->isConst() && type->isVolatile()) { space(); out("const volatile"); } else if (type->isConst()) { space(); out("const"); } else if (type->isVolatile()) { space(); out("volatile"); } } }
void Frame::OnDeleteCurriculum(wxCommandEvent&){ panel_overview->OnDeleteCurriculum(this); }//OnDeleteCurriculum
void Frame::OnDeleteAll(wxCommandEvent&){ panel_overview->OnDeleteAll(); }//OnDeleteAll
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; }
QString CPlusPlus::toString(FullySpecifiedType ty, QString id) { Overview oo; return QString::fromLatin1("%0: %1 (a %2)").arg(id, oo.prettyType(ty), QLatin1String(ty.type() ? typeid(*ty.type()).name() : "(null)")); }
Utils::ChangeSet FunctionDeclDefLink::changes(const Snapshot &snapshot, int targetOffset) { Utils::ChangeSet changes; // parse the current source declaration TypeOfExpression typeOfExpression; // ### just need to preprocess... typeOfExpression.init(sourceDocument, snapshot); QString newDeclText = linkSelection.selectedText(); for (int i = 0; i < newDeclText.size(); ++i) { if (newDeclText.at(i).toAscii() == 0) newDeclText[i] = QLatin1Char('\n'); } newDeclText.append(QLatin1String("{}")); const QString newDeclTextPreprocessed = typeOfExpression.preprocess(newDeclText); Document::Ptr newDeclDoc = Document::create(QLatin1String("<decl>")); newDeclDoc->setSource(newDeclTextPreprocessed.toUtf8()); newDeclDoc->parse(Document::ParseDeclaration); newDeclDoc->check(); // extract the function symbol if (!newDeclDoc->translationUnit()->ast()) return changes; FunctionDefinitionAST *newDef = newDeclDoc->translationUnit()->ast()->asFunctionDefinition(); if (!newDef) return changes; Function *newFunction = newDef->symbol; if (!newFunction) return changes; Overview overview; overview.setShowReturnTypes(true); overview.setShowTemplateParameters(true); overview.setShowArgumentNames(true); overview.setShowFunctionSignatures(true); // abort if the name of the newly parsed function is not the expected one DeclaratorIdAST *newDeclId = getDeclaratorId(newDef->declarator); if (!newDeclId || !newDeclId->name || !newDeclId->name->name || overview(newDeclId->name->name) != nameInitial) { return changes; } LookupContext sourceContext(sourceDocument, snapshot); LookupContext targetContext(targetFile->cppDocument(), snapshot); // sync return type { // set up for rewriting return type SubstitutionEnvironment env; env.setContext(sourceContext); env.switchScope(sourceFunction->enclosingScope()); ClassOrNamespace *targetCoN = targetContext.lookupType(targetFunction->enclosingScope()); if (!targetCoN) targetCoN = targetContext.globalNamespace(); UseMinimalNames q(targetCoN); env.enter(&q); Control *control = sourceContext.control().data(); // get return type start position and declarator info from declaration DeclaratorAST *declarator = 0; SpecifierAST *firstReplaceableSpecifier = 0; TranslationUnit *targetTranslationUnit = targetFile->cppDocument()->translationUnit(); if (SimpleDeclarationAST *simple = targetDeclaration->asSimpleDeclaration()) { declarator = simple->declarator_list->value; firstReplaceableSpecifier = findFirstReplaceableSpecifier( targetTranslationUnit, simple->decl_specifier_list); } else if (FunctionDefinitionAST *def = targetDeclaration->asFunctionDefinition()) { declarator = def->declarator; firstReplaceableSpecifier = findFirstReplaceableSpecifier( targetTranslationUnit, def->decl_specifier_list); } int returnTypeStart = 0; if (firstReplaceableSpecifier) returnTypeStart = targetFile->startOf(firstReplaceableSpecifier); else returnTypeStart = targetFile->startOf(declarator); if (!newFunction->returnType().isEqualTo(sourceFunction->returnType()) && !newFunction->returnType().isEqualTo(targetFunction->returnType())) { FullySpecifiedType type = rewriteType(newFunction->returnType(), &env, control); const QString replacement = overview(type, targetFunction->name()); changes.replace(returnTypeStart, targetFile->startOf(targetFunctionDeclarator->lparen_token), replacement); } } // sync parameters { // set up for rewriting parameter types SubstitutionEnvironment env; env.setContext(sourceContext); env.switchScope(sourceFunction); ClassOrNamespace *targetCoN = targetContext.lookupType(targetFunction); if (!targetCoN) targetCoN = targetContext.globalNamespace(); UseMinimalNames q(targetCoN); env.enter(&q); Control *control = sourceContext.control().data(); Overview overview; const unsigned sourceArgCount = declaredArgumentCount(sourceFunction); const unsigned newArgCount = declaredArgumentCount(newFunction); const unsigned targetArgCount = declaredArgumentCount(targetFunction); // check if parameter types or names have changed const unsigned existingArgs = qMin(targetArgCount, newArgCount); ParameterDeclarationClauseAST *targetParameterDecl = targetFunctionDeclarator->parameter_declaration_clause; ParameterDeclarationListAST *firstTargetParameterDeclIt = targetParameterDecl ? targetParameterDecl->parameter_declaration_list : 0; ParameterDeclarationListAST *targetParameterDeclIt = firstTargetParameterDeclIt; for (unsigned i = 0; i < existingArgs && targetParameterDeclIt; ++i, targetParameterDeclIt = targetParameterDeclIt->next) { Symbol *targetParam = targetFunction->argumentAt(i); Symbol *newParam = newFunction->argumentAt(i); // if new's name and type are the same as source's, forbid changes bool allowChangeType = true; const Name *replacementName = newParam->name(); if (i < sourceArgCount) { Symbol *sourceParam = sourceFunction->argumentAt(i); if (newParam->type().isEqualTo(sourceParam->type())) allowChangeType = false; if (namesEqual(replacementName, sourceParam->name())) replacementName = targetParam->name(); } // don't change the name if it's in a comment if (hasCommentedName(targetFile->cppDocument()->translationUnit(), targetFile->cppDocument()->source(), targetFunctionDeclarator, i)) replacementName = 0; // find the end of the parameter declaration ParameterDeclarationAST *targetParamAst = targetParameterDeclIt->value; int parameterNameEnd = 0; if (targetParamAst->declarator) parameterNameEnd = targetFile->endOf(targetParamAst->declarator); else if (targetParamAst->type_specifier_list) parameterNameEnd = targetFile->endOf(targetParamAst->type_specifier_list->lastToken() - 1); else parameterNameEnd = targetFile->startOf(targetParamAst); // change name and type? if (allowChangeType && !targetParam->type().isEqualTo(newParam->type())) { FullySpecifiedType replacementType = rewriteType(newParam->type(), &env, control); const QString replacement = overview(replacementType, replacementName); changes.replace(targetFile->startOf(targetParamAst), parameterNameEnd, replacement); } // change the name only? else if (!namesEqual(targetParam->name(), replacementName)) { DeclaratorIdAST *id = getDeclaratorId(targetParamAst->declarator); QString replacementNameStr = overview(replacementName); if (id) { changes.replace(targetFile->range(id), replacementNameStr); } else { // add name to unnamed parameter replacementNameStr.prepend(QLatin1Char(' ')); int end; if (targetParamAst->equal_token) { end = targetFile->startOf(targetParamAst->equal_token); replacementNameStr.append(QLatin1Char(' ')); } else { // one past end on purpose end = targetFile->startOf(targetParamAst->lastToken()); } changes.replace(parameterNameEnd, end, replacementNameStr); } } } // remove some parameters? if (newArgCount < targetArgCount) { targetParameterDeclIt = firstTargetParameterDeclIt; if (targetParameterDeclIt) { if (newArgCount == 0) { changes.remove(targetFile->startOf(targetParameterDeclIt->firstToken()), targetFile->endOf(targetParameterDeclIt->lastToken() - 1)); } else { // get the last valid argument for (unsigned i = 0; i < newArgCount - 1 && targetParameterDeclIt; ++i) targetParameterDeclIt = targetParameterDeclIt->next; if (targetParameterDeclIt) { const int start = targetFile->endOf(targetParameterDeclIt->value); const int end = targetFile->endOf(targetParameterDecl->lastToken() - 1); changes.remove(start, end); } } } } // add some parameters? else if (newArgCount > targetArgCount) { QString newParams; for (unsigned i = targetArgCount; i < newArgCount; ++i) { Symbol *param = newFunction->argumentAt(i); FullySpecifiedType type = rewriteType(param->type(), &env, control); if (i != 0) newParams += QLatin1String(", "); newParams += overview(type, param->name()); } targetParameterDeclIt = firstTargetParameterDeclIt; if (targetParameterDeclIt) { while (targetParameterDeclIt->next) targetParameterDeclIt = targetParameterDeclIt->next; changes.insert(targetFile->endOf(targetParameterDeclIt->value), newParams); } else { changes.insert(targetFile->endOf(targetFunctionDeclarator->lparen_token), newParams); } } } // sync cv qualification if (targetFunction->isConst() != newFunction->isConst() || targetFunction->isVolatile() != newFunction->isVolatile()) { QString cvString; if (newFunction->isConst()) cvString += QLatin1String("const"); if (newFunction->isVolatile()) { if (!cvString.isEmpty()) cvString += QLatin1Char(' '); cvString += QLatin1String("volatile"); } const int rparenEnd = targetFile->endOf(targetFunctionDeclarator->rparen_token); if (targetFunctionDeclarator->cv_qualifier_list) { const int cvEnd = targetFile->endOf(targetFunctionDeclarator->cv_qualifier_list->lastToken() - 1); // if the qualifies changed, replace if (!cvString.isEmpty()) { changes.replace(targetFile->startOf(targetFunctionDeclarator->cv_qualifier_list->firstToken()), cvEnd, cvString); } else { // remove changes.remove(rparenEnd, cvEnd); } } else { // otherwise add cvString.prepend(QLatin1Char(' ')); changes.insert(rparenEnd, cvString); } } if (targetOffset != -1) { // move all change operations to have the right start offset const int moveAmount = targetOffset - targetFile->startOf(targetDeclaration); QList<Utils::ChangeSet::EditOp> ops = changes.operationList(); for (int i = 0; i < ops.size(); ++i) { ops[i].pos1 += moveAmount; ops[i].pos2 += moveAmount; } changes = Utils::ChangeSet(ops); } return changes; }
void Frame::OnNewYear(wxCommandEvent&){ panel_overview->addNewYear(this); }//OnNewYear