ide: Fixed issue with enum variables #1262

git-svn-id: svn://ultimatepp.org/upp/trunk@8927 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2015-09-14 14:55:45 +00:00
parent fa8a42603c
commit 5ebe8cd59c
4 changed files with 33 additions and 222 deletions

View file

@ -433,6 +433,7 @@ struct CppBase : ArrayMap<String, Array<CppItem> > {
struct Parser {
struct Context {
String ns;
String scope;
String ctname;
Vector<int> tparam;
@ -555,7 +556,7 @@ struct Parser {
void Do();
String AnonymousName();
String StructDeclaration(const String& tp, const String& tn);
void Enum();
void Enum(bool vars);
CppItem& Item(const String& scope, const String& using_namespace, const String& item,
const String& name, bool impl);
@ -576,6 +577,7 @@ struct Parser {
void Statement();
void Locals(const String& type);
String Tparam(int& q);
bool IsNamespace(const String& scope);
friend class Lex; // Fix to make Lex::ThrowError

View file

@ -324,6 +324,7 @@ inline void ScopeCat(String& scope, const String& s)
void Parser::Context::operator<<=(const Context& t)
{
ns = t.ns;
scope = t.scope;
typenames = clone(t.typenames);
tparam = clone(t.tparam);
@ -332,6 +333,12 @@ void Parser::Context::operator<<=(const Context& t)
namespace_using = t.namespace_using;
}
bool Parser::IsNamespace(const String& scope)
{
int l = scope.GetCount();
return memcmp(~context.ns, ~scope, l) == 0 && findarg(context.ns[l], '\0', ':') >= 0;
}
Parser::Decla::Decla()
{
function = type_def = false;
@ -1273,6 +1280,7 @@ bool Parser::Scope(const String& tp, const String& tn) {
c0 <<= context;
int struct_level0 = struct_level;
ScopeCat(context.scope, name);
ScopeCat(context.ns, name);
AddNamespace(context.scope, name);
if(Key('{')) {
Context cc;
@ -1374,12 +1382,12 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body,
im.at = im.natural.GetLength();
}
im.natural << Purify(d.natural, d.name, nm);
im.kind = templ.GetCount() ? IsNull(scope) ? FUNCTIONTEMPLATE
im.kind = templ.GetCount() ? IsNamespace(scope) ? FUNCTIONTEMPLATE
: d.s_static ? CLASSFUNCTIONTEMPLATE
: INSTANCEFUNCTIONTEMPLATE
: d.istructor ? (d.isdestructor ? DESTRUCTOR : CONSTRUCTOR)
: d.isfriend ? INLINEFRIEND
: IsNull(scope) ? FUNCTION
: IsNamespace(scope) ? FUNCTION
: d.s_static ? CLASSFUNCTION
: INSTANCEFUNCTION;
im.param = param;
@ -1397,7 +1405,7 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body,
return im;
}
void Parser::Enum()
void Parser::Enum(bool vars)
{
String name;
if(lex.IsId())
@ -1424,7 +1432,19 @@ void Parser::Enum()
}
}
while(!Key(';')) {
if(lex.IsId() || lex == ',' || lex == '*') // typedef name ignored here
if(lex.IsId()) {
if(vars) { // typedef name ignored here
String scope = context.scope;
String name = lex.GetId();
CppItem& im = Item(scope, context.namespace_using, name, name);
im.natural = "enum " + name;
im.access = context.access;
im.kind = IsNamespace(scope) ? VARIABLE : INSTANCEVARIABLE;
}
++lex;
}
else
if(lex == ',' || lex == '*')
++lex;
else
break;
@ -1498,7 +1518,7 @@ void Parser::ClassEnum()
im.ptype.Clear();
im.pname.Clear();
im.param.Clear();
Enum();
Enum(true);
context = pick(cc);
SetScopeCurrent();
}
@ -1603,7 +1623,7 @@ void Parser::Do()
else
if(lex == tk_enum && IsEnum(1)) {
++lex;
Enum();
Enum(true);
}
else
if(lex == tk_enum && lex[1] == tk_class && IsEnum(2)) {
@ -1615,7 +1635,7 @@ void Parser::Do()
if(lex == tk_typedef && lex[1] == tk_enum && IsEnum(2)) {
++lex;
++lex;
Enum();
Enum(false);
}
else
if(!Scope(String(), String())) {
@ -1670,7 +1690,7 @@ void Parser::Do()
im.access = context.access;
im.kind = d.isfriend ? FRIENDCLASS :
d.type_def ? TYPEDEF :
IsNull(scope) ? VARIABLE :
IsNamespace(scope) ? VARIABLE :
member_type;
if(im.IsData())
im.isptr = d.isptr;
@ -1729,7 +1749,7 @@ void Parser::Do(Stream& in, CppBase& _base, int filei_, int filetype_,
context.access = PUBLIC;
context.typenames.Clear();
context.tparam.Clear();
context.scope = Join(namespace_stack, "::");
context.ns = context.scope = Join(namespace_stack, "::");
inbody = false;
struct_level = 0;
for(int i = 0; i < typenames.GetCount(); i++)

View file

@ -66,7 +66,7 @@ void Ide::FindId(const String& id)
int pos = editor.GetCursor();
int h = min(editor.GetLength(), pos + 4000);
for(;;) {
if(pos >= h || findarg(editor[pos], ';', '{', '}') >= 0)
if(pos >= h || editor[pos] == ';')
break;
if(iscib(editor[pos])) {
int p0 = pos;

View file

@ -2,217 +2,6 @@
#define LLOG(x) // DLOG(x)
#if 0 // TODO: Remove later...
struct GotoDlg : public WithGotoLayout<TopWindow> {
bool global;
Array<CppItemInfo> item;
Index<String> type;
CppBase lbase;
CppBase *gbase;
void SyncList();
int GetLine();
void SyncOk();
void Serialize(Stream& s);
typedef GotoDlg CLASSNAME;
GotoDlg(const String& s);
};
void GotoDlg::SyncList()
{
list.Clear();
String n = ToLower((String)~target);
int typei = Null;
String scope = Null;
Vector<String> h = Split(n, ':');
if(n[0] == ':') {
if(h.GetCount() > 1 && *n.Last() != ':') {
n = h.Top();
h.Drop();
}
else
n.Clear();
scope = Join(h, "::");
}
else
if(h.GetCount() > 1 || h.GetCount() == 1 && *n.Last() == ':') {
if(h.GetCount() > 1 && *n.Last() != ':') {
n = h.Top();
h.Drop();
}
else
n.Clear();
typei = type.Find(Join(h, "::"));
if(typei < 0)
typei = -1;
}
if(IsDigit(*n))
n.Clear();
Index<String> nc;
for(int i = 0; i < item.GetCount(); i++) {
const CppItemInfo& f = item[i];
if(ToLower(f.name).Find(n) >= 0 && (IsNull(typei) || typei == f.typei) && (IsNull(scope) || scope == f.scope)) {
list.Add(f.scope, RawToValue(f), f.item, f.line, GetSourceFilePath(f.file), f.scope);
nc.FindAdd(f.scope);
}
}
/*
for(int ci = 0; ci < (n.GetCount() ? 2 : 1); ci++)
for(int i = 0; i < item.GetCount(); i++) {
const CppItemInfo& f = item[i];
int q = memcmp(n, f.name, n.GetLength());
if((n.GetLength() == 0 ||
(ci ? q && memcmp_i(n, f.name, n.GetLength()) == 0 : q == 0)) &&
(IsNull(typei) || typei == f.typei) &&
(IsNull(scope) || scope == f.scope)) {
list.Add(f.scope, RawToValue(f), f.item, f.line, GetSourceFilePath(f.file), f.scope);
nc.FindAdd(f.scope);
}
}
*/
list.HeaderTab(0).SetText(Format("Scope (%d)", nc.GetCount()));
list.HeaderTab(1).SetText(Format("Symbol (%d)", list.GetCount()));
SyncOk();
}
int GotoDlg::GetLine()
{
if(list.IsCursor() && list.HasFocus())
return list.Get(3);
String s = ~target;
if(IsDigit(s[0]))
return atoi(s);
if(list.IsCursor())
return list.Get(3);
if(list.GetCount())
return list.Get(0, 3);
return -1;
}
void GotoDlg::SyncOk()
{
ok.Enable(GetLine() >= 0);
}
int GotoFilter(int c)
{
return IsDigit(c) || IsAlpha(c) || c == '_' || c == ':' ? ToUpper(c) : c == '.' ? ':' : 0;
}
void GotoDlg::Serialize(Stream& s)
{
SerializePlacement(s);
list.SerializeHeader(s);
}
struct CppItemInfoSortLine {
bool operator()(const CppItemInfo& a, const CppItemInfo& b) const {
return a.line < b.line;
}
};
struct CppItemInfoSortGlobal {
bool operator()(const CppItemInfo& a, const CppItemInfo& b) const {
return CombineCompare(a.scope, b.scope)
(GetSourceFilePath(a.file), GetSourceFilePath(b.file))
(a.line, b.line) < 0;
}
};
GotoDlg::GotoDlg(const String& s)
{
global = IsNull(s);
if(!global) {
StringStream ss(s);
Parser parser;
parser.Do(ss, IgnoreList(), lbase, Null, CNULL);
}
CtrlLayoutOKCancel(*this, IsNull(s) ? "Go to global" : "Go to line or symbol");
CppBase& base = IsNull(s) ? CodeBase() : lbase;
gbase = &base;
for(int i = 0; i < base.GetCount(); i++) {
Array<CppItem>& n = base[i];
for(int j = 0; j < n.GetCount(); j++) {
const CppItem& m = n[j];
CppItemInfo mf;
(CppItem&)mf = n[j];
mf.scope = base.GetKey(i);
mf.virt = false;
mf.access = m.impl ? (int)WITHBODY : (int)PUBLIC;
mf.item = global ? String().Cat() << GetFileName(GetSourceFilePath(m.file)) << " (" << m.line << ')'
: AsString(m.line);
mf.typei = 0;
item.Add(mf);
}
}
if(global)
Sort(item, CppItemInfoSortGlobal());
else
Sort(item, CppItemInfoSortLine());
target.SetFilter(GotoFilter);
target <<= THISBACK(SyncList);
list.AddColumn("Nesting");
list.AddColumn().SetDisplay(Single<CppItemInfoDisplay>());
list.AddColumn(global ? "Position" : "Line");
list.SetLineCy(BrowserFont().Info().GetHeight() + 3);
if(global)
list.ColumnWidths("181 466 112");
else
list.ColumnWidths("174 516 37");
list.WhenCursor = THISBACK(SyncOk);
list.WhenLeftDouble = Breaker(IDOK);
list.EvenRowColor();
SyncList();
ActiveFocus(target);
Sizeable().Zoomable();
Icon(IdeImg::Navigator());
}
INITBLOCK
{
RegisterGlobalConfig("IdeGoto");
RegisterGlobalConfig("IdeGotoGlobal");
}
void Ide::Goto()
{
if(designer || editor.GetLength() == 0)
return;
GotoDlg dlg(~editor);
LoadFromGlobal(dlg, "IdeGoto");
int c = dlg.Run();
StoreToGlobal(dlg, "IdeGoto");
if(c != IDOK)
return;
int l = dlg.GetLine();
if(l > 0) {
editor.SetCursor(editor.GetPos(l - 1));
editor.TopCursor();
}
}
void Ide::GotoGlobal()
{
SaveFile();
GotoDlg dlg(Null);
LoadFromGlobal(dlg, "IdeGotoGlobal");
int c = dlg.Run();
StoreToGlobal(dlg, "IdeGotoGlobal");
if(c != IDOK)
return;
int l = dlg.GetLine();
if(l > 0 && dlg.list.GetCount()) {
String file = dlg.list.IsCursor() ? dlg.list.Get(4) : dlg.list.Get(0, 4);
GotoPos(file, l);
}
}
#endif
void AssistEditor::SwapSContext(Parser& p)
{
int i = GetCursor();