void PHPCodeCompletion::DoOpenEditorForEntry(PHPEntityBase::Ptr_t entry) { // Open the file (make sure we use the 'OpenFile' so we will get a browsing record) IEditor* editor = m_manager->OpenFile(entry->GetFilename().GetFullPath(), wxEmptyString, entry->GetLine()); if(editor) { // Select the word in the editor (its a new one) int selectFromPos = editor->GetCtrl()->PositionFromLine(entry->GetLine()); DoSelectInEditor(editor, entry->GetShortName(), selectFromPos); } }
PHPLocation::Ptr_t PHPCodeCompletion::FindDefinition(IEditor* editor, int pos) { CHECK_PHP_WORKSPACE_RET_NULL(); PHPLocation::Ptr_t loc; // Null if(IsPHPFile(editor)) { PHPEntityBase::Ptr_t resolved = GetPHPEntryUnderTheAtPos(editor, editor->GetCurrentPosition()); if(resolved) { loc = new PHPLocation; loc->filename = resolved->GetFilename().GetFullPath(); loc->linenumber = resolved->GetLine(); loc->what = resolved->GetShortName(); } } return loc; }
PHPLocation::Ptr_t PHPCodeCompletion::FindDefinition(IEditor* editor, int pos) { CHECK_PHP_WORKSPACE_RET_NULL(); PHPLocation::Ptr_t loc; // Null if(IsPHPFile(editor)) { PHPEntityBase::Ptr_t resolved = GetPHPEntityAtPos(editor, editor->GetCurrentPosition()); if(resolved) { if(resolved->Is(kEntityTypeFunctionAlias)) { // use the internal function resolved = resolved->Cast<PHPEntityFunctionAlias>()->GetFunc(); } loc = new PHPLocation; loc->filename = resolved->GetFilename().GetFullPath(); loc->linenumber = resolved->GetLine(); loc->what = resolved->GetShortName(); } } return loc; }
TagEntryPtr PHPCodeCompletion::DoPHPEntityToTagEntry(PHPEntityBase::Ptr_t entry) { TagEntryPtr t(new TagEntry()); // wxString name = entry->Is(kEntityTypeNamespace) ? entry->GetFullName() : entry->GetShortName(); wxString name = entry->GetShortName(); if(entry->Is(kEntityTypeVariable) && entry->Cast<PHPEntityVariable>()->IsMember() && name.StartsWith(wxT("$")) && !entry->Cast<PHPEntityVariable>()->IsStatic()) { name.Remove(0, 1); } else if((entry->Is(kEntityTypeClass) || entry->Is(kEntityTypeNamespace)) && name.StartsWith("\\")) { name.Remove(0, 1); } t->SetName(name); t->SetParent(entry->Parent() ? entry->Parent()->GetFullName() : ""); t->SetPattern(t->GetName()); // Set the document comment wxString comment, docComment; docComment = entry->GetDocComment(); if(docComment.IsEmpty() == false) { docComment.Trim().Trim(false); // The Doc comment comment << docComment << wxT("\n<hr>"); // HLine } wxFileName fn(entry->GetFilename()); fn.MakeRelativeTo(PHPWorkspace::Get()->GetFilename().GetPath()); comment << fn.GetFullName() << wxT(" : ") << entry->GetLine(); t->SetComment(comment); // Access if(entry->Is(kEntityTypeVariable)) { PHPEntityVariable* var = entry->Cast<PHPEntityVariable>(); // visibility if(var->IsPrivate()) t->SetAccess(wxT("private")); else if(var->IsProtected()) t->SetAccess(wxT("protected")); else t->SetAccess(wxT("public")); // type (affects icon) if(var->IsConst() || var->IsDefine()) { t->SetKind("macro"); } else { t->SetKind("variable"); } t->SetReturnValue(""); } else if(entry->Is(kEntityTypeFunction) || entry->Is(kEntityTypeFunctionAlias)) { PHPEntityFunction* func = NULL; if(entry->Is(kEntityTypeFunctionAlias)) { func = entry->Cast<PHPEntityFunctionAlias>()->GetFunc()->Cast<PHPEntityFunction>(); } else { func = entry->Cast<PHPEntityFunction>(); } if(func->HasFlag(kFunc_Private)) { t->SetAccess(wxT("private")); } else if(func->HasFlag(kFunc_Protected)) { t->SetAccess("protected"); } else { t->SetAccess(wxT("public")); } t->SetSignature(func->GetSignature()); t->SetPattern(func->GetShortName() + func->GetSignature()); t->SetKind("function"); } else if(entry->Is(kEntityTypeClass)) { t->SetAccess(wxT("public")); t->SetKind("class"); } else if(entry->Is(kEntityTypeNamespace)) { t->SetAccess("public"); t->SetKind("namespace"); } else if(entry->Is(kEntityTypeKeyword)) { t->SetAccess("public"); t->SetKind("cpp_keyword"); } t->SetFlags(TagEntry::Tag_No_Signature_Format); return t; }
void PHPExpression::Suggest(PHPEntityBase::Ptr_t resolved, PHPLookupTable& lookup, PHPEntityBase::List_t& matches) { // sanity if(!resolved) return; PHPEntityBase::Ptr_t currentScope = GetSourceFile()->CurrentScope(); // GetCount() == 0 && !GetFilter().IsEmpty() i.e. a word completion is required. // We enhance the list with the following: // - PHP keywords // - Global functions // - Global constants // - Function arguments // - Local variables (of the current scope) // - And aliases e.g. 'use foo\bar as Bar;' if(GetCount() == 0 && !GetFilter().IsEmpty()) { // For functions and constants, PHP will fall back to global functions or constants if a // namespaced function or constant does not exist. PHPEntityBase::List_t globals = lookup.FindGlobalFunctionAndConsts(PHPLookupTable::kLookupFlags_Contains, GetFilter()); matches.insert(matches.end(), globals.begin(), globals.end()); if(currentScope && (currentScope->Is(kEntityTypeFunction) || currentScope->Is(kEntityTypeNamespace))) { // If the current scope is a function // add the local variables + function arguments to the current list of matches const PHPEntityBase::List_t& children = currentScope->GetChildren(); PHPEntityBase::List_t::const_iterator iter = children.begin(); for(; iter != children.end(); ++iter) { PHPEntityBase::Ptr_t child = *iter; if(child->Is(kEntityTypeVariable) && child->GetShortName().Contains(GetFilter()) && child->GetShortName() != GetFilter()) { matches.push_back(child); } } } { // Add aliases PHPEntityBase::List_t aliases = GetSourceFile()->GetAliases(); PHPEntityBase::List_t::iterator iter = aliases.begin(); for(; iter != aliases.end(); ++iter) { if((*iter)->GetShortName().Contains(GetFilter())) { matches.push_back(*iter); } } } { // Add $this incase we are inside a class (but only if '$this' contains the filter string) wxString lcFilter = GetFilter().Lower(); if(GetSourceFile()->Class() && wxString("$this").Contains(lcFilter)) { PHPEntityBase::Ptr_t thiz(new PHPEntityVariable()); thiz->SetFullName("$this"); thiz->SetShortName("$this"); thiz->SetFilename(currentScope->GetFilename()); matches.push_back(thiz); } } } // Add the scoped matches // for the code completion size_t flags = PHPLookupTable::kLookupFlags_Contains | GetLookupFlags(); if(resolved->Is(kEntityTypeClass)) { if(resolved->Cast<PHPEntityClass>()->IsInterface() || resolved->Cast<PHPEntityClass>()->IsAbstractClass()) { flags |= PHPLookupTable::kLookupFlags_IncludeAbstractMethods; } } PHPEntityBase::List_t scopeChildren = lookup.FindChildren(resolved->GetDbId(), flags, GetFilter()); matches.insert(matches.end(), scopeChildren.begin(), scopeChildren.end()); // Incase the resolved is a namespace, suggest all children namespaces if(resolved->Is(kEntityTypeNamespace)) { PHPEntityBase::List_t namespaces = lookup.FindNamespaces(resolved->GetFullName(), GetFilter()); matches.insert(matches.end(), namespaces.begin(), namespaces.end()); } // and make the list unique DoMakeUnique(matches); }
void PHPDocVisitor::OnEntity(PHPEntityBase::Ptr_t entity) { // Locate a comment for this entity entity->SetFilename(m_sourceFile.GetFilename()); if(!entity->GetDocComment().IsEmpty()) { // PHPDoc was already assigned to this entity during the parsing phase if(entity->Is(kEntityTypeClass)) { // Process @property tags here PHPDocComment docComment(m_sourceFile, entity->GetDocComment()); if(!docComment.GetProperties().empty()) { // Got some @properties std::for_each(docComment.GetProperties().begin(), docComment.GetProperties().end(), [&](PHPDocComment::Property::Map_t::value_type& p) { PHPEntityBase::Ptr_t child = entity->FindChild(p.second.name); if(!child) { // No child of this type, create a new property and add it child.Reset(new PHPEntityVariable()); child->SetFilename(m_sourceFile.GetFilename()); child->SetLine(entity->GetLine()); child->Cast<PHPEntityVariable>()->SetTypeHint(p.second.type); child->Cast<PHPEntityVariable>()->SetFlag(kVar_Member); // Member variable child->Cast<PHPEntityVariable>()->SetFlag(kVar_Public); // Public access child->SetShortName(p.second.name); child->SetFullName(p.second.name); entity->AddChild(child); } }); } else if(!docComment.GetMethods().empty()) { std::for_each(docComment.GetMethods().begin(), docComment.GetMethods().end(), [&](PHPEntityBase::Ptr_t method) { entity->AddChild(method); }); } } } else { // search for the comment placed at the top of the variable // this is why we use here -1 int lineNum = (entity->GetLine() - 1); // for debugging purposes wxString entityName = entity->GetShortName(); wxUnusedVar(entityName); std::map<int, phpLexerToken>::iterator iter = m_comments.find(lineNum); if(iter == m_comments.end()) { // try to locate a comment on the same line ++lineNum; iter = m_comments.find(lineNum); } if(iter != m_comments.end()) { // we got a match entity->SetDocComment(iter->second.Text()); m_comments.erase(iter); PHPDocComment docComment(m_sourceFile, entity->GetDocComment()); if(entity->Is(kEntityTypeFunction) && !docComment.GetReturn().IsEmpty()) { entity->Cast<PHPEntityFunction>()->SetReturnValue(docComment.GetReturn()); } else if(entity->Is(kEntityTypeVariable) && !entity->Cast<PHPEntityVariable>()->IsFunctionArg()) { // A global variable, const or a member entity->Cast<PHPEntityVariable>()->SetTypeHint(docComment.GetVar()); } } else if(entity->Is(kEntityTypeVariable) && entity->Parent() && entity->Parent()->Is(kEntityTypeFunction) && entity->Cast<PHPEntityVariable>()->IsFunctionArg()) { // A function argument PHPDocComment docComment(m_sourceFile, entity->Parent()->GetDocComment()); wxString typeHint = docComment.GetParam(entity->GetFullName()); if(!typeHint.IsEmpty()) { entity->Cast<PHPEntityVariable>()->SetTypeHint(typeHint); } } } }
TagEntryPtr PHPCodeCompletion::DoPHPEntityToTagEntry(PHPEntityBase::Ptr_t entry) { TagEntryPtr t(new TagEntry()); // wxString name = entry->Is(kEntityTypeNamespace) ? entry->GetFullName() : entry->GetShortName(); wxString name = entry->GetShortName(); if(entry->Is(kEntityTypeVariable) && entry->Cast<PHPEntityVariable>()->IsMember() && name.StartsWith(wxT("$")) && !entry->Cast<PHPEntityVariable>()->IsStatic()) { name.Remove(0, 1); } else if((entry->Is(kEntityTypeClass) || entry->Is(kEntityTypeNamespace)) && name.StartsWith("\\")) { name.Remove(0, 1); } t->SetName(name); t->SetParent(entry->Parent() ? entry->Parent()->GetFullName() : ""); t->SetPattern(t->GetName()); t->SetComment(entry->GetDocComment()); // Access if(entry->Is(kEntityTypeVariable)) { PHPEntityVariable* var = entry->Cast<PHPEntityVariable>(); // visibility if(var->IsPrivate()) t->SetAccess(wxT("private")); else if(var->IsProtected()) t->SetAccess(wxT("protected")); else t->SetAccess(wxT("public")); // type (affects icon) if(var->IsConst() || var->IsDefine()) { t->SetKind("macro"); } else { t->SetKind("variable"); } t->SetReturnValue(""); } else if(entry->Is(kEntityTypeFunction)) { PHPEntityFunction* func = entry->Cast<PHPEntityFunction>(); if(func->HasFlag(kFunc_Private)) { t->SetAccess(wxT("private")); } else if(func->HasFlag(kFunc_Protected)) { t->SetAccess("protected"); } else { t->SetAccess(wxT("public")); } t->SetSignature(func->GetSignature()); t->SetPattern(func->GetShortName() + func->GetSignature()); t->SetKind("function"); } else if(entry->Is(kEntityTypeClass)) { t->SetAccess(wxT("public")); t->SetKind("class"); } else if(entry->Is(kEntityTypeNamespace)) { t->SetAccess("public"); t->SetKind("namespace"); } t->SetFlags(TagEntry::Tag_No_Signature_Format); return t; }