mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-24 14:22:40 -06:00
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:
parent
fa8a42603c
commit
5ebe8cd59c
4 changed files with 33 additions and 222 deletions
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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++)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue