Skip to content

Commit

Permalink
C++ code completion: a template parameter (e.g. "T") takes precedence…
Browse files Browse the repository at this point in the history
… over a container with the exact same name

that exists in the workspace symbols database
Added boost::shared_ptr unit test
  • Loading branch information
eranif committed Mar 17, 2016
1 parent 9053430 commit ed1e73c
Show file tree
Hide file tree
Showing 6 changed files with 126 additions and 154 deletions.
4 changes: 2 additions & 2 deletions CodeCompletionsTests/CCTest/cctest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -438,8 +438,8 @@ TEST_FUNC(testBoostSharedPtr)
std::vector<TagEntryPtr> tags;
TagsManagerST::Get()->AutoCompleteCandidates(wxFileName(wxT("../tests/boost_shared_ptr.h")),
2,
wxT("autoPtr->second->"),
LoadFile(wxT("../tests/test_auto_simple.h")),
wxT("s->"),
LoadFile(wxT("../tests/boost_shared_ptr.h")),
tags);
CHECK_SIZE(tags.size(), CLASS_WITH_MEMBERS_COUNT);
return true;
Expand Down
12 changes: 6 additions & 6 deletions CodeCompletionsTests/SampleWorkspace/SampleWorksapce.project
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<CodeLite_Project Name="SampleWorksapce" InternalType="">
<Plugins>
<Plugin Name="qmake">
<![CDATA[00010001N0005Debug000000000000]]>
</Plugin>
<Plugin Name="CMakePlugin">
<![CDATA[[{
"name": "Debug",
Expand All @@ -13,9 +16,6 @@
"parentProject": ""
}]]]>
</Plugin>
<Plugin Name="qmake">
<![CDATA[00010001N0005Debug000000000000]]>
</Plugin>
</Plugins>
<Description/>
<Dependencies/>
Expand Down Expand Up @@ -70,12 +70,12 @@
<CustomPostBuild/>
<CustomPreBuild/>
</AdditionalRules>
<Completion EnableCpp11="no" EnableCpp14="no">
<Completion EnableCpp11="yes" EnableCpp14="no">
<ClangCmpFlagsC/>
<ClangCmpFlags/>
<ClangPP/>
<SearchPaths>D:\src\wxWidgets\include
C:\src\codelite</SearchPaths>
<SearchPaths>C:\src\codelite
$BOOST_HOME</SearchPaths>
</Completion>
</Configuration>
<Configuration Name="Release" CompilerType="gnu g++" DebuggerType="GNU gdb debugger" Type="Dynamic Library" BuildCmpWithGlobalSettings="append" BuildLnkWithGlobalSettings="append" BuildResWithGlobalSettings="append">
Expand Down
6 changes: 4 additions & 2 deletions CodeCompletionsTests/SampleWorkspace/header.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <wxcrafter/wx_ordered_map.h>
#include <Plugin/workspace.h>
#include <set>
#include <boost/smart_ptr/shared_ptr.hpp>

struct ST {
std::string name;
Expand Down Expand Up @@ -131,12 +132,13 @@ typedef std::vector<ClassWithMembers> VectorTypedef_t;

// Template class with static member
template <class T>
class Foo
class FooTemplate
{
T* t;

public:
static T* Get() { return t; }
};

typedef Foo<ClassWithMembers> Foo_t;
//ContextManager::Get()->
typedef FooTemplate<ClassWithMembers> Foo_t;
82 changes: 37 additions & 45 deletions CodeLite/language.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,8 @@ ParsedToken* Language::ParseTokens(const wxString& scopeName)
}

