mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-08-21 22:04:56 -06:00
developing indexer/navigator
This commit is contained in:
parent
43276ce7d1
commit
ba681dbc3b
28 changed files with 466 additions and 535 deletions
|
|
@ -311,36 +311,6 @@ void CoWork::SetPoolSize(int n)
|
|||
p.InitThreads(n);
|
||||
}
|
||||
|
||||
void CoWork::Pipe(int stepi, Function<void ()>&& fn)
|
||||
{
|
||||
Mutex::Lock __(stepmutex);
|
||||
auto& q = step.At(stepi);
|
||||
LLOG("Step " << stepi << ", count: " << q.GetCount() << ", running: " << steprunning.GetCount());
|
||||
q.AddHead(pick(fn));
|
||||
if(!steprunning.At(stepi, false)) {
|
||||
steprunning.At(stepi) = true;
|
||||
*this & [=]() {
|
||||
LLOG("Starting step " << stepi << " processor");
|
||||
stepmutex.Enter();
|
||||
for(;;) {
|
||||
Function<void ()> f;
|
||||
auto& q = step[stepi];
|
||||
LLOG("StepWork " << stepi << ", todo:" << q.GetCount());
|
||||
if(q.GetCount() == 0)
|
||||
break;
|
||||
f = pick(q.Tail());
|
||||
q.DropTail();
|
||||
stepmutex.Leave();
|
||||
f();
|
||||
stepmutex.Enter();
|
||||
}
|
||||
steprunning.At(stepi) = false;
|
||||
stepmutex.Leave();
|
||||
LLOG("Exiting step " << stepi << " processor");
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void CoWork::Reset()
|
||||
{
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -57,11 +57,6 @@ public:
|
|||
|
||||
Atomic index;
|
||||
|
||||
// experimental pipe support
|
||||
Mutex stepmutex;
|
||||
Array<BiVector<Function<void ()>>> step;
|
||||
Vector<bool> steprunning;
|
||||
|
||||
public:
|
||||
static bool TrySchedule(Function<void ()>&& fn);
|
||||
static bool TrySchedule(const Function<void ()>& fn) { return TrySchedule(clone(fn)); }
|
||||
|
|
@ -83,7 +78,6 @@ public:
|
|||
int Next() { return ++index - 1; }
|
||||
|
||||
int GetScheduledCount() const { return todo; }
|
||||
void Pipe(int stepi, Function<void ()>&& lambda); // experimental
|
||||
|
||||
static void FinLock();
|
||||
|
||||
|
|
|
|||
|
|
@ -415,7 +415,7 @@ typedef StaticMutex StaticCriticalSection;
|
|||
#endif
|
||||
|
||||
// Auxiliary multithreading - this is not using/cannot use U++ heap, so does not need cleanup.
|
||||
// Used to resolve some host platform issues.
|
||||
// Used to resolve some host platform issues. Do not use.
|
||||
|
||||
#ifdef PLATFORM_WIN32
|
||||
#define auxthread_t DWORD
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ AssistEditor::AssistEditor()
|
|||
navigatorpane.Add(search.TopPos(0, cy).HSizePos(0, cy + 4));
|
||||
navigatorpane.Add(sortitems.TopPos(0, cy).RightPos(0, cy));
|
||||
navigatorpane.Add(navigator_splitter.VSizePos(cy, 0).HSizePos());
|
||||
navigator_splitter.Vert() << scope << list << navlines;
|
||||
navigator_splitter.Vert() << scope << list;
|
||||
navigator_splitter.SetPos(1500, 0);
|
||||
navigator_splitter.SetPos(9500, 1);
|
||||
|
||||
|
|
@ -816,7 +816,7 @@ bool AssistEditor::Key(dword key, int count)
|
|||
Exclamation("No annotation for this line.");
|
||||
}
|
||||
if(key == K_F11) {
|
||||
StartIndexing(theide->GetCurrentIncludePath(), theide->GetCurrentDefines());
|
||||
Indexer::Start(theide->main, theide->GetCurrentIncludePath(), theide->GetCurrentDefines());
|
||||
}
|
||||
#endif
|
||||
if(popup.IsOpen()) {
|
||||
|
|
|
|||
|
|
@ -12,33 +12,7 @@ struct Navigator {
|
|||
enum KindEnum { KIND_LINE = -4000, KIND_NEST, KIND_FILE, KIND_SRCFILE };
|
||||
|
||||
struct NavItem : AnnotationItem {
|
||||
// int priority = 0; // for sorting based on search accuracy
|
||||
/* int decl_line = 0;
|
||||
int decl_file = 0;
|
||||
|
||||
String nest;
|
||||
String qitem;
|
||||
String name;
|
||||
String uname;
|
||||
String natural;
|
||||
String type;
|
||||
String pname;
|
||||
String ptype;
|
||||
String tname;
|
||||
String ctname;
|
||||
byte access;
|
||||
byte kind;
|
||||
int16 at;
|
||||
int line;
|
||||
int file;
|
||||
int decl_line; // header position
|
||||
int decl_file;
|
||||
bool impl;
|
||||
bool decl;
|
||||
int8 pass;
|
||||
|
||||
Vector<NavLine> linefo;
|
||||
*/
|
||||
String path;
|
||||
};
|
||||
|
||||
struct ScopeDisplay : Display {
|
||||
|
|
@ -71,7 +45,6 @@ struct Navigator {
|
|||
Array<NavItem> nitem;
|
||||
Vector<const NavItem *> litem;
|
||||
Array<NavItem> nest_item; // list separators with nest (scope) or file
|
||||
VectorMap<int, SortedVectorMap<int, int> > linefo; // TODO remove?
|
||||
NavigatorDisplay navidisplay;
|
||||
bool navigating;
|
||||
TimeCallback search_trigger;
|
||||
|
|
@ -83,7 +56,6 @@ struct Navigator {
|
|||
|
||||
ArrayCtrl scope;
|
||||
ArrayCtrl list;
|
||||
ArrayCtrl navlines;
|
||||
EditString search;
|
||||
|
||||
ScopeDisplay scope_display;
|
||||
|
|
@ -94,15 +66,10 @@ struct Navigator {
|
|||
void ListLineEnabled(int i, bool& b);
|
||||
void NaviSort();
|
||||
|
||||
Vector<NavLine> GetNavLines(const NavItem& m);
|
||||
|
||||
void Navigate();
|
||||
void ScopeDblClk();
|
||||
void NavigatorClick();
|
||||
void NavigatorEnter();
|
||||
void SyncLines();
|
||||
void SyncNavLines();
|
||||
void GoToNavLine();
|
||||
void SyncCursor();
|
||||
|
||||
typedef Navigator CLASSNAME;
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ Image CxxIcon(int kind)
|
|||
case CXCursor_EnumConstantDecl: return BrowserImg::type_enum();
|
||||
case CXCursor_ClassDecl: return BrowserImg::type_struct();
|
||||
case CXCursor_StructDecl: return BrowserImg::type_struct();
|
||||
case CXCursor_ClassTemplate: return BrowserImg::template_struct();
|
||||
case CXCursor_FunctionTemplate: return BrowserImg::template_function();
|
||||
case CXCursor_ConversionFunction: return BrowserImg::function();
|
||||
case CXCursor_FieldDecl: return BrowserImg::instance_data();
|
||||
|
|
@ -50,9 +51,18 @@ int PaintCpp(Draw& w, const Rect& r, int kind, const String& name, const String&
|
|||
for(int i = 0; i < n.GetCount(); i++)
|
||||
if(n[i].type == ITEM_NAME) {
|
||||
PaintText(w, x, y, pretty, n, i, count - i, focuscursor, ink, false);
|
||||
w.DrawText(x, y, " → ", StdFont(), SGray());
|
||||
x += GetTextSize(" → ", StdFont()).cx;
|
||||
count = i;
|
||||
while(count) { // remove trailing spaces
|
||||
const ItemTextPart& p = n[count - 1];
|
||||
if(p.len == 1 && pretty[p.pos] == ' ')
|
||||
count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if(count) {
|
||||
w.DrawText(x, y, " → ", StdFont(), SGray());
|
||||
x += GetTextSize(" → ", StdFont()).cx;
|
||||
}
|
||||
break;
|
||||
}
|
||||
PaintText(w, x, y, pretty, n, 0, count, focuscursor, ink, false);
|
||||
|
|
|
|||
|
|
@ -2,11 +2,16 @@
|
|||
|
||||
String CacheDir()
|
||||
{
|
||||
String dir;
|
||||
#ifdef PLATFORM_WIN32
|
||||
return ConfigFile("cache");
|
||||
dir = ConfigFile("cache");
|
||||
#else
|
||||
return ConfigFile(".cache/upp.cache");
|
||||
dir = ConfigFile(".cache/upp.cache");
|
||||
#endif
|
||||
ONCELOCK {
|
||||
RealizeDirectory(dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
String CacheFile(const char *name)
|
||||
|
|
@ -16,4 +21,5 @@ String CacheFile(const char *name)
|
|||
|
||||
void ReduceCache(int mb_limit)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
|
@ -10,43 +10,8 @@ void AssistEditor::SyncHeaders()
|
|||
hdepend.SetDirs(theide->GetCurrentIncludePath() + ";" + GetClangInternalIncludes());
|
||||
master_source.Clear();
|
||||
String editfile = NormalizePath(theide->editfile);
|
||||
if(editfile.GetCount() && IsCHeaderFile(editfile)) {
|
||||
DLOG("============= " << editfile);
|
||||
for(int pass = 0; pass < 2; pass++) { // all packages in second pass
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
for(int i = 0; i < wspc.GetCount(); i++) { // find package of included file
|
||||
const Package& pk = wspc.GetPackage(i);
|
||||
String pk_name = wspc[i];
|
||||
|
||||
auto Chk = [&] {
|
||||
for(int i = 0; i < pk.file.GetCount(); i++) {
|
||||
String path = SourcePath(pk_name, pk.file[i]);
|
||||
if(!PathIsEqual(editfile, path) && IsSourceFile(path)) {
|
||||
if(FindIndex(hdepend.GetDependencies(path), editfile) >= 0 && GetFileLength(path) < 200000) {
|
||||
master_source = path;
|
||||
DDUMP(master_source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if(pass) {
|
||||
if(Chk())
|
||||
return;
|
||||
}
|
||||
else
|
||||
for(int i = 0; i < pk.file.GetCount(); i++) {
|
||||
if(PathIsEqual(editfile, SourcePath(pk_name, pk.file[i]))) {
|
||||
if(Chk())
|
||||
return;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(editfile.GetCount() && IsCHeaderFile(editfile))
|
||||
master_source = FindMasterSource(hdepend, GetIdeWorkspace(), editfile);
|
||||
}
|
||||
|
||||
bool AssistEditor::DoIncludeTrick(Index<String>& visited, int level, StringBuffer& out, String path, const String& target_path, int& line_delta)
|
||||
|
|
@ -57,16 +22,12 @@ bool AssistEditor::DoIncludeTrick(Index<String>& visited, int level, StringBuffe
|
|||
return false;
|
||||
visited.Add(path);
|
||||
FileIn in(path);
|
||||
DDUMP(target_path);
|
||||
while(!in.IsEof()) {
|
||||
String l = in.GetLine();
|
||||
String tl = TrimLeft(l);
|
||||
if(!comment && tl.TrimStart("#include") && (*tl == ' ' || *tl == '\t')) {
|
||||
DDUMP(tl);
|
||||
String ipath = hdepend.FindIncludeFile(tl, filedir);
|
||||
DDUMP(ipath);
|
||||
if(ipath.GetCount()) {
|
||||
DDUMP(HdependGetDependencies(ipath));
|
||||
if(NormalizePath(ipath) == NormalizePath(target_path))
|
||||
return true;
|
||||
int q = out.GetCount();
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@ struct NavDlg : WithJumpLayout<TopWindow>, Navigator {
|
|||
virtual int GetCurrentLine();
|
||||
|
||||
void GoTo();
|
||||
void Ok() { if(navlines.IsCursor()) Break(IDOK); }
|
||||
void ListSel() { navlines.GoBegin(); }
|
||||
void Ok() { Break(IDOK); }
|
||||
void ListSel() {}
|
||||
|
||||
void Serialize(Stream& s);
|
||||
|
||||
|
|
@ -35,7 +35,6 @@ NavDlg::NavDlg()
|
|||
Icon(IdeImg::Navigator());
|
||||
list.WhenSel << THISBACK(ListSel);
|
||||
list.WhenLeftDouble = THISBACK(Ok);
|
||||
navlines.WhenLeftDouble = THISBACK(Ok);
|
||||
}
|
||||
|
||||
bool NavDlg::Key(dword key, int count)
|
||||
|
|
@ -52,10 +51,11 @@ bool NavDlg::Key(dword key, int count)
|
|||
|
||||
void NavDlg::GoTo()
|
||||
{
|
||||
if(navlines.IsCursor()) {
|
||||
// TODO
|
||||
/* if(navlines.IsCursor()) {
|
||||
const NavLine& l = navlines.Get(0).To<NavLine>();
|
||||
theide->GotoPos(GetSourceFilePath(l.file), l.line);
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
int NavDlg::GetCurrentLine()
|
||||
|
|
|
|||
|
|
@ -887,7 +887,7 @@ String Ide::GetCurrentIncludePath()
|
|||
Host host;
|
||||
CreateHost(host, false, false);
|
||||
One<Builder> b = CreateBuilder(&host);
|
||||
Index<String> cfg = PackageConfig(wspc, GetPackageIndex(), GetMethodVars(method), mainconfigparam, host, *b);
|
||||
Index<String> cfg = PackageConfig(wspc, max(GetPackageIndex(), 0), GetMethodVars(method), mainconfigparam, host, *b);
|
||||
Index<String> pkg_config;
|
||||
for(int i = 0; i < wspc.GetCount(); i++) {
|
||||
const Package& pkg = wspc.GetPackage(i);
|
||||
|
|
|
|||
|
|
@ -83,13 +83,8 @@ Navigator::Navigator()
|
|||
list.SetLineCy(max(16, GetStdFontCy()));
|
||||
list.NoWantFocus();
|
||||
list.WhenLeftClick = THISBACK(NavigatorClick);
|
||||
list.WhenSel = THISBACK(SyncNavLines);
|
||||
list.WhenLineEnabled = THISBACK(ListLineEnabled);
|
||||
|
||||
navlines.NoHeader().NoWantFocus();
|
||||
navlines.WhenLeftClick = THISBACK(GoToNavLine);
|
||||
navlines.AddColumn().SetDisplay(Single<LineDisplay>());
|
||||
|
||||
search <<= THISBACK(TriggerSearch);
|
||||
search.SetFilter(CharFilterNavigator);
|
||||
search.WhenEnter = THISBACK(NavigatorEnter);
|
||||
|
|
@ -107,8 +102,10 @@ void Navigator::SyncCursor()
|
|||
search.NullText("Symbol/lineno " + k);
|
||||
search.Tip(IsNull(search) ? String() : "Clear " + k);
|
||||
|
||||
// TODO
|
||||
/*
|
||||
if(!navigating && theide->editfile.GetCount()) {
|
||||
navlines.KillCursor();
|
||||
|
||||
int q = linefo.Find(GetSourceFileIndex(theide->editfile));
|
||||
if(q < 0)
|
||||
return;
|
||||
|
|
@ -119,46 +116,11 @@ void Navigator::SyncCursor()
|
|||
list.SetCursor(m[q]);
|
||||
navigating = false;
|
||||
}
|
||||
SyncLines();
|
||||
*/
|
||||
if(scope.IsCursor())
|
||||
scope.RefreshRow(scope.GetCursor());
|
||||
}
|
||||
|
||||
void Navigator::SyncLines()
|
||||
{
|
||||
if(IsNull(theide->editfile) || navigating)
|
||||
return;
|
||||
int ln = GetCurrentLine() + 1;
|
||||
int fi = GetSourceFileIndex(theide->editfile);
|
||||
int q = -1;
|
||||
for(int i = 0; i < navlines.GetCount(); i++) {
|
||||
const NavLine& l = navlines.Get(i, 0).To<NavLine>();
|
||||
if(l.file == fi && l.line <= ln && i < navlines.GetCount())
|
||||
q = i;
|
||||
}
|
||||
if(dlgmode)
|
||||
navlines.GoBegin();
|
||||
else
|
||||
if(q >= 0)
|
||||
navlines.SetCursor(q);
|
||||
}
|
||||
|
||||
void Navigator::SyncNavLines()
|
||||
{
|
||||
int sc = navlines.GetScroll();
|
||||
navlines.Clear();
|
||||
int ii = list.GetCursor();
|
||||
if(ii >= 0 && ii < litem.GetCount()) {
|
||||
Vector<NavLine> l = GetNavLines(*litem[ii]);
|
||||
for(int i = 0; i < l.GetCount(); i++) {
|
||||
String p = GetSourceFilePath(l[i].file);
|
||||
navlines.Add(RawToValue(l[i]));
|
||||
}
|
||||
navlines.ScrollTo(sc);
|
||||
SyncLines();
|
||||
}
|
||||
}
|
||||
|
||||
int Navigator::LineDisplay::DoPaint(Draw& w, const Rect& r, const Value& q, Color ink, Color paper, dword style, int x) const
|
||||
{
|
||||
w.DrawRect(r, paper);
|
||||
|
|
@ -185,52 +147,6 @@ Size Navigator::LineDisplay::GetStdSize(const Value& q) const
|
|||
return Size(DoPaint(w, Size(999999, 999999), q, White(), White(), 0, 0), StdFont().Bold().GetCy());
|
||||
}
|
||||
|
||||
void Navigator::GoToNavLine()
|
||||
{
|
||||
if(dlgmode)
|
||||
return;
|
||||
int ii = navlines.GetClickPos().y;
|
||||
if(ii >= 0 && ii < navlines.GetCount() && theide) {
|
||||
const NavLine& l = navlines.Get(ii, 0).To<NavLine>();
|
||||
theide->GotoPos(GetSourceFilePath(l.file), l.line);
|
||||
}
|
||||
}
|
||||
|
||||
bool Navigator::NavLine::operator<(const NavLine& b) const
|
||||
{
|
||||
String p1 = GetSourceFilePath(file);
|
||||
String p2 = GetSourceFilePath(b.file);
|
||||
return CombineCompare/*(!impl, !b.impl)*/
|
||||
(GetFileExt(p2), GetFileExt(p1)) // .h > .c
|
||||
(GetFileName(p1), GetFileName(p2))
|
||||
(p1, p2)
|
||||
(line, b.line) < 0;
|
||||
}
|
||||
|
||||
Vector<Navigator::NavLine> Navigator::GetNavLines(const NavItem& m)
|
||||
{
|
||||
_DBG_
|
||||
Vector<NavLine> l;
|
||||
/*
|
||||
CodeBaseLock __;
|
||||
int q = CodeBase().Find(m.nest);
|
||||
if(q < 0 || IsNull(m.qitem))
|
||||
return l;
|
||||
const Array<CppItem>& a = CodeBase()[q];
|
||||
for(int i = 0; i < a.GetCount(); i++) {
|
||||
const CppItem& mm = a[i];
|
||||
if(mm.qitem == m.qitem) {
|
||||
NavLine& nl = l.Add();
|
||||
nl.impl = mm.impl;
|
||||
nl.file = mm.file;
|
||||
nl.line = mm.line;
|
||||
}
|
||||
}
|
||||
Sort(l);
|
||||
*/
|
||||
return l;
|
||||
}
|
||||
|
||||
void Navigator::Navigate()
|
||||
{
|
||||
if(navigating)
|
||||
|
|
@ -256,20 +172,7 @@ void Navigator::Navigate()
|
|||
theide->AddHistory();
|
||||
}
|
||||
else {
|
||||
Vector<NavLine> l = GetNavLines(m);
|
||||
int q = l.GetCount() - 1;
|
||||
for(int i = 0; i < l.GetCount(); i++)
|
||||
if(GetSourceFilePath(l[i].file) == NormalizeSourcePath(theide->editfile) && l[i].line == ln) {
|
||||
q = (i + l.GetCount() + 1) % l.GetCount();
|
||||
break;
|
||||
}
|
||||
if(q >= 0 && q < l.GetCount()) {
|
||||
String path = GetSourceFilePath(l[q].file);
|
||||
// TODO:
|
||||
_DBG_
|
||||
// if(!theide->GotoDesignerFile(path, m.nest, m.name, l[q].line))
|
||||
// theide->GotoPos(path, l[q].line);
|
||||
}
|
||||
theide->GotoPos(m.path, m.line);
|
||||
}
|
||||
}
|
||||
navigating = false;
|
||||
|
|
@ -432,7 +335,7 @@ void Navigator::Search()
|
|||
wholeclass = *s == '.' && search_nest.GetCount();
|
||||
}
|
||||
else {
|
||||
search_name = search_nest = ~search;
|
||||
search_name = ~search;
|
||||
both = true;
|
||||
}
|
||||
s = Join(Split(s, '.'), "::") + (s.EndsWith(".") ? "::" : "");
|
||||
|
|
@ -460,23 +363,26 @@ void Navigator::Search()
|
|||
for(const AnnotationItem& m : theide->editor.annotations) {
|
||||
NavItem& n = nitem.Add();
|
||||
(AnnotationItem&)n = m;
|
||||
n.path = theide->editfile;
|
||||
nests.FindAdd(n.nest = Nest(m, theide->editfile));
|
||||
}
|
||||
SortIndex(nests);
|
||||
}
|
||||
else { // TODO: Sort codeindex paths, add files in that order to make things stable
|
||||
else {
|
||||
navigator_global = true;
|
||||
String usearch_nest = ToUpper(search_nest);
|
||||
String usearch_name = ToUpper(search_name);
|
||||
Index<String> visited;
|
||||
SortByKey(CodeIndex());
|
||||
for(int pass = 0; pass < 2; pass++)
|
||||
for(const auto& f : ~CodeIndex())
|
||||
for(const AnnotationItem& m : f.value.items) {
|
||||
int q = visited.Find(m.id);
|
||||
if(q >= 0) { // replace definition (.cpp) with declaration (.h)
|
||||
AnnotationItem& n = nitem[q];
|
||||
if(n.definition && !m.definition) { // file: make it stable
|
||||
if(q >= 0) { // replace declaration (.h) with definition (.cpp)
|
||||
NavItem& n = nitem[q];
|
||||
if(!n.definition && m.definition) {
|
||||
(AnnotationItem&)n = m;
|
||||
n.path = f.key;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
@ -485,6 +391,7 @@ void Navigator::Search()
|
|||
visited.Add(m.id);
|
||||
NavItem& n = nitem.Add();
|
||||
(AnnotationItem&)n = m;
|
||||
n.path = f.key;
|
||||
nests.FindAdd(n.nest = Nest(m, theide->editfile));
|
||||
}
|
||||
}
|
||||
|
|
@ -560,7 +467,6 @@ void Navigator::Scope()
|
|||
LTIMING("FINALIZE");
|
||||
litem.Clear();
|
||||
nest_item.Clear();
|
||||
linefo.Clear();
|
||||
String sc = scope.GetKey();
|
||||
String nest;
|
||||
for(const NavItem& n : nitem)
|
||||
|
|
@ -569,7 +475,6 @@ void Navigator::Scope()
|
|||
NavItem& m = nest_item.Add();
|
||||
m.kind = KIND_NEST;
|
||||
nest = m.pretty = n.nest;
|
||||
DDUMP(n.nest);
|
||||
litem.Add(&m);
|
||||
}
|
||||
litem.Add(&n);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "ide.h"
|
||||
|
||||
struct UppHubNest : Moveable<UppHubNest> {
|
||||
int tier = -1;
|
||||
String name;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#define LLOG(x)
|
||||
|
||||
bool autocomplete_parsing;
|
||||
Semaphore autocomplete_event;
|
||||
CoEvent autocomplete_event;
|
||||
CurrentFileContext autocomplete_file;
|
||||
bool do_autocomplete;
|
||||
bool autocomplete_macros;
|
||||
|
|
@ -121,7 +121,7 @@ void SetAutoCompleteFile(const CurrentFileContext& ctx)
|
|||
{
|
||||
GuiLock __;
|
||||
autocomplete_file = ctx;
|
||||
autocomplete_event.Release();
|
||||
autocomplete_event.Broadcast();
|
||||
}
|
||||
|
||||
void StartAutoComplete(const CurrentFileContext& ctx, int line, int column, bool macros,
|
||||
|
|
@ -136,7 +136,7 @@ void StartAutoComplete(const CurrentFileContext& ctx, int line, int column, bool
|
|||
autocomplete_serial = serial++;
|
||||
autocomplete_done = done;
|
||||
autocomplete_file = ctx;
|
||||
autocomplete_event.Release();
|
||||
autocomplete_event.Broadcast();
|
||||
}
|
||||
|
||||
void CancelAutoComplete()
|
||||
|
|
|
|||
|
|
@ -1,129 +0,0 @@
|
|||
#include "clang.h"
|
||||
|
||||
// TODO: Remove
|
||||
|
||||
#define LLOG(x)
|
||||
|
||||
CXChildVisitResult current_file_visitor2( CXCursor cursor, CXCursor p, CXClientData clientData )
|
||||
{
|
||||
#if 0
|
||||
auto Dump = [&] {
|
||||
#if 1
|
||||
SourceLocation location(cxlocation);
|
||||
LOG("=====================");
|
||||
// DDUMP(location);
|
||||
// DDUMP((int)cursorKind);
|
||||
DDUMP(GetCursorKindName(cursorKind));
|
||||
DDUMP(name);
|
||||
DDUMP(type);
|
||||
DDUMP(pid);
|
||||
DDUMP(CleanupId(pid));
|
||||
DDUMP(scope);
|
||||
DDUMP(nspace);
|
||||
DDUMP(clang_isCursorDefinition(cursor));
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
static Index<unsigned> visited;
|
||||
unsigned h = clang_hashCursor(cursor);
|
||||
if(visited.Find(h) >= 0)
|
||||
return CXChildVisit_Continue;
|
||||
visited.Add(h);
|
||||
#endif
|
||||
CXSourceLocation cxlocation = clang_getCursorLocation( cursor );
|
||||
SourceLocation location = cxlocation;
|
||||
// if( clang_Location_isFromMainFile( location ) == 0 )
|
||||
// return CXChildVisit_Continue;
|
||||
|
||||
CXCursor parent = clang_getCursorSemanticParent(cursor);
|
||||
CXCursorKind cursorKind = clang_getCursorKind(cursor);
|
||||
CXCursorKind parentKind = clang_getCursorKind(parent);
|
||||
|
||||
unsigned int curLevel = *( reinterpret_cast<unsigned int*>(clientData));
|
||||
unsigned int nextLevel = curLevel + 1;
|
||||
|
||||
if(curLevel > 100000 && curLevel - 100000 > 2)
|
||||
return CXChildVisit_Continue;
|
||||
|
||||
String name = GetCursorSpelling(cursor);
|
||||
String type = GetTypeSpelling(cursor);
|
||||
String display = FetchString(clang_getCursorDisplayName(cursor));
|
||||
String scope = GetTypeSpelling(parent);
|
||||
if(scope.GetCount())
|
||||
scope << "::";
|
||||
|
||||
String m;
|
||||
|
||||
auto Dump = [&] {
|
||||
#if 0
|
||||
LOG("=====================");
|
||||
DDUMP(GetCursorKindName(cursorKind));
|
||||
DDUMP(GetCursorSpelling(cursor));
|
||||
DDUMP(GetTypeSpelling(cursor));
|
||||
DDUMP(FetchString(clang_getCursorDisplayName(cursor)));
|
||||
DDUMP(clang_isCursorDefinition(cursor));
|
||||
// DDUMP(FetchString(clang_getCursorPrettyPrinted(cursor, NULL)));
|
||||
DDUMP(GetCursorKindName(parentKind));
|
||||
DDUMP(GetCursorSpelling(parent));
|
||||
DDUMP(GetTypeSpelling(parent));
|
||||
// DDUMP(location);
|
||||
#endif
|
||||
};
|
||||
|
||||
bool valid = clang_Location_isFromMainFile(cxlocation);
|
||||
if(valid) {
|
||||
switch(cursorKind) {
|
||||
case CXCursor_FieldDecl:
|
||||
case CXCursor_VarDecl:
|
||||
case CXCursor_CXXMethod:
|
||||
m << scope << display;
|
||||
break;
|
||||
case CXCursor_StructDecl:
|
||||
m = type << "::struct";
|
||||
break;
|
||||
case CXCursor_UnionDecl:
|
||||
m = type << "::union";
|
||||
break;
|
||||
case CXCursor_ClassDecl:
|
||||
m = type << "::class";
|
||||
break;
|
||||
case CXCursor_FunctionDecl:
|
||||
m = display;
|
||||
break;
|
||||
case CXCursor_EnumDecl:
|
||||
case CXCursor_EnumConstantDecl:
|
||||
// case CXCursor_ParmDecl:
|
||||
case CXCursor_TypedefDecl:
|
||||
case CXCursor_Namespace:
|
||||
case CXCursor_Constructor:
|
||||
case CXCursor_Destructor:
|
||||
case CXCursor_ConversionFunction:
|
||||
case CXCursor_FunctionTemplate:
|
||||
case CXCursor_ClassTemplate:
|
||||
case CXCursor_UnexposedDecl:
|
||||
// case CXCursor_NamespaceAlias:
|
||||
break;
|
||||
default:
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(valid) {
|
||||
Dump();
|
||||
if(m.GetCount())
|
||||
LLOG(">> " << GetCursorKindName(cursorKind) << ": " << m);
|
||||
}
|
||||
clang_visitChildren(cursor, current_file_visitor2, &nextLevel);
|
||||
return CXChildVisit_Continue;
|
||||
}
|
||||
|
||||
// TODO: Remove
|
||||
void CurrentFileVisit(CXTranslationUnit tu)
|
||||
{
|
||||
CXCursor rootCursor = clang_getTranslationUnitCursor(tu);
|
||||
unsigned int treeLevel = 0;
|
||||
clang_visitChildren(rootCursor, current_file_visitor2, &treeLevel);
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@
|
|||
#define LLOG(x)
|
||||
|
||||
bool current_file_parsing;
|
||||
Semaphore current_file_event; // TODO?
|
||||
CoEvent current_file_event;
|
||||
CurrentFileContext current_file;
|
||||
int64 current_file_serial;
|
||||
int64 current_file_done_serial;
|
||||
|
|
@ -44,7 +44,6 @@ void CurrentFileThread()
|
|||
}
|
||||
if(f.filename.GetCount()) {
|
||||
String fn = f.filename;
|
||||
DDUMP(fn);
|
||||
if(!IsSourceFile(fn))
|
||||
fn.Cat(".cpp");
|
||||
if(f.filename != parsed_file.filename || f.real_filename != parsed_file.real_filename ||
|
||||
|
|
@ -54,7 +53,6 @@ void CurrentFileThread()
|
|||
{
|
||||
TIMESTOP("CurrentFile parse");
|
||||
current_file_parsing = true;
|
||||
DDUMP(fn);
|
||||
clang.Parse(fn, f.content, f.includes, f.defines,
|
||||
CXTranslationUnit_DetailedPreprocessingRecord|
|
||||
CXTranslationUnit_PrecompiledPreamble|
|
||||
|
|
@ -91,7 +89,7 @@ void SetCurrentFile(const CurrentFileContext& ctx, Event<const Vector<Annotation
|
|||
GuiLock __;
|
||||
current_file = ctx;
|
||||
annotations_done = done;
|
||||
current_file_event.Release();
|
||||
current_file_event.Broadcast();
|
||||
current_file_serial++;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,7 @@
|
|||
#include "clang.h"
|
||||
|
||||
// TODO: remove
|
||||
|
||||
#if 0
|
||||
case FUNCTIONTEMPLATE:
|
||||
bk = BrowserImg::template_function();
|
||||
|
|
|
|||
|
|
@ -1,8 +1,48 @@
|
|||
#include "clang.h"
|
||||
|
||||
#define LTIMING(x)
|
||||
#define LTIMESTOP(x)
|
||||
#define LLOG(x)
|
||||
#define LTIMESTOP(x) TIMESTOP(x)
|
||||
#define LLOG(x) DLOG(x)
|
||||
|
||||
String FindMasterSource(Hdepend& hdepend, const Workspace& wspc, const String& header_file)
|
||||
{
|
||||
DDUMP(header_file);
|
||||
String master_source;
|
||||
for(int pass = 0; pass < 2; pass++) { // all packages in second pass
|
||||
for(int i = 0; i < wspc.GetCount(); i++) { // find package of included file
|
||||
const Package& pk = wspc.GetPackage(i);
|
||||
String pk_name = wspc[i];
|
||||
|
||||
auto Chk = [&] {
|
||||
for(int i = 0; i < pk.file.GetCount(); i++) {
|
||||
String path = SourcePath(pk_name, pk.file[i]);
|
||||
if(!PathIsEqual(header_file, path) && IsSourceFile(path)) {
|
||||
DDUMP(hdepend.GetDependencies(path));
|
||||
if(FindIndex(hdepend.GetDependencies(path), header_file) >= 0 && GetFileLength(path) < 200000) {
|
||||
master_source = path;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
if(pass) {
|
||||
if(Chk())
|
||||
return master_source;
|
||||
}
|
||||
else
|
||||
for(int i = 0; i < pk.file.GetCount(); i++) {
|
||||
if(PathIsEqual(header_file, SourcePath(pk_name, pk.file[i]))) {
|
||||
if(Chk())
|
||||
return master_source;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return master_source;
|
||||
}
|
||||
|
||||
void AnnotationItem::Serialize(Stream& s)
|
||||
{
|
||||
|
|
@ -16,16 +56,27 @@ void AnnotationItem::Serialize(Stream& s)
|
|||
% uname
|
||||
% nest
|
||||
% unest;
|
||||
|
||||
}
|
||||
|
||||
struct BlitzMaker {
|
||||
Time time;
|
||||
String blitz;
|
||||
Vector<String> individual;
|
||||
void FileAnnotation::Serialize(Stream& s)
|
||||
{
|
||||
s % defines
|
||||
% includes
|
||||
% time
|
||||
% items;
|
||||
}
|
||||
|
||||
void Do(const String& pk_name, const Vector<Tuple<String, bool>>& file, Hdepend& hdepend);
|
||||
};
|
||||
String CachedAnnotationPath(const String& source_file, const String& defines, const String& includes, const String& master = Null)
|
||||
{
|
||||
// TODO: master file?
|
||||
Sha1Stream s;
|
||||
s << source_file
|
||||
<< defines
|
||||
<< includes
|
||||
<< master
|
||||
;
|
||||
return CacheFile(GetFileTitle(source_file) + "$" + s.FinishString() + ".code_index");
|
||||
}
|
||||
|
||||
void BlitzFile(String& blitz, const String& sourceFile, Hdepend& hdepend, int index)
|
||||
{
|
||||
|
|
@ -40,145 +91,234 @@ void BlitzFile(String& blitz, const String& sourceFile, Hdepend& hdepend, int in
|
|||
blitz << "#undef BLITZ_INDEX__\r\n";
|
||||
}
|
||||
|
||||
void BlitzMaker::Do(const String& pk_name, const Vector<Tuple<String, bool>>& file, Hdepend& hdepend)
|
||||
ArrayMap<String, FileAnnotation>& CodeIndex()
|
||||
{
|
||||
blitz.Clear();
|
||||
individual.Clear();
|
||||
time = Null;
|
||||
int index = 1;
|
||||
for(const auto& m : file) {
|
||||
if(IsCSourceFile(m.a)) {
|
||||
Time filetime = hdepend.FileTime(m.a);
|
||||
time = max(Nvl(time, filetime), filetime);
|
||||
if(hdepend.BlitzApproved(m.a) && !m.b)
|
||||
BlitzFile(blitz, m.a, hdepend, index++);
|
||||
else
|
||||
individual.Add(m.a);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArrayMap<String, FileAnnotation>& WriteCodeIndex()
|
||||
{
|
||||
DTIMING("WriteCodeIndex");
|
||||
static ArrayMap<String, FileAnnotation> m;
|
||||
return m;
|
||||
}
|
||||
|
||||
const ArrayMap<String, FileAnnotation>& CodeIndex()
|
||||
void DumpIndex()
|
||||
{
|
||||
return WriteCodeIndex();
|
||||
GuiLock __;
|
||||
FileOut out(ConfigFile("current_index.dump"));
|
||||
ArrayMap<String, FileAnnotation>& x = CodeIndex();
|
||||
for(const auto& m : ~x) {
|
||||
out << m.key << "\n";
|
||||
for(const auto& n : m.value.items)
|
||||
out << '\t' << n.name << " " << n.id << " " << n.pretty << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
static std::atomic<int> indexer_pkgi;
|
||||
static std::atomic<int> running_indexers;
|
||||
static Index<String> visited_files;
|
||||
static Mutex visited_files_mutex;
|
||||
CoEvent Indexer::event;
|
||||
Hdepend Indexer::hdepend;
|
||||
Mutex Indexer::mutex;
|
||||
Vector<Indexer::Job> Indexer::jobs;
|
||||
int Indexer::jobi;
|
||||
std::atomic<int> Indexer::running_indexers;
|
||||
Workspace Indexer::wspc;
|
||||
VectorMap<String, String> Indexer::master_file;
|
||||
|
||||
bool IsIndexing()
|
||||
void Indexer::IndexerThread()
|
||||
{
|
||||
return running_indexers;
|
||||
}
|
||||
|
||||
void Indexer(const String& includes, const String& defines)
|
||||
{
|
||||
static Hdepend hdepend; // shared between threads
|
||||
static Mutex hdepend_mutex;
|
||||
ONCELOCK {
|
||||
hdepend.NoConsole();
|
||||
};
|
||||
Clang clang;
|
||||
int tm0 = msecs();
|
||||
running_indexers++;
|
||||
for(;;) {
|
||||
BlitzMaker m;
|
||||
String pk_name;
|
||||
Vector<Tuple<String, bool>> pk_files;
|
||||
Index<String> pk_files_index;
|
||||
{
|
||||
GuiLock __;
|
||||
const Workspace& wspc = GetIdeWorkspace();
|
||||
int pkgi = indexer_pkgi++;
|
||||
if(pkgi >= wspc.GetCount())
|
||||
break;
|
||||
LTIMING("Indexer Fetch");
|
||||
pk_name = wspc[pkgi];
|
||||
const Package& pk = wspc.GetPackage(pkgi);
|
||||
for(int i = 0; i < pk.GetCount(); i++) {
|
||||
String path = SourcePath(pk_name, pk[i]);
|
||||
pk_files.Add({ path, pk[i].noblitz });
|
||||
pk_files_index.Add(path);
|
||||
}
|
||||
}
|
||||
{
|
||||
Mutex::Lock __(hdepend_mutex);
|
||||
m.Do(pk_name, pk_files, hdepend);
|
||||
}
|
||||
// TODO: Check time
|
||||
|
||||
auto ProcessResults = [&] {
|
||||
ClangVisitor v;
|
||||
Index<String> doing_files;
|
||||
v.WhenFile = [&](const String& path) {
|
||||
return pk_files_index.Find(path) >= 0;
|
||||
};
|
||||
while(!Thread::IsShutdownThreads()) {
|
||||
Clang clang;
|
||||
int tm0 = msecs();
|
||||
running_indexers++;
|
||||
for(;;) {
|
||||
Job job;
|
||||
{
|
||||
DTIMING("Visitor");
|
||||
v.Do(clang.tu);
|
||||
Mutex::Lock __(mutex);
|
||||
if(jobi >= jobs.GetCount())
|
||||
break;
|
||||
job = jobs[jobi++];
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
GuiLock __;
|
||||
DTIMING("Process files");
|
||||
for(int i = 0; i < v.item.GetCount(); i++) {
|
||||
DTIMING("Process file");
|
||||
FileAnnotation& f = WriteCodeIndex().GetAdd(v.item.GetKey(i));
|
||||
f.defines = defines;
|
||||
f.includes = includes;
|
||||
DTIMING("Process file pick");
|
||||
f.items = pick(v.item[i]);
|
||||
}
|
||||
LTIMESTOP("Parsing " + job.path + " " + AsString(job.file_times));
|
||||
clang.Parse(job.path, job.blitz, job.includes, job.defines,
|
||||
CXTranslationUnit_DetailedPreprocessingRecord|
|
||||
CXTranslationUnit_KeepGoing|
|
||||
CXTranslationUnit_SkipFunctionBodies|
|
||||
(job.blitz.GetCount() ? 0 : PARSE_FILE));
|
||||
DumpDiagnostics(clang.tu);
|
||||
}
|
||||
};
|
||||
|
||||
LTIMESTOP("======= Indexing " + pk_name);
|
||||
for(const String& fn : m.individual) {
|
||||
LTIMESTOP("Indexing " + fn);
|
||||
clang.Parse(fn, Null, includes, defines,
|
||||
CXTranslationUnit_DetailedPreprocessingRecord|
|
||||
CXTranslationUnit_KeepGoing|
|
||||
PARSE_FILE);
|
||||
if(clang.tu)
|
||||
ProcessResults();
|
||||
|
||||
if(Thread::IsShutdownThreads())
|
||||
break;
|
||||
|
||||
ClangVisitor v;
|
||||
if(clang.tu) {
|
||||
DumpDiagnostics(clang.tu);
|
||||
|
||||
String current_file;
|
||||
bool do_file = false;
|
||||
VectorMap<String, bool> do_file_cache;
|
||||
|
||||
v.WhenFile = [&](const String& path) {
|
||||
if(IsNull(path))
|
||||
return false;
|
||||
if(current_file != path) {
|
||||
current_file = path;
|
||||
if(IsNull(path) || path.EndsWith("$$$blitz.cpp"))
|
||||
do_file = false;
|
||||
else
|
||||
if(IsCSourceFile(path))
|
||||
do_file = true;
|
||||
else {
|
||||
current_file = path;
|
||||
int q = do_file_cache.Find(path);
|
||||
if(q < 0) {
|
||||
Mutex::Lock __(mutex);
|
||||
do_file = job.file_times.Find(master_file.Get(NormalizePath(path), Null)) >= 0;
|
||||
do_file_cache.Add(path, do_file);
|
||||
}
|
||||
else
|
||||
do_file = do_file_cache[q];
|
||||
}
|
||||
}
|
||||
return do_file;
|
||||
};
|
||||
|
||||
v.Do(clang.tu);
|
||||
}
|
||||
|
||||
|
||||
for(const auto& m : ~job.file_times) {
|
||||
FileAnnotation f;
|
||||
f.defines = job.defines;
|
||||
f.includes = job.includes;
|
||||
int q = v.item.Find(m.key);
|
||||
if(q >= 0)
|
||||
f.items = pick(v.item[q]);
|
||||
else
|
||||
f.items.Clear();
|
||||
f.time = job.file_times.Get(m.key, Time::Low());
|
||||
SaveChangedFile(CachedAnnotationPath(m.key, f.defines, f.includes, Null), StoreAsString(f), true);
|
||||
GuiLock __;
|
||||
CodeIndex().GetAdd(m.key) = pick(f);
|
||||
}
|
||||
|
||||
}
|
||||
if(Thread::IsShutdownThreads())
|
||||
break;
|
||||
LTIMESTOP("Indexing BLITZ " + pk_name);
|
||||
clang.Parse(ConfigFile(pk_name + "$$$blitz.cpp"), m.blitz, includes, defines,
|
||||
CXTranslationUnit_DetailedPreprocessingRecord|
|
||||
CXTranslationUnit_KeepGoing);
|
||||
if(clang.tu)
|
||||
ProcessResults();
|
||||
|
||||
if(Thread::IsShutdownThreads())
|
||||
break;
|
||||
if(--running_indexers == 0) {
|
||||
LLOG("Done everything " << (msecs() - tm0) / 1000.0 << " s");
|
||||
DumpIndex(); // TODO remove
|
||||
}
|
||||
event.Wait(500);
|
||||
}
|
||||
if(--running_indexers == 0)
|
||||
LLOG("Done everything " << (msecs() - tm0) / 1000.0 << " s");
|
||||
LLOG("Done");
|
||||
}
|
||||
|
||||
void StartIndexing(const String& includes, const String& defines)
|
||||
void Indexer::Start(const String& main, const String& includes, const String& defines)
|
||||
{
|
||||
{
|
||||
Mutex::Lock __(visited_files_mutex);
|
||||
visited_files.Clear();
|
||||
}
|
||||
indexer_pkgi = 0;
|
||||
if(!IsIndexing()) {
|
||||
DLOG("Indexer::Start =============================== ");
|
||||
|
||||
ONCELOCK {
|
||||
for(int i = 0; i < CPU_Cores(); i++) // TODO: CPU_Cores?
|
||||
Thread::StartNice([=] { Indexer(includes, defines); });
|
||||
Thread::StartNice([=] { Indexer::IndexerThread(); });
|
||||
}
|
||||
|
||||
Thread::Start([=] {
|
||||
{
|
||||
GuiLock __;
|
||||
DTIMING("Load workspace");
|
||||
wspc.Scan(main);
|
||||
}
|
||||
|
||||
{
|
||||
DTIMING("Create indexer jobs");
|
||||
Mutex::Lock __(mutex);
|
||||
hdepend.NoConsole();
|
||||
hdepend.SetDirs(includes);
|
||||
jobs.Clear();
|
||||
|
||||
master_file.Clear();
|
||||
for(int pi = 0; pi < wspc.GetCount(); pi++) {
|
||||
String pk_name = wspc[pi];
|
||||
const Package& pk = wspc.GetPackage(pi);
|
||||
for(int i = 0; i < pk.GetCount(); i++) {
|
||||
String path = NormalizePath(SourcePath(pk_name, pk[i]));
|
||||
if(IsCSourceFile(path)) {
|
||||
master_file.Add(path, path);
|
||||
for(String p : hdepend.GetDependencies(path)) {
|
||||
p = NormalizePath(p);
|
||||
if(master_file.Find(p) < 0)
|
||||
master_file.Add(p, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(String path : master_file.GetKeys()) {
|
||||
FileAnnotation0 f;
|
||||
{
|
||||
GuiLock __;
|
||||
f = CodeIndex().GetAdd(path);
|
||||
}
|
||||
if(f.includes != includes || f.defines != defines) {
|
||||
String h = LoadFile(CachedAnnotationPath(path, defines, includes, Null));
|
||||
if(h.GetCount()) {
|
||||
FileAnnotation m;
|
||||
if(LoadFromString(m, h)) {
|
||||
m.time = m.time;
|
||||
GuiLock __;
|
||||
CodeIndex().GetAdd(path) = pick(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{ // remove files that are not in project anymore
|
||||
GuiLock __;
|
||||
for(int i = 0; i < CodeIndex().GetCount(); i++)
|
||||
if(master_file.Find(CodeIndex().GetKey(i)) < 0)
|
||||
CodeIndex().Unlink(i);
|
||||
CodeIndex().Sweep();
|
||||
}
|
||||
|
||||
jobi = 0;
|
||||
for(int pi = 0; pi < wspc.GetCount(); pi++) {
|
||||
String blitz;
|
||||
VectorMap<String, Time> blitz_files;
|
||||
String pk_name = wspc[pi];
|
||||
const Package& pk = wspc.GetPackage(pi);
|
||||
auto AddJob = [&](const String& path) -> Job& {
|
||||
Job& job = jobs.Add();
|
||||
job.includes = includes;
|
||||
job.defines = defines;
|
||||
job.path = path;
|
||||
return job;
|
||||
};
|
||||
for(int i = 0; i < pk.GetCount(); i++) {
|
||||
String path = NormalizePath(SourcePath(pk_name, pk[i]));
|
||||
if(IsCSourceFile(path)) {
|
||||
Time time = hdepend.FileTime(path);
|
||||
FileAnnotation0 f;
|
||||
{
|
||||
GuiLock __;
|
||||
f = CodeIndex().GetAdd(path);
|
||||
}
|
||||
DLOG("===========");
|
||||
DDUMP(path);
|
||||
DDUMP(time);
|
||||
DDUMP(f.time);
|
||||
if(f.defines != defines || f.includes != includes || f.time != time) {
|
||||
if(hdepend.BlitzApproved(path) && !pk[i].noblitz) {
|
||||
BlitzFile(blitz, path, hdepend, i);
|
||||
blitz_files.Add(path, time);
|
||||
}
|
||||
else
|
||||
AddJob(path).file_times.Add(path, time);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(blitz.GetCount()) {
|
||||
Job& job = AddJob(ConfigFile(pk_name + "$$$blitz.cpp"));
|
||||
job.blitz = blitz;
|
||||
job.file_times = pick(blitz_files); // the path is fake, file does not exist
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
event.Broadcast();
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,17 +53,18 @@ String CleanupId(const char *s)
|
|||
return s[0] == 'o' && s[1] == 'p' && s[2] == 'e' && s[3] == 'r' &&
|
||||
s[4] == 'a' && s[5] == 't' && s[6] == 'o' && s[7] == 'r';
|
||||
};
|
||||
if(was_id)
|
||||
mm.Cat(' ');
|
||||
if(!operator_def) // because of conversion operators e.g. Foo::operator bool()
|
||||
name_pos = mm.GetCount();
|
||||
if(id.GetCount() == 8 && IsOperator(id))
|
||||
operator_def = true;
|
||||
if(id.GetCount() > 8) {
|
||||
if(id.GetCount() > 8) { // conversion operator?
|
||||
const char *s = ~id + id.GetCount() - 8;
|
||||
operator_def = IsOperator(s) && !iscid(s[-1]);
|
||||
}
|
||||
if(function && (IsBasicType(id) || !IsCppKeyword(id))) // TODO optimize this (IsCppKeywordNoType)
|
||||
was_param_type = true;
|
||||
if(was_id)
|
||||
mm.Cat(' ');
|
||||
name_pos = mm.GetCount();
|
||||
mm.Cat(id);
|
||||
was_id = true;
|
||||
was_name = true;
|
||||
|
|
@ -90,13 +91,13 @@ String CleanupId(const char *s)
|
|||
if(*s == '~' && !operator_def) // prevent culling of 'return value' in destructor
|
||||
destructor = true;
|
||||
if(*s == '(') {
|
||||
function = true;
|
||||
was_param_type = false;
|
||||
operator_def = false;
|
||||
if(name_pos && !destructor) {
|
||||
String h = String(mm).Mid(name_pos);
|
||||
mm = h;
|
||||
}
|
||||
function = true;
|
||||
was_param_type = false;
|
||||
operator_def = false;
|
||||
}
|
||||
if(*s == ',')
|
||||
was_param_type = false;
|
||||
|
|
@ -209,7 +210,7 @@ Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, in
|
|||
p.type = ITEM_NUMBER;
|
||||
}
|
||||
else
|
||||
if(iscid(*s)) {
|
||||
if(iscid(*s) || (*s == '~' && *name == '~')) {
|
||||
if(strncmp(s, name, name_len) == 0 && !iscid(s[name_len])) { // need strncmp because of e.g. operator++
|
||||
p.type = ITEM_NAME;
|
||||
n = name_len;
|
||||
|
|
@ -222,7 +223,8 @@ Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, in
|
|||
*fn_info = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
if(*s != '~') {
|
||||
String id;
|
||||
n = 0;
|
||||
while(iscid(s[n]))
|
||||
|
|
@ -248,6 +250,8 @@ Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, in
|
|||
if(param && fn_info)
|
||||
*fn_info = 1;
|
||||
}
|
||||
else // should not happen, but be safe
|
||||
s++;
|
||||
}
|
||||
else
|
||||
if(sOperatorTab[*s]) {
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ bool ClangVisitor::ProcessNode(CXCursor cursor)
|
|||
|
||||
if(WhenFile)
|
||||
LoadPosition();
|
||||
|
||||
if(!(WhenFile ? WhenFile(path) : clang_Location_isFromMainFile(cxlocation))) {
|
||||
return findarg(cursorKind, CXCursor_StructDecl, CXCursor_UnionDecl, CXCursor_ClassDecl,
|
||||
CXCursor_FunctionTemplate, CXCursor_FunctionDecl, CXCursor_Constructor,
|
||||
|
|
@ -134,15 +135,32 @@ bool ClangVisitor::ProcessNode(CXCursor cursor)
|
|||
r.kind = cursorKind;
|
||||
r.name = name;
|
||||
r.line = line;
|
||||
// DDUMP(m);
|
||||
r.id = CleanupId(m);
|
||||
r.pretty = CleanupPretty(FetchString(clang_getCursorPrettyPrinted(cursor, pp_pretty)));
|
||||
r.definition = clang_isCursorDefinition(cursor);
|
||||
r.nspace = nspace;
|
||||
int q = FindId(r.id, r.name);
|
||||
if(q >= 0) {
|
||||
r.nest = r.id.Mid(0, q);
|
||||
r.nest.TrimEnd("::");
|
||||
// DDUMP(FetchString(clang_getCursorPrettyPrinted(cursor, pp_pretty)));
|
||||
// DDUMP(r.pretty);
|
||||
// DDUMP(r.id);
|
||||
// DDUMP(r.name);
|
||||
// DDUMP(scope);
|
||||
if(findarg(r.kind, CXCursor_Constructor, CXCursor_Destructor) >= 0) {
|
||||
int q = r.id.Find('(');
|
||||
if(q >= 0) {
|
||||
q = r.id.ReverseFind("::", q);
|
||||
if(q >= 0)
|
||||
r.nest = r.id.Mid(0, q);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int q = FindId(r.id, r.name);
|
||||
if(q >= 0) {
|
||||
r.nest = r.id.Mid(0, q);
|
||||
r.nest.TrimEnd("::");
|
||||
}
|
||||
}
|
||||
// DDUMP(r.nest);
|
||||
r.uname = ToUpper(name);
|
||||
r.unest = ToUpper(r.nest);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "clang.h"
|
||||
|
||||
#define LLOG(x)
|
||||
#define LTIMESTOP(x) TIMESTOP(x)
|
||||
|
||||
String FetchString(CXString cs)
|
||||
{
|
||||
|
|
@ -78,6 +79,8 @@ bool Clang::Parse(const String& filename, const String& content, const String& i
|
|||
{
|
||||
if(!index) return false;
|
||||
|
||||
// LTIMESTOP("Parse " << filename << " " << includes_ << " " << defines);
|
||||
|
||||
Dispose();
|
||||
|
||||
String cmdline;
|
||||
|
|
|
|||
|
|
@ -6,6 +6,15 @@
|
|||
|
||||
using namespace Upp;
|
||||
|
||||
class CoEvent {
|
||||
Mutex lock;
|
||||
ConditionVariable cv;
|
||||
|
||||
public:
|
||||
void Wait(int timeout_ms) { lock.Enter(); cv.Wait(lock, timeout_ms); lock.Leave(); }
|
||||
void Broadcast() { cv.Broadcast(); }
|
||||
};
|
||||
|
||||
String FetchString(CXString cs);
|
||||
String GetCursorKindName(CXCursorKind cursorKind);
|
||||
String GetCursorSpelling(CXCursor cursor);
|
||||
|
|
@ -153,18 +162,45 @@ void StartAutoComplete(const CurrentFileContext& ctx, int line, int column, bool
|
|||
Event<const Vector<AutoCompleteItem>&> done);
|
||||
void CancelAutoComplete();
|
||||
|
||||
String FindMasterSource(Hdepend& hdepend, const Workspace& wspc, const String& header_file);
|
||||
|
||||
struct FileAnnotation {
|
||||
String defines;
|
||||
struct FileAnnotation0 {
|
||||
String defines = "<not_loaded>";
|
||||
String includes;
|
||||
Time time;
|
||||
|
||||
Vector<AnnotationItem> items;
|
||||
};
|
||||
|
||||
bool IsIndexing();
|
||||
void StartIndexing(const String& includes, const String& defines);
|
||||
struct FileAnnotation : FileAnnotation0 {
|
||||
Vector<AnnotationItem> items;
|
||||
|
||||
void Serialize(Stream& s);
|
||||
};
|
||||
|
||||
const ArrayMap<String, FileAnnotation>& CodeIndex();
|
||||
ArrayMap<String, FileAnnotation>& CodeIndex();
|
||||
|
||||
class Indexer {
|
||||
struct Job : Moveable<Job> {
|
||||
String path;
|
||||
String blitz;
|
||||
String includes;
|
||||
String defines;
|
||||
WithDeepCopy<VectorMap<String, Time>> file_times;
|
||||
};
|
||||
|
||||
static CoEvent event;
|
||||
static Workspace wspc;
|
||||
static Hdepend hdepend;
|
||||
static Mutex mutex;
|
||||
static Vector<Job> jobs;
|
||||
static int jobi;
|
||||
static std::atomic<int> running_indexers;
|
||||
static VectorMap<String, String> master_file; // header -> first file that includes it
|
||||
|
||||
static void IndexerThread();
|
||||
|
||||
public:
|
||||
static void Start(const String& main, const String& includes, const String& defines);
|
||||
static bool IsRunning() { return running_indexers; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -17,9 +17,8 @@ file
|
|||
CxxIcon.cpp,
|
||||
Signature.cpp,
|
||||
clang.cpp,
|
||||
Codebase.cpp,
|
||||
Visitor.cpp,
|
||||
AutoComplete.cpp,
|
||||
CurrentFile.cpp,
|
||||
Visitor.cpp,
|
||||
Indexer.cpp;
|
||||
|
||||
|
|
|
|||
|
|
@ -28,12 +28,8 @@
|
|||
|
||||
- aux files / autocomplete
|
||||
|
||||
- this is just a test
|
||||
|
||||
- OpenWind.h autocomplete
|
||||
|
||||
- server_methods.i
|
||||
|
||||
- fixups?
|
||||
|
||||
- enum annotation popup (Ctrl::)
|
||||
|
|
@ -46,25 +42,17 @@
|
|||
|
||||
- check editor mode
|
||||
|
||||
- navlines
|
||||
|
||||
- navigator - GotoDesignerFile
|
||||
|
||||
- * nest in navigator local file
|
||||
|
||||
- remove $blitz items
|
||||
|
||||
- constructor/destructor name is not bold (check destructor in navigator display)
|
||||
|
||||
- PaintCpp ending spaces in navigator
|
||||
|
||||
- Error output: (): x += GetTextSize(" Ôćĺ ", StdFont());
|
||||
|
||||
- x += GetTextSize(" Ôćĺ ", StdFont()) - autocomplete fails on UTF8
|
||||
|
||||
- immediate reparse (probably Update?)
|
||||
|
||||
- Navigator -> (constructor does not have return value)
|
||||
- navlines
|
||||
|
||||
- local file navigation off by 1 line
|
||||
|
||||
|
|
@ -72,7 +60,45 @@
|
|||
|
||||
- operator bool - wrong nest (Core/Speller.cpp)
|
||||
|
||||
- constructor - worng nest(Core/Speller.cpp)
|
||||
- Speller.cpp - Speller type has {}, Line too
|
||||
|
||||
- Core/String.h - empty macros at the start in navigator
|
||||
|
||||
- Core/String.h - operator const void *() - wrong highlighting (all bold)
|
||||
|
||||
- Core/String.h - conversion operators wrong nests
|
||||
|
||||
- for .txt file, navigator keeps showing previous local file
|
||||
|
||||
- StringBuffer does not work in debugger pdb
|
||||
|
||||
- Speller.cpp: structures have wrong nest (missing itself)
|
||||
|
||||
- check dialog mode
|
||||
|
||||
- void Navigator::SyncCursor()
|
||||
|
||||
- void NavDlg::GoTo()
|
||||
|
||||
- Hdepend NoConsole
|
||||
|
||||
- AltC static method(); (header->source) retains static
|
||||
|
||||
- Vector<Job> Indexer::jobs; should be: Vector<Indexer::Job> Indexer::jobs;
|
||||
|
||||
- indexer TabBar missing
|
||||
|
||||
- when scope is selected in navigator, search should be ingored
|
||||
|
||||
- unicode is very long because { 123 , 41234234
|
||||
|
||||
- use codeindex info for file annotations
|
||||
|
||||
- save file annotation to codeindex
|
||||
|
||||
- rescan everything function
|
||||
|
||||
- C:\u\llvm_ide\uppsrc\plugin\z\lib\compress.c (22:24) unknown type name 'dest' - do we need CBLITZ?
|
||||
|
||||
|
||||
LATER:
|
||||
|
|
@ -85,6 +111,18 @@ LATER:
|
|||
|
||||
DONE:
|
||||
|
||||
- destructor name is not bold (clang/visitor.cpp)
|
||||
|
||||
- constructor - worng nest(Core/Speller.cpp)
|
||||
|
||||
- AString type [31] - wrong icon
|
||||
|
||||
- * nest in navigator local file
|
||||
|
||||
- PaintCpp ending spaces in navigator
|
||||
|
||||
- Navigator -> (constructor does not have return value)
|
||||
|
||||
- Upp:: missing from Vector
|
||||
|
||||
- class Ctrl
|
||||
|
|
|
|||
|
|
@ -668,7 +668,7 @@ void Ide::SyncClang()
|
|||
a.Add(i > cx - DPI(6) ? bg : Null);
|
||||
}
|
||||
editor.AnimateBar(pick(a));
|
||||
editor.search.SetBackground(Animate(animate_indexer, animate_indexer_dir, IsIndexing()));
|
||||
editor.search.SetBackground(Animate(animate_indexer, animate_indexer_dir, Indexer::IsRunning()));
|
||||
display.Animate(Animate(animate_autocomplete, animate_autocomplete_dir, IsAutocompleteParsing()));
|
||||
animate_phase = phase;
|
||||
}
|
||||
|
|
@ -792,3 +792,8 @@ void Ide::DiffFiles(const char *lname, const String& l, const char *rname, const
|
|||
diff.Set(lname, LoadConflictFile(l), rname, LoadConflictFile(r));
|
||||
diff.Execute();
|
||||
}
|
||||
|
||||
void Ide::TriggerIndexer()
|
||||
{
|
||||
Indexer::Start(main, GetCurrentIncludePath(), GetCurrentDefines());
|
||||
}
|
||||
|
|
@ -1244,7 +1244,9 @@ public:
|
|||
void MacroTarget(EscEscape& e);
|
||||
|
||||
String GetAndroidSdkPath();
|
||||
|
||||
|
||||
void TriggerIndexer();
|
||||
|
||||
typedef Ide CLASSNAME;
|
||||
|
||||
enum {
|
||||
|
|
|
|||
|
|
@ -813,7 +813,6 @@ LAYOUT(JumpLayout, 692, 496)
|
|||
ITEM(Upp::Button, ok, SetLabel(t_("OK")).RightPosZ(76, 64).TopPosZ(4, 24))
|
||||
ITEM(Upp::Button, cancel, SetLabel(t_("Cancel")).RightPosZ(8, 64).TopPosZ(4, 24))
|
||||
UNTYPED(scope, LeftPosZ(4, 176).VSizePosZ(32, 104))
|
||||
UNTYPED(navlines, LeftPosZ(4, 176).BottomPosZ(4, 96))
|
||||
UNTYPED(list, HSizePosZ(184, 8).VSizePosZ(32, 4))
|
||||
END_LAYOUT
|
||||
|
||||
|
|
|
|||
|
|
@ -398,6 +398,7 @@ void Ide::SaveFile0(bool always)
|
|||
SyncUsc();
|
||||
|
||||
MakeTitle();
|
||||
TriggerIndexer();
|
||||
}
|
||||
|
||||
void Ide::FlushFile() {
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ void AppMain___()
|
|||
ide.MakeTitle();
|
||||
if(!ide.IsEditorMode()) {
|
||||
SyncRefs();
|
||||
StartIndexing(ide.GetCurrentIncludePath(), ide.GetCurrentDefines());
|
||||
ide.TriggerIndexer();
|
||||
}
|
||||
ide.FileSelected();
|
||||
ide.isscanning--;
|
||||
|
|
@ -366,6 +366,7 @@ void AppMain___()
|
|||
}
|
||||
#endif
|
||||
#endif
|
||||
Ctrl::ShutdownThreads();
|
||||
}
|
||||
|
||||
#ifdef flagPEAKMEM
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue