void Generator::GenerateClass(const Class& aClass, const std::string& aNameSpace, std::string& aCPPsrc) { std::string ns(""); if (aClass.nameSpace.empty()) ns = aNameSpace + aClass.name + "::"; else ns = aNameSpace + aClass.nameSpace + "::" + aClass.name + "::"; for (uint16_t i = 0; i < aClass.methods.size(); i++) { const Function& generatedMethod = aClass.methods[i]; if (!generatedMethod.hasBody) { // check if this method already exists in source file bool functionExists = false; for (uint16_t i = 0; i < m_declaredFunctions.size(); i++) { const Function& cppMethod = m_declaredFunctions[i]; if (DoesDeclarationMatch(cppMethod, generatedMethod, ns)) { functionExists = true; break; } } if (!functionExists) { uint32_t insertIndex = aCPPsrc.length(), declaredMethodIndex = 0; std::string methodSrc = GenerateMethod(generatedMethod, ns); // check if .cpp file uses our namespace. If it does, don't use namespace's prefix in the // generated function for (uint16_t i = 0; i < m_usedNamespaces.size(); i++) { if (methodSrc.find(m_usedNamespaces[i] + "::") == 0) methodSrc.erase(0, m_usedNamespaces[i].length() + 2); size_t pos; do { pos = methodSrc.find(" " + m_usedNamespaces[i] + "::"); if (pos != std::string::npos) methodSrc.erase(pos+1, m_usedNamespaces[i].length() + 2); } while (pos != std::string::npos); } methodSrc = "\n\n" + methodSrc; if (i > 0) { // find the string index at which previous method ends in source file const Function& previousMethod = aClass.methods[i - 1]; for (uint16_t j = 0; j < m_declaredFunctions.size(); j++) { const Function& cppMethod = m_declaredFunctions[j]; if (DoesDeclarationMatch(cppMethod, previousMethod, ns)) { insertIndex = cppMethod.endIndex; declaredMethodIndex = j; break; } } // update endIndexes for (uint16_t j = declaredMethodIndex + 1; j < m_declaredFunctions.size(); j++) { m_declaredFunctions[j].endIndex += methodSrc.size(); } } aCPPsrc.insert(insertIndex, methodSrc); } } } for (uint16_t i = 0; i < aClass.classes.size(); i++) { GenerateClass(aClass.classes[i], ns, aCPPsrc); } }
void ClassGenerateDialog::OnGenerateClick(wxCommandEvent& event) { if( m_txVirtualDir->GetValue().IsEmpty() ) { wxMessageBox( _("Virtual name cannot be empty"), _("CodeLite"), wxICON_WARNING | wxOK ); m_txVirtualDir->SetFocus(); return; } if (m_dirPicker->GetPath().IsEmpty()) { wxMessageBox( _("Folder name cannot be empty"), _("CodeLite"), wxICON_WARNING | wxOK ); m_dirPicker->SetFocus(); } m_textLog->Clear(); wxString err_msg; wxString project = m_txVirtualDir->GetValue().BeforeFirst(wxT(':')); ProjectPtr proj = m_mgr->GetWorkspace()->FindProjectByName(project, err_msg); if( proj ) { wxString filePath = m_dirPicker->GetPath();//proj->GetFileName().GetPath(); Table* pTable = wxDynamicCast(m_pItems, Table); if (pTable) { if (GenerateClass(pTable,filePath)) m_textLog->AppendText(pTable->GetName() + _("......... Generated successfully!\n")); else m_textLog->AppendText(pTable->GetName() + _("......... Error!!!\n")); } else { SerializableList::compatibility_iterator node = m_pItems->GetFirstChildNode(); while( node ) { Table* pTab = wxDynamicCast(node->GetData(),Table); if (pTab) { if (GenerateClass(pTab,filePath)) m_textLog->AppendText(pTab->GetName() + _("......... Generated successfully!\n")); else m_textLog->AppendText(pTab->GetName() + _("......... Error!!!\n")); } node = node->GetNext(); } } wxCommandEvent e(wxEVT_COMMAND_MENU_SELECTED, XRCID("retag_workspace")); m_mgr->GetTheApp()->GetTopWindow()->GetEventHandler()->AddPendingEvent(e); } }
void Generator::GenerateCPP(const std::string& aHeaderSource, std::string& aSource) { Parser parser(aHeaderSource); std::vector<Class> classes; parser.ParseHeader(classes); Parser srcParser(aSource); m_declaredFunctions.clear(); m_usedNamespaces.clear(); m_usedNamespaces.push_back(""); srcParser.ParseSource(m_declaredFunctions, m_usedNamespaces); for (uint16_t i = 0; i < classes.size(); i++) { GenerateClass(classes[i], "", aSource); } }