if(result.m_isaType) {
pt->SetTypeScope(result.m_scope.empty() ? wxString(wxT("<global>")) :
wxString::From8BitData(result.m_scope.c_str()));
pt->SetTypeScope(
result.m_scope.empty() ? wxString(wxT("<global>")) : wxString::From8BitData(result.m_scope.c_str()));
pt->SetTypeName(wxString::From8BitData(result.m_name.c_str()));

} else if(result.m_isGlobalScope) {
Expand All @@ -156,8 +156,8 @@ ParsedToken* Language::ParseTokens(const wxString& scopeName)
// special handle for 'this' keyword
//-----------------------------------------

pt->SetTypeScope(result.m_scope.empty() ? wxString(wxT("<global>")) :
wxString::From8BitData(result.m_scope.c_str()));
pt->SetTypeScope(
result.m_scope.empty() ? wxString(wxT("<global>")) : wxString::From8BitData(result.m_scope.c_str()));
if(scopeName == wxT("<global>")) {
ParsedToken::DeleteTokens(header);
return NULL;
Expand Down Expand Up @@ -202,11 +202,11 @@ ParsedToken* Language::ParseTokens(const wxString& scopeName)
delim.Clear();
subscript = false;
}

if(header && header->GetNext() && header->GetName().IsEmpty() && header->GetOperator() == "::") {
// a chain with more than one token and the first token is simple "::"
// Delete the first token from the list
ParsedToken *newHeader = header->GetNext();
ParsedToken* newHeader = header->GetNext();
newHeader->SetPrev(NULL);
wxDELETE(header);
header = newHeader;
Expand Down Expand Up @@ -318,18 +318,16 @@ bool Language::NextToken(wxString& token, wxString& delim, bool& subscriptOperat

void Language::SetAutoCompDeliemters(const std::vector<wxString>& delimArr) { m_delimArr = delimArr; }

bool Language::ProcessExpression(const wxString& stmt,
const wxString& text,
const wxFileName& fn,
int lineno,
wxString& typeName, // output
wxString& typeScope, // output
wxString& oper, // output
wxString& scopeTemplateInitList) // output
bool Language::ProcessExpression(const wxString& stmt, const wxString& text, const wxFileName& fn, int lineno,
wxString& typeName, // output
wxString& typeScope, // output
wxString& oper, // output
wxString& scopeTemplateInitList) // output
{
CL_DEBUG(wxT(" >>> Language::ProcessExpression started ..."));

bool evaluationSucceeded = true;
m_templateArgs.clear();

wxString statement(stmt);

Expand Down Expand Up @@ -420,7 +418,7 @@ bool Language::ProcessExpression(const wxString& stmt,

if(container.current->GetIsTemplate() && container.current->GetTemplateArgList().IsEmpty()) {
// We got no template declaration...
container.current->SetTemplateArgList(DoExtractTemplateDeclarationArgs(container.current));
container.current->SetTemplateArgList(DoExtractTemplateDeclarationArgs(container.current), m_templateArgs);
}

int retryCount(0);
Expand Down Expand Up @@ -802,7 +800,7 @@ wxString Language::GetScopeName(const wxString& in, std::vector<wxString>* addit
wxArrayString moreScopes = GetTagsManager()->BreakToOuterScopes(scope);
for(size_t i = 0; i < moreScopes.GetCount(); i++) {
if(moreScopes.Item(i) != scope &&
std::find(additionlNS->begin(), additionlNS->end(), moreScopes.Item(i)) == additionlNS->end()) {
std::find(additionlNS->begin(), additionlNS->end(), moreScopes.Item(i)) == additionlNS->end()) {
additionlNS->push_back(moreScopes.Item(i));
}
}
Expand Down Expand Up @@ -855,7 +853,7 @@ bool Language::ProcessToken(TokenContainer* tokeContainer)

CL_DEBUG(wxT("Parsing for local variables..."));
CL_DEBUG1("Current scrope:\n%s\n", GetVisibleScope());

const wxCharBuffer buf = _C(GetVisibleScope());
const wxCharBuffer buf2 = _C(GetLastFunctionSignature() + wxT(";"));
get_variables(buf.data(), li, ignoreTokens, false);
Expand Down Expand Up @@ -953,7 +951,7 @@ bool Language::ProcessToken(TokenContainer* tokeContainer)
// if we are a "member" or " variable"
// try to locate the template initialization list
bool isTyperef = !tags.at(0)->GetTyperef().IsEmpty();

TagEntryPtr tag = tags.at(0);
if(!isTyperef && (tags.at(0)->GetKind() == wxT("member") || tags.at(0)->GetKind() == wxT("variable"))) {
const wxCharBuffer buf = _C(tags.at(0)->GetPattern());
Expand All @@ -978,10 +976,10 @@ bool Language::ProcessToken(TokenContainer* tokeContainer)
// Parse the definition list
CxxTemplateFunction ctf(tag);
ctf.ParseDefinitionList();

if(!ctf.GetList().IsEmpty()) {
token->SetIsTemplate(true);
token->SetTemplateArgList(ctf.GetList());
token->SetTemplateArgList(ctf.GetList(), m_templateArgs);
}
}
// fall through...
Expand All @@ -996,10 +994,8 @@ bool Language::ProcessToken(TokenContainer* tokeContainer)
return false;
}

bool Language::CorrectUsingNamespace(wxString& type,
wxString& typeScope,
const wxString& parentScope,
std::vector<TagEntryPtr>& tags)
bool Language::CorrectUsingNamespace(
wxString& type, wxString& typeScope, const wxString& parentScope, std::vector<TagEntryPtr>& tags)
{
wxString strippedScope(typeScope);
wxArrayString tmplInitList;
Expand Down Expand Up @@ -1047,12 +1043,8 @@ bool Language::CorrectUsingNamespace(wxString& type,
return true;
}

bool Language::DoSearchByNameAndScope(const wxString& name,
const wxString& scopeName,
std::vector<TagEntryPtr>& tags,
wxString& type,
wxString& typeScope,
bool testGlobalScope)
bool Language::DoSearchByNameAndScope(const wxString& name, const wxString& scopeName, std::vector<TagEntryPtr>& tags,
wxString& type, wxString& typeScope, bool testGlobalScope)
{
PERF_BLOCK("DoSearchByNameAndScope")
{
Expand Down Expand Up @@ -1343,7 +1335,7 @@ void Language::GetLocalVariables(const wxString& in, std::vector<TagEntryPtr>& t
// Don't suggest what we have typed so far
if(flags & PartialMatch && tmpTagName == tmpName) continue;
if(flags & ExactMatch && tmpTagName != tmpName) continue;

} // else no name is specified, collect all tags

TagEntryPtr tag(new TagEntry());
Expand Down Expand Up @@ -1533,7 +1525,7 @@ void Language::CheckForTemplateAndTypedef(ParsedToken* token)
if(tags.size() == 1 && !tags.at(0)->IsTypedef()) {

// Not a typedef
token->SetTemplateArgList(DoExtractTemplateDeclarationArgs(tags.at(0)));
token->SetTemplateArgList(DoExtractTemplateDeclarationArgs(tags.at(0)), m_templateArgs);
token->SetIsTemplate(token->GetTemplateArgList().IsEmpty() == false);

} else if(tags.size() == 1) {
Expand Down Expand Up @@ -1743,7 +1735,7 @@ wxString TemplateHelper::Substitute(const wxString& name)
if(where != wxNOT_FOUND) {
// it exists, return the name in the templateInstantiation list
if(templateInstantiationVector.at(i).GetCount() > (size_t)where &&
templateInstantiationVector.at(i).Item(where) != name)
templateInstantiationVector.at(i).Item(where) != name)
return templateInstantiationVector.at(i).Item(where);
}
}
Expand Down Expand Up @@ -1785,7 +1777,7 @@ void Language::SetAdditionalScopes(const std::vector<wxString>& additionalScopes
// "using namespace" may not contains current namespace, so make sure we add it
for(size_t i = 0; i < additionalScopes.size(); i++) {
if(!(std::find(this->m_additionalScopes.begin(), this->m_additionalScopes.end(), additionalScopes.at(i)) !=
this->m_additionalScopes.end())) {
this->m_additionalScopes.end())) {
this->m_additionalScopes.push_back(additionalScopes.at(i));
}
}
Expand Down Expand Up @@ -1873,6 +1865,11 @@ bool Language::DoIsTypeAndScopeExist(ParsedToken* token)
return true;
}

// Does the typename is happen to be a template argument?
if(m_templateArgs.count(token->GetTypeName())) {
return true;
}

wxString type(token->GetTypeName());
wxString scope(token->GetTypeScope());
bool res = GetTagsManager()->IsTypeAndScopeExists(type, scope);
Expand Down Expand Up @@ -1943,7 +1940,7 @@ void Language::DoExtractTemplateInitListFromInheritance(TagEntryPtr tag, ParsedT
if(tags.size() == 1) {
wxArrayString newArgList = DoExtractTemplateDeclarationArgs(tags.at(0));
if(newArgList.IsEmpty() == false) {
token->SetTemplateArgList(newArgList);
token->SetTemplateArgList(newArgList, m_templateArgs);
}
}
}
Expand Down Expand Up @@ -2011,7 +2008,7 @@ void Language::DoExtractTemplateArgsFromSelf(ParsedToken* token)
GetTagsManager()->FindByPath(token->GetPath(), tags);
if(tags.size() == 1 && !tags.at(0)->IsTypedef()) {
// Not a typedef
token->SetTemplateArgList(DoExtractTemplateDeclarationArgs(tags.at(0)));
token->SetTemplateArgList(DoExtractTemplateDeclarationArgs(tags.at(0)), m_templateArgs);
token->SetIsTemplate(token->GetTemplateArgList().IsEmpty() == false);
}
}
Expand Down Expand Up @@ -2094,10 +2091,8 @@ int Language::DoReadClassName(CppScanner& scanner, wxString& clsname) const
return 0;
}

bool Language::InsertFunctionDecl(const wxString& clsname,
const wxString& functionDecl,
wxString& sourceContent,
int visibility)
bool Language::InsertFunctionDecl(
const wxString& clsname, const wxString& functionDecl, wxString& sourceContent, int visibility)
{
// detemine the visibility requested
int typeVisibility = lexPUBLIC;
Expand Down Expand Up @@ -2228,11 +2223,8 @@ bool Language::InsertFunctionDecl(const wxString& clsname,
return true;
}

void Language::InsertFunctionImpl(const wxString& clsname,
const wxString& functionImpl,
const wxString& filename,
wxString& sourceContent,
int& insertedLine)
void Language::InsertFunctionImpl(const wxString& clsname, const wxString& functionImpl, const wxString& filename,
wxString& sourceContent, int& insertedLine)
{
insertedLine = wxNOT_FOUND;
if(sourceContent.EndsWith(wxT("\n")) == false) sourceContent << wxT("\n");
Expand Down
2 changes: 2 additions & 0 deletions CodeLite/language.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "comment.h"
#include <vector>
#include "codelite_exports.h"
#include <set>

enum SearchFlags {
PartialMatch = 0x00000001,
Expand Down Expand Up @@ -101,6 +102,7 @@ class WXDLLIMPEXP_CL Language
std::vector<wxString> m_additionalScopes; // collected by parsing 'using namespace XXX'
std::map<wxString, std::vector<wxString> > m_additionalScopesCache; // collected by parsing 'using namespace XXX'
TemplateHelper m_templateHelper;
std::set<wxString> m_templateArgs;

protected:
void SetVisibleScope(const wxString& visibleScope) { this->m_visibleScope = visibleScope; }
Expand Down
Loading

0 comments on commit ed1e73c

Please sign in to comment.