Relatively massive C++ parser and Assist++ refactoring...

git-svn-id: svn://ultimatepp.org/upp/trunk@510 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2008-10-05 21:36:04 +00:00
parent 5806a3f0f2
commit 3ed63a1352
25 changed files with 718 additions and 791 deletions

View file

@ -2,7 +2,8 @@
NAMESPACE_UPP
void Renumber(LineInfo& lf) {
void Renumber(LineInfo& lf)
{
LineInfo tf;
int l = 0;
if(lf.GetCount()) {
@ -34,12 +35,14 @@ void Renumber(LineInfo& lf) {
lf = tf;
}
void ClearBreakpoints(LineInfo& lf) {
void ClearBreakpoints(LineInfo& lf)
{
for(int i = 0; i < lf.GetCount(); i++)
lf[i].breakpoint.Clear();
}
void ValidateBreakpoints(LineInfo& lf) {
void ValidateBreakpoints(LineInfo& lf)
{
for(int i = 0; i < lf.GetCount(); i++)
if(lf[i].breakpoint[0] == 0xe)
lf[i].breakpoint = "1";
@ -50,7 +53,8 @@ void EditorBar::sPaintImage(Draw& w, int y, int fy, const Image& img)
w.DrawImage(0, y + (fy - img.GetSize().cy) / 2, img);
}
void EditorBar::Paint(Draw& w) {
void EditorBar::Paint(Draw& w)
{
static Image (*numeri[])() = {
CodeEditorImg::N0, CodeEditorImg::N1, CodeEditorImg::N2, CodeEditorImg::N3, CodeEditorImg::N4,
CodeEditorImg::N5, CodeEditorImg::N6, CodeEditorImg::N7, CodeEditorImg::N8, CodeEditorImg::N9,
@ -152,7 +156,8 @@ void EditorBar::Paint(Draw& w) {
}
}
void EditorBar::MouseMove(Point p, dword flags) {
void EditorBar::MouseMove(Point p, dword flags)
{
int pa = active_annotation;
if(p.x > GetSize().cx - annotations)
active_annotation = p.y / editor->GetFont().Info().GetHeight() + editor->GetScrollPos().y;
@ -172,18 +177,21 @@ void EditorBar::MouseLeave()
WhenAnnotationMove();
}
void EditorBar::LeftDown(Point p, dword flags) {
void EditorBar::LeftDown(Point p, dword flags)
{
if(editor)
editor->LeftDown(Point(0, p.y), flags);
}
String& EditorBar::PointBreak(int& y) {
String& EditorBar::PointBreak(int& y)
{
y = minmax(y / editor->GetFont().Info().GetHeight()
+ editor->GetScrollPos().y, 0, editor->GetLineCount());
return li.At(y).breakpoint;
}
void EditorBar::LeftDouble(Point p, dword flags) {
void EditorBar::LeftDouble(Point p, dword flags)
{
if(!editor || !bingenabled) return;
String& b = PointBreak(p.y);
if(b.IsEmpty())
@ -194,7 +202,8 @@ void EditorBar::LeftDouble(Point p, dword flags) {
Refresh();
}
void EditorBar::RightDown(Point p, dword flags) {
void EditorBar::RightDown(Point p, dword flags)
{
return;
if(!editor || !bingenabled) return;
String& b = PointBreak(p.y);
@ -203,7 +212,8 @@ void EditorBar::RightDown(Point p, dword flags) {
Refresh();
}
void EditorBar::InsertLines(int i, int count) {
void EditorBar::InsertLines(int i, int count)
{
li.InsertN(minmax(i + 1, 0, li.GetCount()), max(count, 0));
if(editor->GetCheckEdited()) {
if(editor->IsUndoOp() && li_removed.GetCount() >= count) {
@ -226,7 +236,8 @@ void EditorBar::InsertLines(int i, int count) {
Refresh();
}
void EditorBar::RemoveLines(int i, int count) {
void EditorBar::RemoveLines(int i, int count)
{
if(editor->GetCheckEdited() && !editor->IsUndoOp()) {
for(int t = i - 1; t < i + count - 1; t++) {
LineInfoRemRecord& rm = li_removed.Add();
@ -243,7 +254,8 @@ void EditorBar::RemoveLines(int i, int count) {
Refresh();
}
void EditorBar::ClearLines() {
void EditorBar::ClearLines()
{
li.Clear();
li.Shrink();
li_removed.Clear();
@ -251,7 +263,8 @@ void EditorBar::ClearLines() {
Refresh();
}
LineInfo EditorBar::GetLineInfo() const {
LineInfo EditorBar::GetLineInfo() const
{
LineInfo lf;
int l = -2;
for(int i = 0; i < li.GetCount(); i++) {
@ -279,7 +292,8 @@ LineInfo EditorBar::GetLineInfo() const {
return lf;
}
void EditorBar::SetLineInfo(const LineInfo& lf, int total) {
void EditorBar::SetLineInfo(const LineInfo& lf, int total)
{
li.Clear();
if(lf.GetCount() == 0) {
for(int i = 0; i < total; i++)
@ -304,13 +318,15 @@ void EditorBar::SetLineInfo(const LineInfo& lf, int total) {
}
}
void EditorBar::Renumber(int linecount) {
void EditorBar::Renumber(int linecount)
{
li.SetCount(linecount);
for(int i = 0; i < linecount; i++)
li[i].lineno = i;
}
void EditorBar::ClearBreakpoints() {
void EditorBar::ClearBreakpoints()
{
for(int i = 0; i < li.GetCount(); i++)
li[i].breakpoint.Clear();
Refresh();
@ -459,7 +475,8 @@ void EditorBar::Annotations(int width)
SyncWidth();
}
EditorBar::EditorBar() {
EditorBar::EditorBar()
{
LineNumbers(false);
editor = NULL;
bingenabled = true;

View file

@ -5,15 +5,51 @@ NAMESPACE_UPP
#define LLOG(x)
#define LTIMING(x) // RTIMING(x)
CppItem& CppNest::GetAdd(const String& _key, const String& _name)
void CppItem::Serialize(Stream& s)
{
int i = key.Find(_key);
if(i < 0) {
key.Add(_key);
name.Add(_name);
return item.Add();
s % kind % access;
s % item % name % natural % at % tparam % param % pname
% tname % ctname % type % ptype % virt % line;
}
struct CmpItem {
bool operator()(const CppItem& a, const String& b) const
{
return a.qitem < b;
}
return item[i];
};
int FindItem(const Array<CppItem>& x, const String& qitem)
{
int q = FindLowerBound(x, qitem, CmpItem());
if(q < x.GetCount() && x[q].qitem == qitem)
return q;
return -1;
}
int FindNext(const Array<CppItem>& x, int i)
{
if(i >= x.GetCount())
return i;
String q = x[i].qitem;
while(i < x.GetCount() && x[i].qitem == q)
i++;
return i;
}
int GetCount(const Array<CppItem>& x, int i)
{
return FindNext(x, i) - i;
}
int FindName(const Array<CppItem>& x, const String& name, int i)
{
while(i < x.GetCount()) {
if(x[i].name == name)
return i;
i++;
}
return -1;
}
bool CppBase::IsType(int i) const
@ -25,35 +61,22 @@ bool CppBase::IsType(int i) const
void Remove(CppBase& base, const Vector<String>& pf)
{
int ni = 0;
Vector<int> file;
Index<int> file;
for(int i = 0; i < pf.GetCount(); i++)
file.Add(GetCppFileIndex(pf[i]));
while(ni < base.GetCount()) {
CppNest& n = base[ni];
Array<CppItem>& n = base[ni];
Vector<int> nr;
for(int mi = 0; mi < n.GetCount(); mi++) {
CppItem& m = n.item[mi];
int i = 0;
while(i < m.pos.GetCount())
if(FindIndex(file, m.pos[i].file) >= 0)
m.pos.Remove(i);
else
i++;
if(m.pos.GetCount() == 0)
nr.Add(mi);
}
n.Remove(nr);
if(n.GetCount() == 0)
base.nest.Remove(ni);
else
for(int i = 0; i < n.GetCount(); i++)
if(file.Find(n[i].file) >= 0)
nr.Add(i);
if(nr.GetCount() == n.GetCount())
base.Remove(ni);
else {
n.Remove(nr);
ni++;
}
}
}
void CppItem::Serialize(Stream& s)
{
s % kind % access;
s % natural % at % tparam % param % pname % tname % ctname % type % ptype % virt % key;
}
END_UPP_NAMESPACE

View file

@ -205,19 +205,19 @@ enum {
PRIVATE,
};
struct CppPos : Moveable<CppPos> {
bool impl;
int line;
int file;
String GetFile() const { return GetCppFile(file); }
CppPos() { line = 0; impl = false; }
enum {
FILE_H,
FILE_HPP,
FILE_CPP,
FILE_C,
FILE_OTHER,
};
struct CppSimpleItem {
struct CppItem {
String qitem;
String item;
String name;
String natural;
String type;
String qtype;
String tparam;
@ -232,52 +232,34 @@ struct CppSimpleItem {
int16 at;
bool virt;
bool decla;
byte filetype;
bool impl;
int file;
int line;
byte qualify_type, qualify_param;
int serial;
bool IsType() const { return IsCppType(kind); }
bool IsCode() const { return IsCppCode(kind); }
bool IsData() const { return IsCppData(kind); }
bool IsMacro() const { return IsCppMacro(kind); }
bool IsTemplate() const { return IsCppTemplate(kind); }
void Serialize(Stream& s);
CppSimpleItem() { decla = false; virt = false; at = 0; }
CppItem() { decla = false; virt = false; at = 0; }
};
struct CppItem : CppSimpleItem {
Vector<CppPos> pos;
String key;
byte qualify_type, qualify_param;
int FindItem(const Array<CppItem>& x, const String& qitem);
int GetCount(const Array<CppItem>& x, int i);
int FindNext(const Array<CppItem>& x, int i);
int FindName(const Array<CppItem>& x, const String& name, int i = 0);
struct CppBase : ArrayMap<String, Array<CppItem> > {
int serial;
void Serialize(Stream& s);
CppItem() { qualify_type = qualify_param = true; serial = 0; }
};
struct CppNest {
int namespacel;
Index<String> key;
Index<String> name;
Array<CppItem> item;
void Remove(const Vector<int>& rm) { key.Remove(rm); name.Remove(rm); item.Remove(rm); }
int GetCount() const { return item.GetCount(); }
const CppItem& operator[](int i) const { return item[i]; }
CppItem& GetAdd(const String& key, const String& name);
CppNest() { namespacel = 0; }
};
struct CppBase {
ArrayMap<String, CppNest> nest;
int serial;
String serial_md5;
CppNest& operator[](int i) { return nest[i]; }
int GetCount() const { return nest.GetCount(); }
const String& GetKey(int i) const { return nest.GetKey(i); }
void Clear() { nest.Clear(); }
int Find(const String& s) const { return nest.Find(s); }
CppNest& GetAdd(const String& s) { return nest.GetAdd(s); }
String serial_md5;
bool IsType(int i) const;
@ -286,8 +268,7 @@ struct CppBase {
class Parser {
struct Context {
int namespacel;
String nesting;
String scopeing;
String ctname;
Vector<int> tparam;
Index<int> typenames;
@ -344,6 +325,7 @@ class Parser {
SrcFile file;
Lex lex;
int filei;
byte filetype;
bool inbody;
Callback2<int, const String&> err;
@ -369,7 +351,7 @@ class Parser {
bool IsParamList(int q);
void Elipsis(Decl& d);
Decl& Finish(Decl& d, const char *p);
bool Nest(const String& tp, const String& tn);
bool Scope(const String& tp, const String& tn);
String TemplateParams(String& pnames);
String TemplateParams();
@ -384,12 +366,12 @@ class Parser {
void Check(bool b, const char *err);
void CheckKey(int c);
void SetNestCurrent();
void NestBody();
void SetScopeCurrent();
void ScopeBody();
void Do();
CppItem& Item(const String& nesting, const String& item, const String& name, bool impl);
CppItem& Item(const String& nesting, const String& item, const String& name);
CppItem& Item(const String& scopeing, const String& item, const String& name, bool impl);
CppItem& Item(const String& scopeing, const String& item, const String& name);
CppItem& Fn(const Decl& d, const String& templ, bool body, int kind, const String& tname, const String& tparam);
@ -407,11 +389,11 @@ class Parser {
public:
struct FunctionStat
{
FunctionStat(const String & nesting,
FunctionStat(const String & scopeing,
const CppItem & cppItem,
const LexSymbolStat &symbolStat,
int maxScopeDepth);
String nesting;
String scopeing;
const CppItem & cppItem;
const LexSymbolStat &symbolStat;
int maxScopeDepth;
@ -422,7 +404,7 @@ public:
typedef Callback1<const FunctionStat &> FnEndCallback;
bool dobody;
String current_nest;
String current_scope;
int current_namespacel;
String current_key;
String current_name;
@ -443,11 +425,11 @@ public:
String NoTemplatePars(const String& type);
class Nestfo {
class Scopefo {
bool bvalid, nvalid;
Vector<String> baselist;
Vector<String> nests;
int nesti;
Vector<String> scopes;
int scopei;
void Bases(int i, Vector<int>& g);
void Init();
@ -456,19 +438,19 @@ public:
VectorMap<String, String> cache;
const Vector<String>& GetBases();
const Vector<String>& GetNests();
int GetNest() const { return nesti; }
const Vector<String>& GetScopes();
int GetScope() const { return scopei; }
void NoBases() { baselist.Clear(); bvalid = true; }
Nestfo(const CppBase& base, int nesti = -1);
Nestfo(int nesti, const CppBase& base);
Nestfo(const CppBase& base, const String& nest);
Nestfo(const Nestfo& f);
Scopefo(const CppBase& base, int scopei = -1);
Scopefo(int scopei, const CppBase& base);
Scopefo(const CppBase& base, const String& scope);
Scopefo(const Scopefo& f);
};
String Qualify(const CppBase& base, const String& nest, const String& type);
void QualifyTypes(CppBase& base, const String& nest, CppItem& m);
String QualifyKey(const CppBase& base, const String& nest, const String& type);
String Qualify(const CppBase& base, const String& scope, const String& type);
void QualifyTypes(CppBase& base, const String& scope, CppItem& m);
String QualifyKey(const CppBase& base, const String& scope, const String& type);
void Qualify(CppBase& base);

View file

@ -12,7 +12,7 @@ file
cpplex.cpp,
Parser.cpp,
Base.cpp,
Nestfo.cpp,
Scopefo.cpp,
Qualify.cpp,
Info readonly separator,
Copying;

View file

@ -174,35 +174,34 @@ void ScAdd(String& s, const String& a)
String Parser::Context::Dump() const
{
return "Nesting: " + nesting;
return "Scopeing: " + scopeing;
}
Parser::FunctionStat::FunctionStat(const String & nesting,
Parser::FunctionStat::FunctionStat(const String & scopeing,
const CppItem & cppItem,
const LexSymbolStat &symbolStat,
int maxScopeDepth) :
nesting(nesting), cppItem(cppItem),
scopeing(scopeing), cppItem(cppItem),
symbolStat(symbolStat), maxScopeDepth(maxScopeDepth)
{
}
static String s_dblcln("::");
inline void NestCat(String& nest, const String& s)
inline void ScopeCat(String& scope, const String& s)
{
if(nest.GetCount())
nest << s_dblcln;
nest << s;
if(scope.GetCount())
scope << s_dblcln;
scope << s;
}
void Parser::Context::operator<<=(const Context& t)
{
nesting = t.nesting;
scopeing = t.scopeing;
typenames <<= t.typenames;
tparam <<= t.tparam;
access = t.access;
noclass = t.noclass;
namespacel = t.namespacel;
ctname = t.ctname;
}
@ -252,7 +251,7 @@ void Parser::ThrowError(const String& e)
int i = 0;
while(i < 40 && lex[i] != t_eof)
i++;
LLOG("ERROR: (" << GetLine(lex.Pos()) << ") " << e << ", nest: " << current_nest <<
LLOG("ERROR: (" << GetLine(lex.Pos()) << ") " << e << ", scope: " << current_scope <<
" " << AsCString(String(lex.Pos(), lex.Pos(i))));
#endif
throw Error();
@ -421,6 +420,7 @@ String Parser::SimpleType(Decla& d)
return Null;
}
if(Key(tk_short)) {
Key(tk_unsigned);
Key(tk_int);
return Null;
}
@ -792,7 +792,7 @@ bool Parser::TryDecl()
q++;
if(!lex.IsId(q))
return false;
type = Qualify(*base, current_nest, type);
type = Qualify(*base, current_scope, type);
if(base->Find(NoTemplatePars(type)) >= 0) {
Locals(type);
return true;
@ -952,36 +952,34 @@ String CleanTp(const String& tp)
return r;
}
void Parser::SetNestCurrent()
void Parser::SetScopeCurrent()
{
// current_nest = Nvl(context.nesting, "::");
current_nest = context.nesting;
current_scope = context.scopeing;
}
CppItem& Parser::Item(const String& nesting, const String& item, const String& name, bool impl)
CppItem& Parser::Item(const String& scopeing, const String& item, const String& name, bool impl)
{
// current_nest = Nvl(nesting, "::");
current_nest = nesting;
current_scope = scopeing;
if(dobody)
current = CppItem();
current_key = item;
current_name = name;
CppNest& n = base->GetAdd(current_nest);
n.namespacel = current_namespacel = context.namespacel;
CppItem& im = dobody ? current : n.GetAdd(item, name);
im.key = item;
CppPos& p = im.pos.Add();
p.file = filei;
p.line = line + 1;
p.impl = impl;
LLOG("New item " << GetCppFile(filei) << ' ' << line + 1 << " " << nesting << "::" << item);
Array<CppItem>& n = base->GetAdd(current_scope);
CppItem& im = dobody ? current : n.Add();
im.item = item;
im.name = name;
im.file = filei;
im.line = line + 1;
im.impl = impl;
im.filetype = filetype;
LOG("New item " << GetCppFile(filei) << ' ' << line + 1 << " " << scopeing << "::" << item);
return im;
}
CppItem& Parser::Item(const String& nesting, const String& item, const String& name)
CppItem& Parser::Item(const String& scopeing, const String& item, const String& name)
{
String h = Purify(item);
CppItem& im = Item(nesting, h, name, false);
CppItem& im = Item(scopeing, h, name, false);
im.natural = h;
return im;
}
@ -995,7 +993,7 @@ void Parser::Resume(int bl)
}
}
void Parser::NestBody()
void Parser::ScopeBody()
{
int bl = lex.GetBracesLevel();
while(!Key('}')) {
@ -1048,20 +1046,18 @@ String Subst(const String& s, const Vector<String>& tpar)
return r;
}
bool Parser::Nest(const String& tp, const String& tn) {
bool Parser::Scope(const String& tp, const String& tn) {
if(Key(tk_namespace)) {
Check(lex.IsId(), "Expected name of namespace");
String name = lex.GetId();
if(Key('{')) {
Context cc;
cc <<= context;
// context.nesting << "::" << name;
// context.namespacel = context.nesting.GetLength();
NestBody();
ScopeBody();
context <<= cc;
}
Key(';');
SetNestCurrent();
SetScopeCurrent();
return true;
}
if((lex == tk_class || lex == tk_struct || lex == tk_union) && lex[1] != '{') {
@ -1084,13 +1080,13 @@ bool Parser::Nest(const String& tp, const String& tn) {
}
}
if(Key(t_dblcolon))
context.nesting = Null;
context.scopeing = Null;
String name;
do {
Check(lex.IsId(), "Missing identifier");
context.typenames.FindAdd(lex);
name = lex.GetId();
NestCat(context.nesting, name);
ScopeCat(context.scopeing, name);
}
while(Key(t_dblcolon));
context.access = t == tk_class ? PRIVATE : PUBLIC;
@ -1105,10 +1101,10 @@ bool Parser::Nest(const String& tp, const String& tn) {
nn = "template " + tp + " ";
String key = (t == tk_class ? "class" : t == tk_union ? "union" : "struct");
nn << key << ' ' << name;
CppItem& im = Item(context.nesting, key, name, lex != ';');
CppItem& im = Item(context.scopeing, key, name, lex != ';');
if(Key(';')) {
context = cc;
SetNestCurrent();
SetScopeCurrent();
return true;
}
im.kind = tp.IsEmpty() ? STRUCT : STRUCTTEMPLATE;
@ -1146,7 +1142,7 @@ bool Parser::Nest(const String& tp, const String& tn) {
while(Key(','));
}
if(Key('{')) {
NestBody();
ScopeBody();
im.natural = Gpurify(nn);
im.decla = true;
}
@ -1155,7 +1151,7 @@ bool Parser::Nest(const String& tp, const String& tn) {
im.natural = Gpurify(nn);
context = cc;
CheckKey(';');
SetNestCurrent();
SetScopeCurrent();
return true;
}
return false;
@ -1190,7 +1186,7 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body, int kind,
nn0 = d.name.Mid(0, q - 1);
}
String item = FnItem(d.natural, pname, d.name, nm);
String nesting = context.nesting;
String scopeing = context.scopeing;
String nn;
const char *s = nn0;
int l = 0;
@ -1208,8 +1204,8 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body, int kind,
s = nn;
while(*s == ':') s++;
if(*s)
NestCat(nesting, s);
CppItem& im = Item(nesting, item, nm, body);
ScopeCat(scopeing, s);
CppItem& im = Item(scopeing, item, nm, body);
if(!body || IsNull(im.natural)) {
im.natural.Clear();
if(!IsNull(templ)) {
@ -1228,7 +1224,7 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body, int kind,
im.tname = tname;
im.tparam = tparam;
im.ctname = context.ctname;
LLOG("FnItem: " << nesting << "::" << item << ", natural: " << im.natural
LLOG("FnItem: " << scopeing << "::" << item << ", natural: " << im.natural
<< ", ctname: " << im.ctname);
}
return im;
@ -1236,7 +1232,7 @@ CppItem& Parser::Fn(const Decl& d, const String& templ, bool body, int kind,
void Parser::Do()
{
LLOG("Do, nest: " << current_nest);
LLOG("Do, scope: " << current_scope);
Line();
if(Key(tk_using)) {
while(!Key(';') && lex != t_eof)
@ -1277,7 +1273,7 @@ void Parser::Do()
else {
String tnames;
String tparam = TemplateParams(tnames);
if(!Nest(tparam, tnames)) {
if(!Scope(tparam, tnames)) {
Array<Decl> r = Declaration(true, true);
CppItem *functionItem = 0;
bool body = lex == '{';
@ -1298,7 +1294,7 @@ void Parser::Do()
}
EatBody();
if(body && functionItem && whenFnEnd) {
whenFnEnd(FunctionStat(current_nest, *functionItem,
whenFnEnd(FunctionStat(current_scope, *functionItem,
lex.FinishStatCollection(), maxScopeDepth));
lex.StartStatCollection(); // start collection of orphan symbols
}
@ -1319,7 +1315,7 @@ void Parser::Do()
String val;
Check(lex.IsId(), "Expected identifier");
String id = lex.GetId();
CppItem& im = Item(context.nesting, id, id);
CppItem& im = Item(context.scopeing, id, id);
im.natural = "enum ";
if(!IsNull(name))
im.natural << name << ' ';
@ -1333,7 +1329,7 @@ void Parser::Do()
}
}
Key(';');
SetNestCurrent();
SetScopeCurrent();
}
else
if(Key('#')) {
@ -1343,7 +1339,7 @@ void Parser::Do()
const char *s = n;
while(*s && iscid(*s))
name.Cat(*s++);
CppItem& im = Item(context.nesting, n, name);
CppItem& im = Item(context.scopeing, n, name);
im.kind = MACRO;
s = strchr(n, '(');
if(s) {
@ -1364,7 +1360,7 @@ void Parser::Do()
}
}
else
if(!Nest(String(), String())) {
if(!Scope(String(), String())) {
if(Key(tk_public)) {
context.access = PUBLIC;
Key(':');
@ -1400,10 +1396,10 @@ void Parser::Do()
int q = h.Find('=');
if(q >= 0)
h = TrimRight(h.Mid(0, q));
String nest = context.nesting;
String scope = context.scopeing;
if(d.type_def)
NestCat(nest, d.name);
CppItem& im = Item(nest, d.type_def ? "typedef" : d.name, d.name);
ScopeCat(scope, d.name);
CppItem& im = Item(scope, d.type_def ? "typedef" : d.name, d.name);
im.natural = Purify(h);
im.type = im.ptype = d.type;
im.access = context.access;
@ -1419,11 +1415,11 @@ void Parser::Do()
}
EatBody();
if(body && functionItem && whenFnEnd) {
whenFnEnd(FunctionStat(current_nest, *functionItem,
whenFnEnd(FunctionStat(current_scope, *functionItem,
lex.FinishStatCollection(), maxScopeDepth));
lex.StartStatCollection(); // start collection of orphan symbols
}
SetNestCurrent();
SetScopeCurrent();
Key(';');
}
}
@ -1438,6 +1434,20 @@ void Parser::Do(Stream& in, const Vector<String>& ignore, CppBase& _base, const
lex.Init(~file.text, ignore);
err = _err;
filei = GetCppFileIndex(fn);
String ext = ToLower(GetFileExt(fn));
if(ext == ".h")
filetype = FILE_H;
else
if(ext == ".hpp")
filetype = FILE_HPP;
else
if(ext == ".cpp")
filetype = FILE_CPP;
else
if(ext == ".c")
filetype = FILE_C;
else
filetype = FILE_OTHER;
lpos = 0;
line = 0;
if(whenFnEnd)
@ -1446,17 +1456,15 @@ void Parser::Do(Stream& in, const Vector<String>& ignore, CppBase& _base, const
while(lex != t_eof)
try {
try {
// current_nest = "::";
current_nest.Clear();
current_scope.Clear();
context.access = PUBLIC;
context.noclass = true;
context.typenames.Clear();
context.tparam.Clear();
context.nesting.Clear();
context.scopeing.Clear();
inbody = false;
for(int i = 0; i < typenames.GetCount(); i++)
context.typenames.Add(lex.Id(typenames[i]));
context.namespacel = 0;
Do();
}
catch(Error) {

View file

@ -5,29 +5,29 @@ NAMESPACE_UPP
#define LLOG(x)
#define LTIMING(x) // RTIMING(x)
bool DoQualify(Nestfo& nf, const String& type, String& qt);
bool DoQualify(Scopefo& nf, const String& type, String& qt);
bool Qualify0(Nestfo& nf, const String& type, String& qt)
bool Qualify0(Scopefo& nf, const String& type, String& qt)
{
const Vector<String>& nd = nf.GetNests();
const Vector<String>& nd = nf.GetScopes();
if(nd.GetCount()) {
LTIMING("First test");
qt = nd[0] + type;
if(nf.base.Find(qt) >= 0)
return true;
}
if(nf.GetNest() >= 0) {
if(nf.GetScope() >= 0) {
int q = type.ReverseFind(':');
if(q > 0) {
LTIMING("Qualifying qualification");
Nestfo hnf(nf);
Scopefo hnf(nf);
hnf.NoBases();
String qn;
if(DoQualify(hnf, type.Mid(0, q - 1), qn)) {
int nesti = nf.base.Find(qn);
if(nesti >= 0) {
int scopei = nf.base.Find(qn);
if(scopei >= 0) {
String tp = type.Mid(q + 1);
Nestfo nnf(nf.base, nesti);
Scopefo nnf(nf.base, scopei);
const Vector<String>& bs = nnf.GetBases();
for(int i = 0; i < bs.GetCount(); i++) {
qt = bs[i] + tp;
@ -48,7 +48,7 @@ bool Qualify0(Nestfo& nf, const String& type, String& qt)
}
}
if(type[0] != ':') {
LTIMING("Testing nests");
LTIMING("Testing scopes");
for(int i = 1; i < nd.GetCount(); i++) {
qt = nd[i] + type;
if(nf.base.Find(qt) >= 0)
@ -61,7 +61,7 @@ bool Qualify0(Nestfo& nf, const String& type, String& qt)
return Qualify0(nf, type.Mid(q + 1), qt);
}
bool DoQualify(Nestfo& nf, const String& type, String& qt)
bool DoQualify(Scopefo& nf, const String& type, String& qt)
{
LTIMING("Qualify");
int q = nf.cache.Find(type);
@ -76,7 +76,7 @@ bool DoQualify(Nestfo& nf, const String& type, String& qt)
return true;
}
String DoQualify(Nestfo& nf, const String& type)
String DoQualify(Scopefo& nf, const String& type)
{
String qt;
return DoQualify(nf, type, qt) ? qt : type;
@ -93,7 +93,7 @@ static String s_struct("struct");
static String s_class("class");
static String s_unsigned("unsigned");
inline void Qualify(String& r, Nestfo& nf, const char *b, const char *s, byte& qual)
inline void Qualify(String& r, Scopefo& nf, const char *b, const char *s, byte& qual)
{
String type(b, s);
if(type.GetCount() == 0 || type == s_const ||
@ -106,7 +106,7 @@ inline void Qualify(String& r, Nestfo& nf, const char *b, const char *s, byte& q
r << DoQualify(nf, type);
}
String QualifyIds(Nestfo& nf, const String& k, bool all, byte& qual)
String QualifyIds(Scopefo& nf, const String& k, bool all, byte& qual)
{
LTIMING("QualifyIds");
String r;
@ -118,7 +118,7 @@ String QualifyIds(Nestfo& nf, const String& k, bool all, byte& qual)
const char *b = s++;
while(*s == ':' || iscid(*s)) s++;
if(all) {
Nestfo nnf(nf.GetNest(), nf.base);
Scopefo nnf(nf.GetScope(), nf.base);
Qualify(r, nnf, b, s, qual);
}
else
@ -146,23 +146,23 @@ String QualifyIds(Nestfo& nf, const String& k, bool all, byte& qual)
return r;
}
String Qualify(const CppBase& base, const String& nest, const String& type)
String Qualify(const CppBase& base, const String& scope, const String& type)
{
Nestfo nf(base, nest);
Scopefo nf(base, scope);
byte dummy = 2;
return QualifyIds(nf, type, true, dummy);
}
String QualifyKey(const CppBase& base, const String& nest, const String& type)
String QualifyKey(const CppBase& base, const String& scope, const String& type)
{
Nestfo nf(base, nest);
Scopefo nf(base, scope);
byte dummy = 2;
return QualifyIds(nf, type, false, dummy);
}
void QualifyTypes(CppBase& base, const String& nest, CppItem& m)
void QualifyTypes(CppBase& base, const String& scope, CppItem& m)
{
Nestfo nf(base, nest);
Scopefo nf(base, scope);
m.qtype = QualifyIds(nf, m.type, true, m.qualify_type);
m.qptype = QualifyIds(nf, m.ptype, true, m.qualify_param);
}
@ -171,10 +171,10 @@ void QualifyPass1(CppBase& base)
{
LTIMING("QualifyPass1");
for(int ni = 0; ni < base.GetCount(); ni++) {
CppNest& n = base[ni];
Nestfo nf(base, ni);
Array<CppItem>& n = base[ni];
Scopefo nf(base, ni);
for(int i = 0; i < n.GetCount(); i++) {
CppItem& m = n.item[i];
CppItem& m = n[i];
if(m.serial != base.serial && m.IsType()) {
m.serial = base.serial;
if(m.qualify_type) {
@ -185,78 +185,65 @@ void QualifyPass1(CppBase& base)
m.qualify_param = false;
m.qptype = QualifyIds(nf, m.ptype, true, m.qualify_param);
}
m.qitem = m.item;
}
}
}
}
struct CmpCppItem {
bool operator()(const CppItem& a, const CppItem& b) const
{
int q = SgnCompare(a.qitem, b.qitem);
if(q) return q < 0;
q = SgnCompare(a.kind, b.kind);
if(q) return q < 0;
q = SgnCompare(a.impl, b.impl);
if(q) return a.IsType() ? q > 0 : q < 0;
q = SgnCompare(GetCppFile(a.file), GetCppFile(b.file));
if(q) return q < 0;
return a.line < b.line;
}
};
void QualifyPass2(CppBase& base)
{
LTIMING("QualifyPass2");
for(int ni = 0; ni < base.GetCount(); ni++) {
CppNest& n = base[ni];
Nestfo nf(base, ni);
Array<CppItem>& n = base[ni];
Scopefo nf(base, ni);
Index<int> rem;
String prev_type, prev_qtype;
byte prev_qualify = 0;
bool sort = false;
for(int i = 0; i < n.GetCount(); i++) {
CppItem& m = n.item[i];
CppItem& m = n[i];
if(m.serial != base.serial && !m.IsType()) {
sort = true;
m.serial = base.serial;
if(m.qualify_type) {
if(m.type == prev_type) {
m.qtype = prev_qtype;
m.qualify_type = prev_qualify;
}
else {
m.qualify_type = false;
m.qtype = QualifyIds(nf, m.type, true, m.qualify_type);
prev_type = m.type;
prev_qtype = m.qtype;
prev_qualify = m.qualify_type;
}
m.qualify_type = false;
m.qtype = QualifyIds(nf, m.type, true, m.qualify_type);
}
if(m.qualify_param) {
m.qualify_param = false;
m.qptype = QualifyIds(nf, m.ptype, true, m.qualify_param);
if(m.IsCode()) {
String k = n.key[i];
String r = QualifyIds(nf, m.key, false, m.qualify_param);
if(k != r) {
LTIMING("Key adjustment");
int q = n.key.Find(r);
if(q >= 0 && q != i)
if(m.decla) {
m.pos.Append(n.item[q].pos);
rem.FindAdd(q);
n.key.Set(i, r);
}
else {
n.item[q].pos.Append(m.pos);
rem.FindAdd(i);
}
else
n.key.Set(i, r);
}
}
m.qitem = m.IsCode() ? QualifyIds(nf, m.item, false, m.qualify_param)
: m.item;
}
}
}
LTIMING("Key removal");
Vector<int> rm = rem.PickKeys();
Sort(rm);
n.Remove(rm);
if(sort)
Sort(n, CmpCppItem());
}
}
void Qualify(CppBase& base)
{
Md5Stream md5;
Vector<int> no = GetSortOrder(base.nest.GetKeys());
Vector<int> no = GetSortOrder(base.GetKeys());
for(int q = 0; q < base.GetCount(); q++) {
int ni = no[q];
md5 << base.GetKey(ni);
const CppNest& n = base.nest[ni];
const Array<CppItem>& n = base[ni];
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& m = n[i];
if(m.IsType())

View file

@ -5,45 +5,45 @@ NAMESPACE_UPP
#define LLOG(x)
#define LTIMING(x) // RTIMING(x)
Nestfo::Nestfo(const CppBase& base, int nesti)
: nesti(nesti), base(base)
Scopefo::Scopefo(const CppBase& base, int scopei)
: scopei(scopei), base(base)
{
LTIMING("Nestfo(const CppBase& base, int nesti)");
LTIMING("Scopefo(const CppBase& base, int scopei)");
Init();
}
Nestfo::Nestfo(int nesti, const CppBase& base)
: nesti(nesti), base(base)
Scopefo::Scopefo(int scopei, const CppBase& base)
: scopei(scopei), base(base)
{
LTIMING("Nestfo(int nesti, const CppBase& base)");
LTIMING("Scopefo(int scopei, const CppBase& base)");
Init();
}
Nestfo::Nestfo(const CppBase& base, const String& nest)
: nesti(base.Find(nest)), base(base)
Scopefo::Scopefo(const CppBase& base, const String& scope)
: scopei(base.Find(scope)), base(base)
{
LTIMING("Nestfo(const CppBase& base, const String& nest)");
LTIMING("Scopefo(const CppBase& base, const String& scope)");
Init();
}
Nestfo::Nestfo(const Nestfo& f)
Scopefo::Scopefo(const Scopefo& f)
: base(f.base)
{
LTIMING("Nestfo copy contructor");
nests <<= f.nests;
LTIMING("Scopefo copy contructor");
scopes <<= f.scopes;
bvalid = nvalid = false;
nesti = f.nesti;
scopei = f.scopei;
}
void Nestfo::Init()
void Scopefo::Init()
{
bvalid = nvalid = false;
}
void Nestfo::Bases(int i, Vector<int>& g)
void Scopefo::Bases(int i, Vector<int>& g)
{
if(base.IsType(i)) {
const CppNest& n = base.nest[i];
const Array<CppItem>& n = base[i];
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& im = n[i];
if(im.IsType()) {
@ -69,17 +69,17 @@ void Nestfo::Bases(int i, Vector<int>& g)
}
}
const Vector<String>& Nestfo::GetBases()
const Vector<String>& Scopefo::GetBases()
{
LTIMING("GetBases");
if(!bvalid) {
bvalid = true;
baselist.Clear();
if(nesti < 0)
if(scopei < 0)
return baselist;
Vector<int> b;
Index<int> bi;
Bases(nesti, b);
Bases(scopei, b);
while(b.GetCount()) {
Vector<int> bb;
for(int i = 0; i < b.GetCount(); i++) {
@ -97,27 +97,27 @@ const Vector<String>& Nestfo::GetBases()
return baselist;
}
const Vector<String>& Nestfo::GetNests()
const Vector<String>& Scopefo::GetScopes()
{
LTIMING("GetNests");
LTIMING("GetScopes");
if(!nvalid) {
nvalid = true;
nests.Clear();
if(nesti < 0)
return nests;
String nn = base.GetKey(nesti);
scopes.Clear();
if(scopei < 0)
return scopes;
String nn = base.GetKey(scopei);
while(nn.GetCount()) {
if(nn[0] == ':' && nn.GetCount() == 2) {
nests.Add(nn);
return nests;
scopes.Add(nn);
return scopes;
}
nests.Add(nn + "::");
scopes.Add(nn + "::");
int q = nn.ReverseFind(':');
nn.Trim(max(0, q - 1));
}
nests.Add("");
scopes.Add("");
}
return nests;
return scopes;
}
END_UPP_NAMESPACE

View file

@ -5,20 +5,15 @@ void AssistEditor::Annotate(const String& filename)
int fi = GetCppFileIndex(filename);
CppBase& base = BrowserBase();
for(int j = 0; j < base.GetCount(); j++) {
CppNest& nest = base[j];
for(int k = 0; k < nest.GetCount(); k++) {
CppItem& m = nest.item[k];
for(int p = 0; p < m.pos.GetCount(); p++) {
if(m.pos[p].file == fi) {
String coderef = base.GetKey(j);
if(coderef.GetCount())
coderef << "::";
coderef << nest.key[k];
SetAnnotation(m.pos[p].line - 1,
GetRefLinks(coderef).GetCount() ? IdeImg::tpp_doc()
: IdeImg::tpp_pen(),
coderef);
}
const Array<CppItem>& n = base[j];
for(int k = 0; k < n.GetCount(); k++) {
const CppItem& m = n[k];
if(m.file == fi) {
String coderef = MakeCodeRef(base.GetKey(j), m.qitem);
SetAnnotation(m.line - 1,
GetRefLinks(coderef).GetCount() ? IdeImg::tpp_doc()
: IdeImg::tpp_pen(),
coderef);
}
}
}

View file

@ -88,29 +88,28 @@ void SubstituteTpars(Vector<String>& type, const String& tname)
}
}
bool AssistEditor::NestId(const CppNest& n, const String& id, Vector<String>& type, bool& code,
String& t)
bool AssistEditor::ScopeId(const Array<CppItem>& n, const String& id, Vector<String>& type, bool& code,
String& t)
{
int q = n.name.Find(NoTemplatePars(id));
if(q >= 0) {
do {
const CppItem& m = n[q];
String ntp = NoTemplatePars(id);
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& m = n[i];
if(n[i].name == ntp) {
const String& qt = m.qtype;
if(!IsNull(qt) && FindIndex(type, qt) < 0 && (m.IsCode() || m.IsData())) {
type.Add(qt);
if(m.IsCode())
code = true;
}
q = n.name.FindNext(q);
}
while(q >= 0);
return true;
}
q = n.key.Find("class");
if(type.GetCount())
return true;
int q = FindItem(n, "class");
if(q < 0)
q = n.key.Find("struct");
q = FindItem(n, "struct");
if(q < 0)
q = n.key.Find("typedef");
q = FindItem(n, "typedef");
LDUMP(q);
if(q >= 0) {
Vector<String> base = Split(n[q].qptype, ';');
@ -120,7 +119,7 @@ bool AssistEditor::NestId(const CppNest& n, const String& id, Vector<String>& ty
for(int i = 0; i < base.GetCount(); i++) {
q = BrowserBase().Find(NoTemplatePars(base[i]));
String h = base[i];
if(q >= 0 && NestId(BrowserBase()[q], id, type, code, h)) {
if(q >= 0 && ScopeId(BrowserBase()[q], id, type, code, h)) {
t = h;
return true;
}
@ -143,11 +142,11 @@ void AssistEditor::Context(Parser& parser, int pos)
StringStream ss(s);
parser.dobody = true;
parser.Do(ss, IgnoreList(), BrowserBase(), Null, callback(AssistScanError));
QualifyTypes(BrowserBase(), parser.current_nest, parser.current);
QualifyTypes(BrowserBase(), parser.current_scope, parser.current);
inbody = parser.IsInBody();
#ifdef _DEBUG
PutVerbose("body: " + AsString(inbody));
PutVerbose("nest: " + AsString(parser.current_nest));
PutVerbose("scope: " + AsString(parser.current_scope));
#endif
}
@ -157,12 +156,12 @@ void AssistEditor::TypeOf(const String& id, Vector<String>& r, bool& code)
Context(parser, GetCursor());
code = false;
if(id == "this") {
r.Add(parser.current_nest);
r.Add(parser.current_scope);
return;
}
if(IsNull(id)) {
r.Add(parser.current_nest);
if(parser.current_nest != "::")
r.Add(parser.current_scope);
if(parser.current_scope != "::")
r.Add("::");
return;
}
@ -179,7 +178,7 @@ void AssistEditor::TypeOf(const String& id, Vector<String>& r, bool& code)
r.Add(p[q]);
return;
}
String n = parser.current_nest;
String n = parser.current_scope;
for(;;) {
String type = n + "::" + id;
if(BrowserBase().Find(type)) {
@ -191,13 +190,13 @@ void AssistEditor::TypeOf(const String& id, Vector<String>& r, bool& code)
break;
n.Trim(q - 1);
}
q = BrowserBase().Find(parser.current_nest);
q = BrowserBase().Find(parser.current_scope);
String dummy;
if(q >= 0 && NestId(BrowserBase()[q], id, r, code, dummy))
if(q >= 0 && ScopeId(BrowserBase()[q], id, r, code, dummy))
return;
q = BrowserBase().Find("::");
if(q >= 0)
NestId(BrowserBase()[q], id, r, code, dummy);
ScopeId(BrowserBase()[q], id, r, code, dummy);
}
Vector<String> AssistEditor::Operator(const char *oper, const Vector<String>& type)
@ -207,7 +206,7 @@ Vector<String> AssistEditor::Operator(const char *oper, const Vector<String>& ty
for(int i = 0; i < type.GetCount(); i++) {
String t = type[i];
int q = BrowserBase().Find(NoTemplatePars(t));
if(q < 0 || !NestId(BrowserBase()[q], oper, nt, d, t))
if(q < 0 || !ScopeId(BrowserBase()[q], oper, nt, d, t))
nt.Add(type[i]);
SubstituteTpars(nt, t);
}
@ -221,7 +220,7 @@ Vector<String> AssistEditor::TypeOf(const Vector<String>& xp, const String& tp)
if(!IsNull(tp)) {
Parser parser;
Context(parser, GetCursor());
type.Add(Qualify(BrowserBase(), parser.current_nest, tp));
type.Add(Qualify(BrowserBase(), parser.current_scope, tp));
}
else {
if(xp.GetCount() == 0 || !iscid(xp[0][0]))
@ -243,7 +242,7 @@ Vector<String> AssistEditor::TypeOf(const Vector<String>& xp, const String& tp)
String t = type[i];
int j = BrowserBase().Find(NoTemplatePars(t));
if(j >= 0)
NestId(BrowserBase()[j], xp[q], nt, code, t);
ScopeId(BrowserBase()[j], xp[q], nt, code, t);
LDUMPC(nt);
SubstituteTpars(nt, t);
}
@ -289,44 +288,40 @@ void AssistEditor::GatherItems(const String& type, bool nom, Index<String>& in_t
String n = BrowserBase().GetKey(i);
if(n.GetLength() > ntp.GetLength() && memcmp(~ntp, ~n, ntp.GetLength()) == 0) {
LDUMP(n);
CppNest& m = BrowserBase()[i];
Array<CppItem>& m = BrowserBase()[i];
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
String name = m.name[i];
if(im.IsType()) {
CppItemInfo& f = assist_item.Add(name);
f.name = name;
CppItemInfo& f = assist_item.Add(im.name);
f.typei = typei;
(CppSimpleItem&)f = im;
(CppItem&)f = im;
break;
}
}
}
}
}
const CppNest& m = BrowserBase()[q];
const Array<CppItem>& m = BrowserBase()[q];
String base;
int typei = assist_type.FindAdd(ntp);
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
String name = m.name[i];
if(im.IsType())
base = im.qptype;
LDUMP(name);
LDUMP(im.name);
if((im.IsCode() || im.IsData() || im.IsMacro() && type == "::")
&& (nom || im.access == PUBLIC)) {
if(im.IsCode()) {
int q = assist_item.Find(name);
int q = assist_item.Find(im.name);
while(q >= 0) {
if(assist_item[q].typei != typei)
assist_item[q].over = true;
q = assist_item.FindNext(q);
}
}
CppItemInfo& f = assist_item.Add(name);
f.name = name;
CppItemInfo& f = assist_item.Add(im.name);
f.typei = typei;
(CppSimpleItem&)f = im;
(CppItem&)f = im;
}
}
Vector<String> b = Split(base, ';');
@ -883,16 +878,16 @@ void AssistEditor::DCopy()
Context(ctx, l);
String txt = Get(l, h - l);
StringStream ss(txt);
String cls = ctx.current_nest.Mid(ctx.current_namespacel);
String cls = ctx.current_scope.Mid(ctx.current_namespacel);
if(cls[0] == ':' && cls[1] == ':')
cls = cls.Mid(2);
CppBase cpp;
Parser parser;
parser.Do(ss, IgnoreList(), cpp, Null, CNULL, Split(cls, ':'));
for(int i = 0; i < cpp.GetCount(); i++) {
const CppNest& nest = cpp[i];
for(int j = 0; j < nest.GetCount(); j++) {
const CppItem& m = nest[j];
const Array<CppItem>& scope = cpp[i];
for(int j = 0; j < scope.GetCount(); j++) {
const CppItem& m = scope[j];
if(m.IsCode())
if(cls.GetCount())
r << MakeDefinition(cls, m.natural) << "\n{\n}\n\n";
@ -908,32 +903,39 @@ void AssistEditor::DCopy()
WriteClipboardText(r);
}
String GetIdNest(const String& nest, const String& id, Index<String>& done)
bool GetIdScope(String& os, const String& scope, const String& id, Index<String>& done)
{
if(done.Find(nest) >= 0)
if(done.Find(scope) >= 0)
return Null;
done.Add(nest);
String n = NoTemplatePars(nest);
done.Add(scope);
String n = NoTemplatePars(scope);
int q = BrowserBase().Find(n);
if(q < 0)
return Null;
CppNest& m = BrowserBase()[q];
const Array<CppItem>& m = BrowserBase()[q];
Vector<String> r;
if(m.name.Find(id) >= 0)
return n;
if(FindName(m, id) >= 0) {
os = n;
return true;
}
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
if(im.IsType()) {
Vector<String> b = Split(im.qptype, ';');
SubstituteTpars(b, nest);
SubstituteTpars(b, scope);
for(int i = 0; i < b.GetCount(); i++) {
String r = GetIdNest(b[i], id, done);
if(!IsNull(r))
return r;
if(GetIdScope(os, b[i], id, done))
return true;
}
}
}
return Null;
return false;
}
bool GetIdScope(String& os, const String& scope, const String& id)
{
Index<String> done;
return GetIdScope(os, scope, id, done);
}
bool IsPif(const String& l)
@ -955,6 +957,8 @@ void Ide::JumpS()
{
if(designer)
return;
if(!editor.assist_active)
return;
int li = editor.GetCursorLine();
String l = editor.GetUtf8Line(li);
if(IsPif(l) || IsPelse(l)) {
@ -998,8 +1002,6 @@ void Ide::JumpS()
}
return;
}
if(!editor.assist_active)
return;
q = editor.GetCursor();
while(iscid(editor.Ch(q - 1)))
q--;
@ -1008,77 +1010,76 @@ void Ide::JumpS()
Vector<String> type;
Parser parser;
editor.Context(parser, editor.GetCursor());
if(h.GetCount() == 0 && IsNull(tp)) {
type.Add(parser.current_nest);
}
if(h.GetCount() == 0 && IsNull(tp))
type.Add(parser.current_scope);
else {
type = editor.TypeOf(h, tp);
if(type.GetCount() == 0)
return;
}
String id = editor.GetWord();
Vector<String> nest;
if(id.GetCount() == 0)
return;
Vector<String> scope;
for(int i = 0; i < type.GetCount(); i++) {
Index<String> done;
String r = GetIdNest(type[i], id, done);
if(!IsNull(r))
nest.Add(r);
String r;
if(GetIdScope(r, type[i], id, done))
scope.Add(r);
}
if(nest.GetCount() == 0) {
if(scope.GetCount() == 0) {
Index<String> done;
String r = GetIdNest("::", id, done);
if(IsNull(r)) {
String t = Qualify(BrowserBase(), parser.current_nest, id);
String r;
if(GetIdScope(r, "", id, done))
scope.Add(r);
else {
String t = Qualify(BrowserBase(), parser.current_scope, id);
if(BrowserBase().Find(t) < 0)
return;
nest.Add(t);
scope.Add(t);
}
else
nest.Add(r);
}
if(nest.GetCount() == 0)
if(scope.GetCount() == 0)
return;
q = BrowserBase().Find(nest[0]);
q = BrowserBase().Find(scope[0]);
if(q < 0)
return;
const CppNest& n = BrowserBase()[q];
q = n.name.Find(id);
const Array<CppItem>& n = BrowserBase()[q];
q = FindName(n, id);
if(q >= 0)
JumpToDefinition(n[q]);
JumpToDefinition(n, q);
}
void Ide::JumpToDefinition(const CppItem& m)
void Ide::JumpToDefinition(const Array<CppItem>& n, int q)
{
if(m.pos.GetCount() == 0)
return;
int ai = 0;
for(int i = 0; i < m.pos.GetCount(); i++) {
const CppPos& fp = m.pos[i];
if(fp.impl) {
GotoCpp(fp);
String qitem = n[q].qitem;
int i = q;
while(i < n.GetCount() && n[i].qitem == qitem) {
const CppItem& m = n[i];
if(m.impl) {
GotoCpp(m);
return;
}
String ext = ToLower(GetFileExt(fp.GetFile()));
if(ext == ".cpp" || ext == ".c" || ext == ".cc")
ai = i;
if(m.filetype == FILE_CPP || m.filetype == FILE_C)
q = i;
i++;
}
GotoCpp(m.pos[ai]);
GotoCpp(n[q]);
}
void Ide::IdeGotoLink(String link)
{
LLOG("IdeGotoLink " << link);
String nest, key;
if(!SplitNestKey(link, nest, key))
return;
int q = BrowserBase().Find(nest);
String scope, item;
SplitCodeRef(link, scope, item);
int q = BrowserBase().Find(scope);
if(q < 0)
return;
const CppNest& n = BrowserBase()[q];
q = n.key.Find(key);
const Array<CppItem>& n = BrowserBase()[q];
q = FindItem(n, item);
if(q >= 0)
JumpToDefinition(n[q]);
JumpToDefinition(n, q);
}

View file

@ -175,8 +175,8 @@ void Ide::SyncBottom()
calc.SetFont(editorfont);
SetBar();
if(q == BBROWSER) {
if(!browser.nesting.IsCursor())
browser.nesting.GoBegin();
if(!browser.scopeing.IsCursor())
browser.scopeing.GoBegin();
}
if(q == BCALC)
ActiveFocus(calc);

View file

@ -3,7 +3,24 @@
#define LTIMING(x) // RTIMING(x)
#define LLOG(x)
static const char s_dbver[] = "Assist++ 2.2";
static const char s_dbver[] = "Assist++ 2.123";
void GC_Cache()
{
String cfg = ConfigFile("cfg");
FindFile ff(AppendFileName(cfg, "*.cache"));
Time tm0 = ToTime(GetSysDate() - 20);
while(ff) {
if(ff.IsFile() && Time(ff.GetLastWriteTime()) > tm0)
FileDelete(AppendFileName(cfg, ff.GetName()));
ff.Next();
}
}
String CacheFile(const String& res)
{
return AppendFileName(ConfigFile("cfg"), MD5String(res) + ".cache");
}
CppBase& BrowserBase()
{
@ -45,13 +62,11 @@ void BrowserScanError(int line, const String& text)
PutConsole(String().Cat() << s_file << " (" << line << "): " << text);
}
int NoSlash(int c)
{
return c == '/' || c == '\\' || c == ':' ? '$' : c;
}
void SaveBrowserBase()
{
LTIMING("SaveBrowserBase");
RealizeDirectory(ConfigFile("cfg"));
GC_Cache();
CppBase& base = BrowserBase();
if(base.GetCount() == 0)
return;
@ -59,30 +74,20 @@ void SaveBrowserBase()
ArrayMap<String, StringStream> out;
String s;
for(int j = 0; j < base.GetCount(); j++) {
CppNest& nest = base[j];
for(int k = 0; k < nest.GetCount(); k++) {
CppItem& m = nest.item[k];
for(int p = 0; p < m.pos.GetCount(); p++) {
StringStream& o = out.GetAdd(m.pos[p].GetFile());
s = base.GetKey(j);
o % s;
s = nest.key[k];
o % s;
s = nest.name[k];
o % s;
o % nest.namespacel;
o % m;
o % m.pos[p].line;
}
Array<CppItem>& n = base[j];
for(int k = 0; k < n.GetCount(); k++) {
CppItem& m = n[k];
StringStream& o = out.GetAdd(GetCppFile(m.file));
s = base.GetKey(j);
o % s;
o % m;
}
}
const Workspace& wspc = GetIdeWorkspace();
for(int i = 0; i < wspc.GetCount(); i++) {
String package = wspc[i];
String cfg = ConfigFile("cfg");
RealizeDirectory(cfg);
FileOut fo(AppendFileName(cfg, ForceExt(Filter(Nvl(package, "&"), NoSlash) + '@' + GetVarsName(), ".cdb")));
FileOut fo(CacheFile(package));
s = s_dbver;
fo % s;
for(int i = 0; i < fileset.GetCount(); i++)
@ -100,6 +105,7 @@ void SaveBrowserBase()
void LoadBrowserBase(Progress& pi)
{
LTIMING("LoadBrowserBase");
CppBase& base = BrowserBase();
ArrayMap<String, BrowserFileInfo>& fileset = FileSet();
String s;
@ -110,8 +116,7 @@ void LoadBrowserBase(Progress& pi)
for(int i = 0; i < wspc.GetCount(); i++) {
pi.Step();
String package = wspc[i];
String cfg = ConfigFile("cfg");
FileIn in(AppendFileName(cfg, ForceExt(Filter(package, NoSlash) + '@' + GetVarsName(), ".cdb")));
FileIn in(CacheFile(package));
in.LoadThrowing();
if(in) {
try {
@ -130,17 +135,11 @@ void LoadBrowserBase(Progress& pi)
StringStream ss(q);
ss.LoadThrowing();
while(!ss.IsEof()) {
String nest, key, name;
ss % nest;
ss % key;
ss % name;
CppNest& n = base.GetAdd(nest);
ss % n.namespacel;
CppItem& m = n.GetAdd(key, name);
String s;
ss % s;
CppItem& m = base.GetAdd(s).Add();
ss % m;
CppPos& p = m.pos.Add();
p.file = GetCppFileIndex(fn);
ss % p.line;
m.file = GetCppFileIndex(fn);
}
}
}
@ -170,7 +169,7 @@ Vector<String> SortedNests()
CppBase& base = BrowserBase();
Vector<String> n;
for(int i = 0; i < base.GetCount(); i++)
if(!base.nest.IsUnlinked(i))
if(!base.IsUnlinked(i))
n.Add(base.GetKey(i));
Sort(n);
return n;
@ -313,10 +312,5 @@ void RescanBrowserBase()
bool ExistsBrowserItem(const String& item)
{
String nest, key;
if(!SplitNestKey(item, nest, key))
return false;
CppBase& base = BrowserBase();
int q = base.Find(nest);
return q >= 0 ? base[q].key.Find(key) >= 0 : false;
return GetCodeRefItem(item);
}

View file

@ -8,33 +8,31 @@ bool MatchItemFile(const CppItem& m, const BrowserQuery& q)
{
if(IsNull(q.package) && IsNull(q.file))
return true;
for(int i = 0; i < m.pos.GetCount(); i++) {
int w = FileSet().Find(m.pos[i].GetFile());
if(w >= 0) {
const BrowserFileInfo& f = FileSet()[w];
if((IsNull(q.package) || q.package == f.package) && (IsNull(q.file) || q.file == f.file))
return true;
}
int w = FileSet().Find(GetCppFile(m.file));
if(w >= 0) {
const BrowserFileInfo& f = FileSet()[w];
if((IsNull(q.package) || q.package == f.package) && (IsNull(q.file) || q.file == f.file))
return true;
}
return false;
}
String JoinNestKey(const String& nest, const String& key)
String JoinNestKey(const String& scope, const String& key)
{
String s = nest;
String s = scope;
if(s != "::")
s << "::";
s << key;
return s;
}
bool MatchDocumented(const String& nest, const String& key, const String& name, const BrowserQuery& q)
bool MatchDocumented(const String& scope, const String& key, const String& name, const BrowserQuery& q)
{
int n = GetRefLinks(JoinNestKey(nest, key)).GetCount();
int n = GetRefLinks(JoinNestKey(scope, key)).GetCount();
return q.notdocumented && q.documented || q.notdocumented && n == 0 || q.documented && n;
}
bool MatchItem(const String& nest, const CppItem& m, const String& key, const String& name, const BrowserQuery& q, bool all)
bool MatchItem(const String& scope, const CppItem& m, const String& key, const String& name, const BrowserQuery& q, bool all)
{
if(q.a_private && m.access == PRIVATE ||
q.a_protected && m.access == PROTECTED ||
@ -43,61 +41,61 @@ bool MatchItem(const String& nest, const CppItem& m, const String& key, const St
q.code && m.IsCode() ||
q.data && m.IsData() ||
q.macro && m.IsMacro())
if(all || IsNull(q.name) || name == q.name || nest + "::" + name == q.name)
return MatchItemFile(m, q) && MatchDocumented(nest, key, name, q);
if(all || IsNull(q.name) || name == q.name || scope + "::" + name == q.name)
return MatchItemFile(m, q) && MatchDocumented(scope, key, name, q);
return false;
}
bool MatchNestName(const char *nest, const String& name)
bool MatchNestName(const char *scope, const String& name)
{
for(;;) {
if(strncmp(nest, name, name.GetLength()) == 0) {
int c = nest[name.GetLength()];
if(strncmp(scope, name, name.GetLength()) == 0) {
int c = scope[name.GetLength()];
if(c == '\0' || c == ':')
return true;
}
while(*nest != ':') {
if(*nest == '\0')
while(*scope != ':') {
if(*scope == '\0')
return false;
nest++;
scope++;
}
while(*nest == ':')
nest++;
while(*scope == ':')
scope++;
}
}
bool MatchNest(const char *nest, const CppNest& m, const BrowserQuery& q)
bool MatchNest(const char *scope, const Array<CppItem>& m, const BrowserQuery& q)
{
if(MatchNestName(nest, q.name))
if(MatchNestName(scope, q.name))
for(int i = 0; i < m.GetCount(); i++)
if(MatchItem(nest, m[i], m.key[i], m.name[i], q, true))
if(MatchItem(scope, m[i], m[i].qitem, m[i].name, q, true))
return true;
for(int i = 0; i < m.GetCount(); i++)
if(MatchItem(nest, m[i], m.key[i], m.name[i], q, false))
if(MatchItem(scope, m[i], m[i].qitem, m[i].name, q, false))
return true;
return false;
}
void Browser::WithSearch(EditString& search_nest, EditString& search_item)
void Browser::WithSearch(EditString& search_scope, EditString& search_item)
{
item.WantFocus();
search_nest.NullText("Search nest", StdFont().Italic(), SColorDisabled());
search_nest.SetFilter(CharFilterAlphaToUpper);
s_nest = &search_nest;
search_nest <<= THISBACK(Reload);
search_scope.NullText("Search scope", StdFont().Italic(), SColorDisabled());
search_scope.SetFilter(CharFilterAlphaToUpper);
s_scope = &search_scope;
search_scope <<= THISBACK(Reload);
search_item.NullText("Search item", StdFont().Italic(), SColorDisabled());
search_item.SetFilter(CharFilterAlphaToUpper);
s_item = &search_item;
search_item <<= THISBACK(EnterNesting);
}
bool Browser::FindSet(const String& knesting, const String& kitem, int nestingsc, int itemsc)
bool Browser::FindSet(const String& kscopeing, const String& kitem, int scopeingsc, int itemsc)
{
if(!IsNull(knesting) && nesting.FindSetCursor(knesting)) {
nesting.ScCursor(nestingsc);
if(!IsNull(kscopeing) && scopeing.FindSetCursor(kscopeing)) {
scopeing.ScCursor(scopeingsc);
if(!IsNull(kitem))
for(int i = 0; i < item.GetCount(); i++)
if(ValueTo<CppItemInfo>(item.Get(i)).key == kitem) {
if(ValueTo<CppItemInfo>(item.Get(i)).qitem == kitem) {
item.SetCursor(i);
item.SetSbPos(itemsc);
return true;
@ -110,35 +108,32 @@ void Browser::Reload()
{
item.active_topics = WhenShowTopic;
CppBase& base = BrowserBase();
String knesting, kitem;
int nestingsc, itemsc;
if(nesting.IsCursor()) {
knesting = nesting.GetKey();
nestingsc = nesting.GetCursorSc();
String kscopeing, kitem;
int scopeingsc, itemsc;
if(scopeing.IsCursor()) {
kscopeing = scopeing.GetKey();
scopeingsc = scopeing.GetCursorSc();
if(item.IsCursor()) {
kitem = ValueTo<CppItemInfo>(item.Get(item.GetCursor())).key;
kitem = ValueTo<CppItemInfo>(item.Get(item.GetCursor())).qitem;
itemsc = item.GetSbPos();
}
}
nesting.Clear();
scopeing.Clear();
item.Clear();
String srch;
if(s_nest)
srch = ~*s_nest;
if(s_scope)
srch = ~*s_scope;
for(int i = 0; i < base.GetCount(); i++) {
String k = base.GetKey(i);
if(MatchNest(k, base[i], query) && (srch.GetCount() == 0 || ToUpper(k).Find(srch) >= 0)) {
CppNestingInfo f;
f.namespacel = base[i].namespacel;
f.nesting = k;
nesting.Add(f.nesting, i, RawToValue<CppNestingInfo>(f));
scopeing.Add(k, i, k);
}
}
nesting.Sort();
if(!IsNull(knesting) && nesting.FindSetCursor(knesting)) {
nesting.ScCursor(nestingsc);
scopeing.Sort();
if(!IsNull(kscopeing) && scopeing.FindSetCursor(kscopeing)) {
scopeing.ScCursor(scopeingsc);
for(int i = 0; i < item.GetCount(); i++)
if(ValueTo<CppItemInfo>(item.Get(i)).key == kitem) {
if(ValueTo<CppItemInfo>(item.Get(i)).qitem == kitem) {
item.SetSbPos(itemsc);
break;
}
@ -149,32 +144,31 @@ int ItemCompare(const Value& v1, const Value& v2)
{
const CppItemInfo& a = ValueTo<CppItemInfo>(v1);
const CppItemInfo& b = ValueTo<CppItemInfo>(v2);
/* int ak = a.kind >= FUNCTION && a.kind <= CLASSFUNCTIONTEMPLATE ? FUNCTION : a.kind;
int bk = b.kind >= FUNCTION && b.kind <= CLASSFUNCTIONTEMPLATE ? FUNCTION : b.kind;
if(ak != bk)
return ak - bk;*/
int q = a.inherited - b.inherited;
if(q) return q;
q = a.fn.Compare(b.fn);
q = SgnCompare(GetCppFile(a.file), GetCppFile(b.file));
return q ? q : a.line - b.line;
}
void Browser::LoadNest(const String& nest, ArrayMap<String, CppItemInfo>& item, int inherited)
void Browser::LoadNest(const String& scope, ArrayMap<String, CppItemInfo>& item, int inherited, Index<String>& rl)
{
int q = BrowserBase().Find(nest);
if(rl.Find(scope) < 0)
return;
rl.Add(scope);
int q = BrowserBase().Find(scope);
if(q < 0)
return;
CppNest& m = BrowserBase()[q];
bool all = !IsNull(query.name) && MatchNestName(nest, query.name) || inherited;
Array<CppItem>& m = BrowserBase()[q];
bool all = !IsNull(query.name) && MatchNestName(scope, query.name) || inherited;
String base;
String srch;
if(s_item)
srch = ~*s_item;
for(int i = 0; i < m.GetCount(); i++) {
if(MatchItem(nest, m[i], m.key[i], m.name[i], query, all) &&
(srch.GetCount() == 0 || ToUpper(m.name[i]).Find(srch) >= 0)) {
if(MatchItem(scope, m[i], m[i].qitem, m[i].name, query, all) &&
(srch.GetCount() == 0 || ToUpper(m[i].name).Find(srch) >= 0)) {
const CppItem& im = m[i];
String k = m.key[i];
String k = m[i].qitem;
int q = item.Find(k);
if(q >= 0 && im.IsCode())
item[q].over = true;
@ -182,38 +176,8 @@ void Browser::LoadNest(const String& nest, ArrayMap<String, CppItemInfo>& item,
if(im.IsType())
base = im.qptype;
f.inherited = inherited;
(CppSimpleItem&)f = im;
f.name = m.name[i];
f.key = k;
f.nesting = nest;
int cline = 0;
String cfn;
int hline = 0;
String hfn;
for(int i = 0; i < im.pos.GetCount(); i++) {
const CppPos& p = im.pos[i];
String fn = p.GetFile();
if(ToUpper(GetFileExt(p.GetFile())) == ".H") {
if(p.line > hline) {
hline = p.line;
hfn = fn;
}
}
else
if(p.line > cline) {
cline = p.line;
cfn = fn;
}
}
if(!IsNull(hfn)) {
f.fn = hfn;
f.line = hline;
}
else
if(IsNull(f.fn)) {
f.fn = cfn;
f.line = cline;
}
(CppItem&)f = im;
f.scope = scope;
if(q >= 0)
for(;;) {
q = item.FindNext(q);
@ -227,16 +191,17 @@ void Browser::LoadNest(const String& nest, ArrayMap<String, CppItemInfo>& item,
if(show_inherited) {
Vector<String> b = Split(base, ';');
for(int i = 0; i < b.GetCount(); i++)
LoadNest(b[i], item, ++inherited);
LoadNest(b[i], item, ++inherited, rl);
}
}
void Browser::EnterNesting()
{
item.Clear();
if(nesting.IsCursor()) {
if(scopeing.IsCursor()) {
ArrayMap<String, CppItemInfo> m;
LoadNest(nesting.GetKey(), m, false);
Index<String> rl;
LoadNest(scopeing.GetKey(), m, false, rl);
for(int i = 0; i < m.GetCount(); i++)
item.Add(RawToValue(m[i]));
item.Sort(FnValueOrder(ItemCompare));
@ -271,20 +236,19 @@ bool Browser::IsCurrentItem()
if(!item.IsCursor())
return false;
const CppItemInfo& m = ValueTo<CppItemInfo>(item.Get(item.GetCursor()));
int q = BrowserBase().Find(m.nesting);
int q = BrowserBase().Find(m.scope);
if(q < 0)
return false;
CppNest& n = BrowserBase()[q];
q = n.key.Find(m.key);
return q >= 0 && q < n.item.GetCount();
Array<CppItem>& n = BrowserBase()[q];
return FindItem(n, m.qitem) >= 0;
}
CppItem& Browser::CurrentItem()
{
ASSERT(nesting.IsCursor() && item.IsCursor());
ASSERT(scopeing.IsCursor() && item.IsCursor());
const CppItemInfo& m = ValueTo<CppItemInfo>(item.Get(item.GetCursor()));
CppNest& n = BrowserBase().GetAdd(m.nesting);
return n.item[n.key.Find(m.key)];
Array<CppItem>& n = BrowserBase().GetAdd(m.scope);
return n[FindItem(n, m.qitem)];
}
void Browser::GotoPos(int pos)
@ -292,18 +256,17 @@ void Browser::GotoPos(int pos)
if(!IsCurrentItem())
return;
CppItem& m = CurrentItem();
CppPos& p = m.pos[pos % m.pos.GetCount()];
WhenPos(p.GetFile(), p.line);
WhenPos(GetCppFile(m.file), m.line);
}
String Browser::GetItem(int i)
{
if(i < 0 || i >= item.GetCount())
return Null;
String s = (String)nesting.GetKey();
String s = (String)scopeing.GetKey();
if(s != "::")
s << "::";
s << ValueTo<CppItemInfo>(item.Get(i)).key;
s << ValueTo<CppItemInfo>(item.Get(i)).qitem;
return s;
}
@ -314,37 +277,12 @@ CppItemInfo Browser::GetItemInfo(int i)
return ValueTo<CppItemInfo>(item.Get(i));
}
bool SplitNestKey(const String& s, String& nest, String& key)
{
CParser p(s);
if(!p.Char2(':', ':'))
return false;
const char *q = s;
for(;;) {
q = p.GetPtr();
if(p.Char('~') || p.Id("operator"))
break;
if(p.IsId()) {
String h = p.ReadId();
if(!p.Char2(':', ':'))
break;
nest << "::" << h;
}
else
break;
}
key = q;
nest = Nvl(nest, "::");
return true;
}
bool Browser::FindSet(const String& s)
{
String n;
String m;
if(!SplitNestKey(s, n, m))
return false;
return FindSet(n, m);
String scope;
String item;
SplitCodeRef(s, scope, item);
return FindSet(scope, item);
}
void Browser::ItemMenu(Bar& bar)
@ -352,14 +290,11 @@ void Browser::ItemMenu(Bar& bar)
if(IsCurrentItem()) {
if(WhenPos) {
CppItem& m = CurrentItem();
for(int i = 0; i < m.pos.GetCount(); i++) {
CppPos& p = m.pos[i];
bar.Add(String().Cat() << GetFileName(p.GetFile()) << " (" << p.line << ')',
IdeFileImage(p.GetFile()),
THISBACK1(GotoPos, i));
}
if(!m.pos.IsEmpty())
bar.Separator();
String fn = GetCppFile(m.file);
bar.Add(String().Cat() << GetFileName(fn) << " (" << m.line << ')',
IdeFileImage(fn),
THISBACK1(GotoPos, 0));
bar.Separator();
}
if(WhenShowTopic) {
Vector<String> link = GetRefLinks(GetItem());
@ -371,15 +306,15 @@ void Browser::ItemMenu(Bar& bar)
}
bar.Add("Query..", BrowserImg::Query(), THISBACK(DoDoQuery));
bar.Separator();
bar.Add(false, AsString(nesting.GetCount()) + " nests, " + AsString(item.GetCount()) + " items", Callback());
bar.Add(false, AsString(scopeing.GetCount()) + " scopes, " + AsString(item.GetCount()) + " items", Callback());
}
void Browser::QueryNest()
{
query.name = nesting.GetKey();
query.name = scopeing.GetKey();
querydlg.name <<= query.name;
Reload();
nesting.GoBegin();
scopeing.GoBegin();
item.SetCursor(0);
}
@ -391,10 +326,10 @@ void Browser::QueryWord(const String& w)
querydlg.Clear();
querydlg.name <<= w;
Reload();
nesting.GoBegin();
scopeing.GoBegin();
}
void Browser::SetId(const String& id, const Vector<String>& nest)
void Browser::SetId(const String& id, const Vector<String>& scope)
{
query.package.Clear();
query.file.Clear();
@ -402,17 +337,13 @@ void Browser::SetId(const String& id, const Vector<String>& nest)
querydlg.Clear();
querydlg.name <<= id;
CppBase& base = BrowserBase();
nesting.Clear();
for(int i = 0; i < nest.GetCount(); i++) {
int q = base.Find(nest[i]);
if(q >= 0) {
CppNestingInfo f;
f.namespacel = base[q].namespacel;
f.nesting = nest[i];
nesting.Add(f.nesting, i, RawToValue<CppNestingInfo>(f));
}
scopeing.Clear();
for(int i = 0; i < scope.GetCount(); i++) {
int q = base.Find(scope[i]);
if(q >= 0)
scopeing.Add(scope[i], i, scope[i]);
}
nesting.GoBegin();
scopeing.GoBegin();
}
void Browser::ShowTopic(String w)
@ -447,27 +378,16 @@ void Browser::Serialize(Stream& s)
s % split;
}
void CppNestingInfoDisplay::Paint(Draw& w, const Rect& r, const Value& q,
Color _ink, Color paper, dword style) const {
w.DrawRect(r, paper);
const CppNestingInfo& f = ValueTo<CppNestingInfo>(q);
bool focuscursor = (style & (FOCUS|CURSOR)) == (FOCUS|CURSOR) || (style & SELECT);
int t = r.top + (r.Height() - Draw::GetStdFontCy()) / 2;
w.DrawText(r.left, t, f.nesting, StdFont(), focuscursor ? _ink : Magenta(), f.namespacel);
w.DrawText(r.left + GetTextSize(f.nesting, StdFont(), f.namespacel).cx, t, ~f.nesting + f.namespacel,
StdFont(), _ink);
}
Browser::Browser()
{
s_nest = s_item = NULL;
nesting.NoHeader().NoGrid();
nesting.AddKey();
nesting.AddIndex();
nesting.AddColumn("").SetDisplay(Single<CppNestingInfoDisplay>());
nesting.WhenEnterRow = THISBACK(EnterNesting);
nesting.WhenLeftDouble = THISBACK(QueryNest);
nesting.NoWantFocus();
s_scope = s_item = NULL;
scopeing.NoHeader().NoGrid();
scopeing.AddKey();
scopeing.AddIndex();
scopeing.AddColumn("");
scopeing.WhenEnterRow = THISBACK(EnterNesting);
scopeing.WhenLeftDouble = THISBACK(QueryNest);
scopeing.NoWantFocus();
item.WhenEnterItem = THISBACK(EnterItem);
item.WhenLeftClick = THISBACK(ItemClick);
item.WhenLeftDouble = THISBACK(ItemDblClk);
@ -475,7 +395,7 @@ Browser::Browser()
item.active_topics = false;
item.Columns(2);
split.SetPos(2000);
Add(split.Horz(nesting, item).SizePos());
Add(split.Horz(scopeing, item).SizePos());
Register(this);
Reload();
BackPaint();

View file

@ -14,6 +14,30 @@
#define IMAGEFILE <ide/Browser/Browser.iml>
#include <Draw/iml_header.h>
class Browser;
void GC_Cache();
CppBase& BrowserBase();
void StartBrowserBase();
void BrowserBaseScan(Stream& s, const String& fn);
void ClearBrowserBase();
void RescanBrowserBase();
void SyncBrowserBase();
void SaveBrowserBase();
void Register(Browser *b); //!!!
void UnRegister(Browser *b); //!!!
bool ExistsBrowserItem(const String& item);
void ReQualifyBrowserBase();
void BrowserBaseScanLay(const String& fn);
void ScanLayFile(const char *fn);
String MakeCodeRef(const String& scope, const String& item);
void SplitCodeRef(const String& ref, String& scope, String& item);
const CppItem *GetCodeRefItem(const String& ref);
enum { WITHBODY = 33 };
inline Font BrowserFont()
@ -23,23 +47,14 @@ inline Font BrowserFont()
{ return Arial(Ctrl::VertLayoutZoom(9)); }
#endif
struct CppNestingInfo {
String nesting;
int namespacel;
};
struct CppItemInfo : CppSimpleItem, CppNestingInfo {
String key;
String name;
struct CppItemInfo : CppItem {
String scope;
bool over;
bool overed;
int inherited;
String fn;
int line;
int typei;
int nesti;
CppItemInfo() { over = overed = virt = false; inherited = line = namespacel = 0; }
CppItemInfo() { over = overed = virt = false; inherited = line = 0; }
};
enum {
@ -63,12 +78,10 @@ struct ItemTextPart : Moveable<ItemTextPart> {
int ii;
};
Vector<ItemTextPart> ParseItemNatural(const String& name, const CppSimpleItem& m, const char *natural);
Vector<ItemTextPart> ParseItemNatural(const String& name, const CppItem& m, const char *natural);
Vector<ItemTextPart> ParseItemNatural(const CppItemInfo& m);
Vector<ItemTextPart> ParseItemNatural(const CppItemInfo& m);
bool SplitNestKey(const String& s, String& nest, String& key);
struct BrowserFileInfo {
Time time;
String package;
@ -79,7 +92,7 @@ struct BrowserFileInfo {
ArrayMap<String, BrowserFileInfo>& FileSet();
int GetItemHeight(const CppSimpleItem& m, int cx);
int GetItemHeight(const CppItem& m, int cx);
struct BrowserQuery {
String name;
@ -119,12 +132,6 @@ struct CppItemInfoDisplay : public Display
virtual Size GetStdSize(const Value& q) const;
};
struct CppNestingInfoDisplay : public Display
{
virtual void Paint(Draw& w, const Rect& r, const Value& q,
Color _ink, Color paper, dword style) const;
};
class ItemList : public ColumnList {
CppItemInfoDisplay display;
@ -146,7 +153,7 @@ public:
void Serialize(Stream& s);
void SerializeWspc(Stream& s);
ArrayCtrl nesting;
ArrayCtrl scopeing;
ItemList item;
Splitter split;
BrowserQuery query;
@ -158,9 +165,9 @@ public:
Callback1<String> WhenShowTopic;
bool clickpos;
bool show_inherited;
EditString *s_item, *s_nest;
EditString *s_item, *s_scope;
void LoadNest(const String& nest, ArrayMap<String, CppItemInfo>& item, int inherited);
void LoadNest(const String& nest, ArrayMap<String, CppItemInfo>& item, int inherited, Index<String>& rl);
bool IsCurrentItem();
CppItem& CurrentItem();
void Reload();
@ -196,21 +203,6 @@ public:
~Browser();
};
CppBase& BrowserBase();
void StartBrowserBase();
void BrowserBaseScan(Stream& s, const String& fn);
void ClearBrowserBase();
void RescanBrowserBase();
void SyncBrowserBase();
void SaveBrowserBase();
void Register(Browser *b);
void UnRegister(Browser *b);
bool ExistsBrowserItem(const String& item);
void ReQualifyBrowserBase();
void BrowserBaseScanLay(const String& fn);
void ScanLayFile(const char *fn);
struct TopicInfo : Moveable<TopicInfo> {
Time time;
String path;
@ -359,7 +351,7 @@ protected:
void Tools(Bar& bar);
void Label(String&);
void CreateQtf(const String& item, const String& name, const CppSimpleItem& m, String& p1, String& p2);
void CreateQtf(const String& item, const String& name, const CppItem& m, String& p1, String& p2);
void InsertItem();
void FindBrokenRef();

View file

@ -11,6 +11,7 @@ file
Browser readonly separator,
Lay.cpp,
Base.cpp optimize_speed,
Util.cpp,
Item.cpp,
ItemList.cpp,
Query.cpp,

View file

@ -71,15 +71,8 @@ void TopicEditor::FindBrokenRef()
RichPara para = txt.Get(i);
if(para.format.label == "noref")
continue;
if(!IsNull(para.format.label)) {
String nest;
String key;
if(SplitNestKey(para.format.label, nest, key)) {
int q = BrowserBase().Find(nest);
if(q >= 0 || BrowserBase()[q].key.Find(key) >= 0)
continue;
}
}
if(!IsNull(para.format.label) && GetCodeRefItem(para.format.label))
continue;
editor.Move(txt.GetPartPos(i));
return;
}
@ -171,7 +164,7 @@ static int sSplitT(int c) {
return c == ';' || c == '<' || c == '>' || c == ',';
}
String DecoratedItem(const String& name, const CppSimpleItem& m, const char *natural)
String DecoratedItem(const String& name, const CppItem& m, const char *natural)
{
String qtf = "[%00-00K ";
Vector<ItemTextPart> n = ParseItemNatural(name, m, natural);
@ -219,7 +212,7 @@ String DecoratedItem(const String& name, const CppSimpleItem& m, const char *nat
return qtf + "]";
}
void TopicEditor::CreateQtf(const String& item, const String& name, const CppSimpleItem& m,
void TopicEditor::CreateQtf(const String& item, const String& name, const CppItem& m,
String& p1, String& p2)
{
String qtf;
@ -294,11 +287,10 @@ void TopicEditor::InsertItem()
return;
if(c == IDYES) {
String qtf = "&{{1 ";
for(int i = 0; i < ref.browser.nesting.GetCount(); i++) {
const CppNestingInfo& f = ValueTo<CppNestingInfo>(ref.browser.nesting.Get(i, 2));
for(int i = 0; i < ref.browser.scopeing.GetCount(); i++) {
if(i)
qtf << ":: ";
qtf << DeQtf(f.nesting);
qtf << DeQtf((String)ref.browser.scopeing.Get(i, 2));
}
qtf << "}}&";
editor.PasteText(ParseQTF(qtf));
@ -331,13 +323,6 @@ void TopicEditor::InsertItem()
editor.Move(c);
}
String MakeCodeRef(const String& nest, const String& item)
{
if(nest.GetCount())
return nest + "::" + item;
return item;
}
void TopicEditor::FixTopic()
{
String nest;
@ -349,7 +334,7 @@ void TopicEditor::FixTopic()
Exclamation("Nest not found");
return;
}
CppNest& n = base[q];
Array<CppItem>& n = base[q];
Index<String> natural;
Vector<String> link;
for(int i = 0; i < n.GetCount(); i++) {
@ -361,7 +346,7 @@ void TopicEditor::FixTopic()
nat << "static ";
nat << m.natural;
natural.Add(nat);
link.Add(MakeCodeRef(nest, n.key[i]));
link.Add(MakeCodeRef(nest, n[i].qitem));
}
RichText result;
const RichText& txt = editor.Get();
@ -394,9 +379,9 @@ void TopicEditor::FixTopic()
int q = natural.Find(nat);
if(q >= 0) {
started = true;
const CppSimpleItem& m = n[q];
const CppItem& m = n[q];
String p1, p2;
CreateQtf(link[q], n.name[q], m, p1, p2);
CreateQtf(link[q], n[q].name, m, p1, p2);
p1 = "[s7; &]" + p1;
RichText h = ParseQTF(styles + p1);
if(h.GetPartCount())

View file

@ -65,7 +65,7 @@ inline bool sOperator(byte c)
return sOperatorTab[c];
}
Vector<ItemTextPart> ParseItemNatural(const String& name, const CppSimpleItem& m, const char *s)
Vector<ItemTextPart> ParseItemNatural(const String& name, const CppItem& m, const char *s)
{
LLOG("ParseItemNatural " << m.natural << ", pname: " << m.pname
<< ", tname: " << m.tname << ", m.ctname: " << m.ctname);

View file

@ -130,10 +130,7 @@ int CppItemInfoDisplay::DoPaint(Draw& w, const Rect& r, const Value& q,
if(m.inherited && m.IsType())
w.DrawRect(r.left, r.top, r.Width(), 1, SColorDisabled);
String k = m.nesting;
if(k != "::")
k << "::";
k << m.key;
String k = MakeCodeRef(m.scope, m.qitem);
int cnt = GetRefLinks(k).GetCount();
if(cnt) {
Size sz = BrowserImg::Ref().GetSize();
@ -171,11 +168,7 @@ Size CppItemInfoDisplay::GetStdSize(const Value& q) const
String ItemList::Item(int i)
{
const CppItemInfo& m = ValueTo<CppItemInfo>(Get(i));
String k = m.nesting;
if(k != "::")
k << "::";
k << m.key;
return k;
return MakeCodeRef(m.scope, m.qitem);
}
int ItemList::GetTopic(Point p, String& key)

View file

@ -101,6 +101,6 @@ bool Browser::DoQuery()
if(querydlg.Perform(query) != IDOK)
return false;
Reload();
nesting.GoBegin();
scopeing.GoBegin();
return true;
}

View file

@ -0,0 +1,37 @@
#include "Browser.h"
void SplitCodeRef(const String& s, String& scope, String& item)
{
int q = s.Find('(');
q = q >= 0 ? s.ReverseFind(':', q) : s.ReverseFind(':');
if(q < 0) {
scope.Clear();
item = s;
}
else {
scope = s.Mid(0, max(q - 1, 0));
item = s.Mid(q + 1);
}
}
String MakeCodeRef(const String& nest, const String& item)
{
if(nest.GetCount())
return nest + "::" + item;
return item;
}
const CppItem *GetCodeRefItem(const String& ref)
{
String scope;
String item;
SplitCodeRef(ref, scope, item);
int q = BrowserBase().Find(scope);
if(q < 0)
return NULL;
const Array<CppItem>& n = BrowserBase()[q];
q = FindItem(n, item);
if(q < 0)
return NULL;
return &n[q];
}

View file

@ -4,7 +4,7 @@
#include "ide\Common/init"
#include "PdfDraw/init"
#include "RichEdit/init"
#define BLITZ_INDEX__ F249BD357E97BA043EF2E512156539AB2
#define BLITZ_INDEX__ F547B71646DBD1F21ED27EEFCF1ED888E
#include "TopicI.icpp"
#undef BLITZ_INDEX__
#endif

View file

@ -1,6 +1,6 @@
#include "ide.h"
#define LLOG(x) // DLOG(x)
#define LLOG(x) // DLOG(x)
struct GotoDlg : public WithGotoLayout<TopWindow> {
bool global;
@ -25,7 +25,7 @@ void GotoDlg::SyncList()
list.Clear();
String n = ~target;
int typei = Null;
int nesti = Null;
String scope = Null;
Vector<String> h = Split(n, ':');
if(n[0] == ':') {
if(h.GetCount() > 1 && *n.Last() != ':') {
@ -34,9 +34,7 @@ void GotoDlg::SyncList()
}
else
n.Clear();
nesti = gbase->Find("::" + Join(h, "::"));
if(nesti < 0)
nesti = -1;
scope = Join(h, "::");
}
else
if(h.GetCount() > 1 || h.GetCount() == 1 && *n.Last() == ':') {
@ -60,12 +58,12 @@ void GotoDlg::SyncList()
if((n.GetLength() == 0 ||
(ci ? q && memcmp_i(n, f.name, n.GetLength()) == 0 : q == 0)) &&
(IsNull(typei) || typei == f.typei) &&
(IsNull(nesti) || nesti == f.nesti)) {
list.Add(RawToValue(CppNestingInfo(f)), RawToValue(f), f.key, f.line, f.fn, f.nesting);
nc.FindAdd(f.nesting);
(IsNull(scope) || scope == f.scope)) {
list.Add(f.scope, RawToValue(f), f.item, f.line, GetCppFile(f.file), f.scope);
nc.FindAdd(f.scope);
}
}
list.HeaderTab(0).SetText(Format("Nesting (%d)", nc.GetCount()));
list.HeaderTab(0).SetText(Format("Scope (%d)", nc.GetCount()));
list.HeaderTab(1).SetText(Format("Symbol (%d)", list.GetCount()));
SyncOk();
}
@ -108,7 +106,9 @@ struct CppItemInfoSortLine {
struct CppItemInfoSortGlobal {
bool operator()(const CppItemInfo& a, const CppItemInfo& b) const {
return CombineCompare(a.nesting, b.nesting)(a.fn, b.fn)(a.line, b.line) < 0;
return CombineCompare(a.scope, b.scope)
(GetCppFile(a.file), GetCppFile(b.file))
(a.line, b.line) < 0;
}
};
@ -124,29 +124,18 @@ GotoDlg::GotoDlg(const String& s)
CppBase& base = IsNull(s) ? BrowserBase() : lbase;
gbase = &base;
for(int i = 0; i < base.GetCount(); i++) {
CppNest& n = base[i];
Array<CppItem>& n = base[i];
for(int j = 0; j < n.GetCount(); j++) {
const CppItem& m = n[j];
for(int l = 0; l < m.pos.GetCount(); l++) {
CppItemInfo mf;
(CppSimpleItem&)mf = n[j];
mf.nesting = base.GetKey(i);
mf.namespacel = n.namespacel;
const CppPos& p = m.pos[l];
mf.name = n.name[j];
mf.line = p.line;
mf.fn = p.GetFile();
mf.virt = false;
mf.access = m.pos[l].impl ? (int)WITHBODY : (int)PUBLIC;
mf.key = global ? String().Cat() << GetFileName(mf.fn) << " (" << p.line << ')' : AsString(p.line);
int nl = mf.namespacel + 2;
String tp;
if(nl < mf.nesting.GetLength())
tp = mf.nesting.Mid(nl);
mf.typei = type.FindAdd(tp);
mf.nesti = i;
item.Add(mf);
}
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(GetCppFile(m.file)) << " (" << m.line << ')'
: AsString(m.line);
mf.typei = 0;
item.Add(mf);
}
}
if(global)
@ -155,7 +144,7 @@ GotoDlg::GotoDlg(const String& s)
Sort(item, CppItemInfoSortLine());
target.SetFilter(GotoFilter);
target <<= THISBACK(SyncList);
list.AddColumn("Nesting").SetDisplay(Single<CppNestingInfoDisplay>());
list.AddColumn("Nesting");
list.AddColumn().SetDisplay(Single<CppItemInfoDisplay>());
list.AddColumn(global ? "Position" : "Line");
if(global)
@ -235,30 +224,32 @@ void Ide::SwapS()
return;
Parser p;
editor.SwapSContext(p);
int q = BrowserBase().Find(p.current_nest);
LLOG("SwapS nest: " << p.current_nest);
int q = BrowserBase().Find(p.current_scope);
LLOG("SwapS scope: " << p.current_scope);
if(q < 0)
return;
const CppNest& n = BrowserBase()[q];
q = n.key.Find(QualifyKey(BrowserBase(), p.current_nest, p.current_key));
if(q < 0 || n[q].pos.GetCount() == 1) {
q = n.name.Find(p.current_name);
const Array<CppItem>& n = BrowserBase()[q];
q = FindItem(n, QualifyKey(BrowserBase(), p.current_scope, p.current_key));
if(q < 0) return;
int count = GetCount(n, q);
if(q < 0 || count == 1) {
q = FindName(n, p.current_name);
if(q < 0)
return;
count = GetCount(n, q);
if(count == 1)
return;
}
int line = -1;
if(p.current.pos.GetCount())
line = p.current.pos.Top().line;
int file = GetCppFileIndex(editfile);
int line = p.current.line;
LLOG("SwapS line: " << line);
const CppItem& m = n[q];
int i;
for(i = 0; i < m.pos.GetCount(); i++) {
const CppPos& fp = m.pos[i];
LLOG("file: " << fp.GetFile() << ", line: " << fp.line);
if(fp.GetFile() == editfile && fp.line == line) {
for(i = 0; i < count; i++) {
LLOG("file: " << GetCppFile(n[q + i].file) << ", line: " << n[q + i].line);
if(n[q + i].file == file && n[q + i].line == line) {
i++;
break;
}
}
GotoCpp(m.pos[i % m.pos.GetCount()]);
GotoCpp(n[q + i % count]);
}

View file

@ -4,13 +4,13 @@ bool IsCb(String t) {
int q = t.Find('<');
if(q >= 0)
t.Trim(q);
return t == "::Callback" || t == "::Callback1" || t == "::Callback2" ||
t == "::Callback3" || t == "::Gate" || t == "::Gate1" || t == "::Gate2";
return t == "Callback" || t == "Callback1" || t == "Callback2" || t == "Callback3" ||
t == "Gate" || t == "Gate1" || t == "Gate2";
}
struct ThisbacksDlg : WithThisbacksLayout<TopWindow> {
struct CbInfo {
String nest;
String scope;
String type;
String name;
};
@ -18,13 +18,13 @@ struct ThisbacksDlg : WithThisbacksLayout<TopWindow> {
Index<String> nname;
Array<CbInfo> cb;
void GatherCallbacks(const String& pfx, Index<String>& done, const String& nest, int access);
void GatherCallbacks(const String& pfx, Index<String>& done, const String& scope, int access);
void CbEdit(One<Ctrl>& ctrl);
void Generate(String& ins, String& clip, const String& nest);
void Generate(String& ins, String& clip, const String& scope);
typedef ThisbacksDlg CLASSNAME;
ThisbacksDlg(const String& nest);
ThisbacksDlg(const String& scope);
};
int FilterId(int c)
@ -37,7 +37,7 @@ void ThisbacksDlg::CbEdit(One<Ctrl>& ctrl)
ctrl.Create<EditString>().SetFilter(FilterId);
}
ThisbacksDlg::ThisbacksDlg(const String& nest)
ThisbacksDlg::ThisbacksDlg(const String& scope)
{
CtrlLayoutOKCancel(*this, "THISBACKs");
list.AddColumn("Defined in");
@ -50,31 +50,31 @@ ThisbacksDlg::ThisbacksDlg(const String& nest)
list.EvenRowColor();
list.NoCursor();
Sizeable().Zoomable();
int q = BrowserBase().Find(nest);
int q = BrowserBase().Find(scope);
if(q < 0)
return;
CppNest& m = BrowserBase()[q];
for(int i = 0; i < m.GetCount(); i++)
nname.Add(m.name[i]);
const Array<CppItem>& n = BrowserBase()[q];
for(int i = 0; i < n.GetCount(); i++)
nname.Add(n[i].name);
Index<String> done;
GatherCallbacks("", done, nest, PRIVATE);
GatherCallbacks("", done, scope, PRIVATE);
}
void ThisbacksDlg::GatherCallbacks(const String& pfx, Index<String>& done,
const String& nest, int access)
const String& scope, int access)
{
String h = pfx + nest;
String h = pfx + scope;
if(done.Find(h) >= 0)
return;
done.Add(h);
int q = BrowserBase().Find(NoTemplatePars(nest));
int q = BrowserBase().Find(NoTemplatePars(scope));
if(q < 0)
return;
CppNest& m = BrowserBase()[q];
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
if(im.IsData() && IsCb(im.qtype) && im.access <= access) {
String n = m.name[i];
const Array<CppItem>& n = BrowserBase()[q];
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& m = n[i];
if(m.IsData() && IsCb(m.qtype) && m.access <= access) {
String n = m.name;
String name = pfx + '.' + n;
if(*name == '.')
name = name.Mid(1);
@ -97,29 +97,29 @@ void ThisbacksDlg::GatherCallbacks(const String& pfx, Index<String>& done,
while(nname.Find(n) >= 0)
n = "On" + n;
}
list.Add(nest, im.type, name, 0, n, m.name[i]);
list.Add(scope, m.type, name, 0, n, m.name);
}
}
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
if(im.IsType() && im.access <= access) {
Vector<String> b = Split(im.qptype, ';');
SubstituteTpars(b, nest);
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& m = n[i];
if(m.IsType() && m.access <= access) {
Vector<String> b = Split(m.qptype, ';');
SubstituteTpars(b, scope);
for(int i = 0; i < b.GetCount(); i++)
GatherCallbacks(pfx, done, b[i], min(access, (int)PROTECTED));
}
}
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
if(im.IsData() && im.type.GetCount() && !IsCb(im.qtype)
&& im.natural.Find('&') < 0 && im.natural.Find('*') < 0
&& im.access <= access
&& memcmp(m.name[i], "dv___", 5))
GatherCallbacks(pfx + "." + m.name[i], done, im.qtype, min(access, (int)PUBLIC));
for(int i = 0; i < n.GetCount(); i++) {
const CppItem& m = n[i];
if(m.IsData() && m.type.GetCount() && !IsCb(m.qtype)
&& m.natural.Find('&') < 0 && m.natural.Find('*') < 0
&& m.access <= access
&& memcmp(m.name, "dv___", 5))
GatherCallbacks(pfx + "." + m.name, done, m.qtype, min(access, (int)PUBLIC));
}
}
void ThisbacksDlg::Generate(String& ins, String& clip, const String& nest)
void ThisbacksDlg::Generate(String& ins, String& clip, const String& scope)
{
String ac;
for(int i = 0; i < list.GetCount(); i++) {
@ -143,7 +143,7 @@ void ThisbacksDlg::Generate(String& ins, String& clip, const String& nest)
type.Trim(q);
}
}
String n = nest;
String n = scope;
if(n[0] == ':' && n[1] == ':')
n = n.Mid(2);
String t = (memcmp(type, "Gate", 4) == 0 ? "bool " : "void ");
@ -164,16 +164,16 @@ void AssistEditor::Thisbacks()
{
Parser ctx;
Context(ctx, GetCursor());
if(IsNull(ctx.current_nest) || ctx.current_nest == "::" || !ctx.IsInBody())
if(IsNull(ctx.current_scope) || ctx.current_scope == "::" || !ctx.IsInBody())
return;
ThisbacksDlg dlg(ctx.current_nest);
ThisbacksDlg dlg(ctx.current_scope);
LoadFromGlobal(dlg, "ThisbacksDlg");
int c = dlg.Run();
StoreToGlobal(dlg, "ThisbacksDlg");
if(c != IDOK)
return;
String a, b;
dlg.Generate(a, b, ctx.current_nest);
dlg.Generate(a, b, ctx.current_scope);
Paste(a.ToWString());
WriteClipboardText(b);
}

View file

@ -1,26 +1,26 @@
#include "ide.h"
struct AssistItemInfo : CppSimpleItem {
struct AssistItemInfo : CppItem {
String defined;
String overed;
String name;
};
void GatherVirtuals(ArrayMap<String, AssistItemInfo>& item, const String& nest,
void GatherVirtuals(ArrayMap<String, AssistItemInfo>& item, const String& scope,
Index<String>& done)
{
if(done.Find(nest) >= 0)
if(done.Find(scope) >= 0)
return;
done.Add(nest);
int q = BrowserBase().Find(NoTemplatePars(nest));
done.Add(scope);
int q = BrowserBase().Find(NoTemplatePars(scope));
if(q < 0)
return;
CppNest& m = BrowserBase()[q];
const Array<CppItem>& m = BrowserBase()[q];
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
if(im.IsType()) {
Vector<String> b = Split(im.qptype, ';');
SubstituteTpars(b, nest);
SubstituteTpars(b, scope);
for(int i = 0; i < b.GetCount(); i++)
GatherVirtuals(item, b[i], done);
}
@ -28,17 +28,17 @@ void GatherVirtuals(ArrayMap<String, AssistItemInfo>& item, const String& nest,
for(int i = 0; i < m.GetCount(); i++) {
const CppItem& im = m[i];
if(im.IsCode()) {
String k = m.key[i];
String k = im.qitem;
if(im.IsCode()) {
int q = item.Find(k);
if(q >= 0)
item[q].overed = nest;
item[q].overed = scope;
else
if(im.virt) {
AssistItemInfo& f = item.Add(k);
f.defined = f.overed = nest;
f.name = m.name[i];
(CppSimpleItem&)f = im;
f.defined = f.overed = scope;
f.name = im.name;
(CppItem&)f = im;
}
}
}
@ -59,7 +59,7 @@ struct VirtualsDlg : public WithVirtualsLayout<TopWindow> {
list.Clear();
for(int i = 0; i < item.GetCount(); i++) {
CppItemInfo f;
(CppSimpleItem&)f = item[i];
(CppItem&)f = item[i];
f.virt = false;
f.name = item[i].name;
if(memcmp_i(name, f.name, name.GetCount()) == 0)
@ -85,9 +85,9 @@ struct VirtualsDlg : public WithVirtualsLayout<TopWindow> {
typedef VirtualsDlg CLASSNAME;
VirtualsDlg(const String& nest) {
VirtualsDlg(const String& scope) {
Index<String> done;
GatherVirtuals(item, nest, done);
GatherVirtuals(item, scope, done);
CtrlLayoutOKCancel(*this, "Virtual methods");
list.AddIndex();
list.AddIndex();
@ -114,15 +114,15 @@ void AssistEditor::Virtuals()
{
Parser ctx;
Context(ctx, GetCursor());
if(IsNull(ctx.current_nest) || ctx.current_nest == "::" || ctx.IsInBody())
if(IsNull(ctx.current_scope) || ctx.current_scope == "::" || ctx.IsInBody())
return;
VirtualsDlg dlg(ctx.current_nest);
VirtualsDlg dlg(ctx.current_scope);
LoadFromGlobal(dlg, "VirtualsDlg");
int c = dlg.Run();
StoreToGlobal(dlg, "VirtualsDlg");
if(c != IDOK)
return;
String cls = ctx.current_nest.Mid(ctx.current_namespacel);
String cls = ctx.current_scope.Mid(ctx.current_namespacel);
if(cls[0] == ':' && cls[1] == ':')
cls = cls.Mid(2);
String text;

View file

@ -402,7 +402,7 @@ struct AssistEditor : CodeEditor {
void Complete();
void Context(Parser& parser, int pos);
bool NestId(const CppNest& n, const String& id, Vector<String>& type, bool& code, String& t);
bool ScopeId(const Array<CppItem>& n, const String& id, Vector<String>& type, bool& code, String& t);
void TypeOf(const String& id, Vector<String>& r, bool& code);
Vector<String> Operator(const char *oper, const Vector<String>& type);
Vector<String> TypeOf(const Vector<String>& xp, const String& tp);
@ -787,7 +787,7 @@ public:
void SerializeOutputMode(Stream& s);
void GotoPos(String path, int line);
void GotoCpp(const CppPos& pos);
void GotoCpp(const CppItem& pos);
Vector<String> SvnDirs();
@ -1004,7 +1004,7 @@ public:
bool OpenMainPackage();
void NewMainPackage();
void JumpToDefinition(const CppItem& m);
void JumpToDefinition(const Array<CppItem>& scope, int q);
void SearchTopics();
void ShowTopics();
void ShowTopic(String topic);

View file

@ -52,9 +52,10 @@ void Ide::GotoPos(String path, int line)
AddHistory();
}
void Ide::GotoCpp(const CppPos& pos)
void Ide::GotoCpp(const CppItem& pos)
{
GotoPos(pos.GetFile(), pos.line);
GotoPos(GetCppFile(pos.file), pos.line);
}
void Ide::RescanCode()