diff --git a/uppsrc/Core/CoWork.cpp b/uppsrc/Core/CoWork.cpp index 08f7c5411..11455d4b1 100644 --- a/uppsrc/Core/CoWork.cpp +++ b/uppsrc/Core/CoWork.cpp @@ -311,36 +311,6 @@ void CoWork::SetPoolSize(int n) p.InitThreads(n); } -void CoWork::Pipe(int stepi, Function&& 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 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 { diff --git a/uppsrc/Core/CoWork.h b/uppsrc/Core/CoWork.h index 1cd45b34d..cf37e48d9 100644 --- a/uppsrc/Core/CoWork.h +++ b/uppsrc/Core/CoWork.h @@ -57,11 +57,6 @@ public: Atomic index; -// experimental pipe support - Mutex stepmutex; - Array>> step; - Vector steprunning; - public: static bool TrySchedule(Function&& fn); static bool TrySchedule(const Function& 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&& lambda); // experimental static void FinLock(); diff --git a/uppsrc/Core/Mt.h b/uppsrc/Core/Mt.h index 34ed72490..f24ec4055 100644 --- a/uppsrc/Core/Mt.h +++ b/uppsrc/Core/Mt.h @@ -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 diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index 149f6453b..e517eea33 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -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()) { diff --git a/uppsrc/ide/Assist.h b/uppsrc/ide/Assist.h index 7fe7bc8b7..96a10534d 100644 --- a/uppsrc/ide/Assist.h +++ b/uppsrc/ide/Assist.h @@ -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 linefo; - */ + String path; }; struct ScopeDisplay : Display { @@ -71,7 +45,6 @@ struct Navigator { Array nitem; Vector litem; Array nest_item; // list separators with nest (scope) or file - VectorMap > 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 GetNavLines(const NavItem& m); - void Navigate(); void ScopeDblClk(); void NavigatorClick(); void NavigatorEnter(); - void SyncLines(); - void SyncNavLines(); - void GoToNavLine(); void SyncCursor(); typedef Navigator CLASSNAME; diff --git a/uppsrc/ide/AssistDisplay.cpp b/uppsrc/ide/AssistDisplay.cpp index 56dd05319..b74e64904 100644 --- a/uppsrc/ide/AssistDisplay.cpp +++ b/uppsrc/ide/AssistDisplay.cpp @@ -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); diff --git a/uppsrc/ide/Core/Cache.cpp b/uppsrc/ide/Core/Cache.cpp index 325b79e83..27113c63d 100644 --- a/uppsrc/ide/Core/Cache.cpp +++ b/uppsrc/ide/Core/Cache.cpp @@ -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 } \ No newline at end of file diff --git a/uppsrc/ide/IncludeTrick.cpp b/uppsrc/ide/IncludeTrick.cpp index 627196cdd..05915859c 100644 --- a/uppsrc/ide/IncludeTrick.cpp +++ b/uppsrc/ide/IncludeTrick.cpp @@ -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& visited, int level, StringBuffer& out, String path, const String& target_path, int& line_delta) @@ -57,16 +22,12 @@ bool AssistEditor::DoIncludeTrick(Index& 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(); diff --git a/uppsrc/ide/Jump.cpp b/uppsrc/ide/Jump.cpp index 81415b596..077f6dfa7 100644 --- a/uppsrc/ide/Jump.cpp +++ b/uppsrc/ide/Jump.cpp @@ -8,8 +8,8 @@ struct NavDlg : WithJumpLayout, 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(); theide->GotoPos(GetSourceFilePath(l.file), l.line); - } + }*/ } int NavDlg::GetCurrentLine() diff --git a/uppsrc/ide/Methods.cpp b/uppsrc/ide/Methods.cpp index 49b52ce33..54f544e67 100644 --- a/uppsrc/ide/Methods.cpp +++ b/uppsrc/ide/Methods.cpp @@ -887,7 +887,7 @@ String Ide::GetCurrentIncludePath() Host host; CreateHost(host, false, false); One b = CreateBuilder(&host); - Index cfg = PackageConfig(wspc, GetPackageIndex(), GetMethodVars(method), mainconfigparam, host, *b); + Index cfg = PackageConfig(wspc, max(GetPackageIndex(), 0), GetMethodVars(method), mainconfigparam, host, *b); Index pkg_config; for(int i = 0; i < wspc.GetCount(); i++) { const Package& pkg = wspc.GetPackage(i); diff --git a/uppsrc/ide/Navigator2.cpp b/uppsrc/ide/Navigator2.cpp index caceaecb5..f41f9092c 100644 --- a/uppsrc/ide/Navigator2.cpp +++ b/uppsrc/ide/Navigator2.cpp @@ -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()); - 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(); - 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 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(); - 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::GetNavLines(const NavItem& m) -{ - _DBG_ - Vector l; -/* - CodeBaseLock __; - int q = CodeBase().Find(m.nest); - if(q < 0 || IsNull(m.qitem)) - return l; - const Array& 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 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 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); diff --git a/uppsrc/ide/UppHub.cpp b/uppsrc/ide/UppHub.cpp index 5708bf91e..64b57ad55 100644 --- a/uppsrc/ide/UppHub.cpp +++ b/uppsrc/ide/UppHub.cpp @@ -1,4 +1,5 @@ #include "ide.h" + struct UppHubNest : Moveable { int tier = -1; String name; diff --git a/uppsrc/ide/clang/AutoComplete.cpp b/uppsrc/ide/clang/AutoComplete.cpp index 7b1fcd6b9..9f3f4d1f9 100644 --- a/uppsrc/ide/clang/AutoComplete.cpp +++ b/uppsrc/ide/clang/AutoComplete.cpp @@ -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() diff --git a/uppsrc/ide/clang/Codebase.cpp b/uppsrc/ide/clang/Codebase.cpp deleted file mode 100644 index 5a53bbe70..000000000 --- a/uppsrc/ide/clang/Codebase.cpp +++ /dev/null @@ -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 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(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); -} diff --git a/uppsrc/ide/clang/CurrentFile.cpp b/uppsrc/ide/clang/CurrentFile.cpp index 36345b216..700c744b1 100644 --- a/uppsrc/ide/clang/CurrentFile.cpp +++ b/uppsrc/ide/clang/CurrentFile.cpp @@ -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= 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 individual; +void FileAnnotation::Serialize(Stream& s) +{ + s % defines + % includes + % time + % items; +} - void Do(const String& pk_name, const Vector>& 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>& file, Hdepend& hdepend) +ArrayMap& 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& WriteCodeIndex() -{ - DTIMING("WriteCodeIndex"); static ArrayMap m; return m; } -const ArrayMap& CodeIndex() +void DumpIndex() { - return WriteCodeIndex(); + GuiLock __; + FileOut out(ConfigFile("current_index.dump")); + ArrayMap& 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 indexer_pkgi; -static std::atomic running_indexers; -static Index visited_files; -static Mutex visited_files_mutex; +CoEvent Indexer::event; +Hdepend Indexer::hdepend; +Mutex Indexer::mutex; +Vector Indexer::jobs; +int Indexer::jobi; +std::atomic Indexer::running_indexers; +Workspace Indexer::wspc; +VectorMap 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> pk_files; - Index 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 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 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 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(); + }); } diff --git a/uppsrc/ide/clang/Signature.cpp b/uppsrc/ide/clang/Signature.cpp index 85605bd5f..dac83d178 100644 --- a/uppsrc/ide/clang/Signature.cpp +++ b/uppsrc/ide/clang/Signature.cpp @@ -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 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 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 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]) { diff --git a/uppsrc/ide/clang/Visitor.cpp b/uppsrc/ide/clang/Visitor.cpp index ce07c41f3..b218b3628 100644 --- a/uppsrc/ide/clang/Visitor.cpp +++ b/uppsrc/ide/clang/Visitor.cpp @@ -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); } diff --git a/uppsrc/ide/clang/clang.cpp b/uppsrc/ide/clang/clang.cpp index 420787627..1d56f353a 100644 --- a/uppsrc/ide/clang/clang.cpp +++ b/uppsrc/ide/clang/clang.cpp @@ -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; diff --git a/uppsrc/ide/clang/clang.h b/uppsrc/ide/clang/clang.h index 738190160..b70fd4656 100644 --- a/uppsrc/ide/clang/clang.h +++ b/uppsrc/ide/clang/clang.h @@ -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&> done); void CancelAutoComplete(); +String FindMasterSource(Hdepend& hdepend, const Workspace& wspc, const String& header_file); -struct FileAnnotation { - String defines; +struct FileAnnotation0 { + String defines = ""; String includes; Time time; - - Vector items; }; -bool IsIndexing(); -void StartIndexing(const String& includes, const String& defines); +struct FileAnnotation : FileAnnotation0 { + Vector items; + + void Serialize(Stream& s); +}; -const ArrayMap& CodeIndex(); +ArrayMap& CodeIndex(); + +class Indexer { + struct Job : Moveable { + String path; + String blitz; + String includes; + String defines; + WithDeepCopy> file_times; + }; + + static CoEvent event; + static Workspace wspc; + static Hdepend hdepend; + static Mutex mutex; + static Vector jobs; + static int jobi; + static std::atomic running_indexers; + static VectorMap 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 diff --git a/uppsrc/ide/clang/clang.upp b/uppsrc/ide/clang/clang.upp index c334e278f..ac46743ae 100644 --- a/uppsrc/ide/clang/clang.upp +++ b/uppsrc/ide/clang/clang.upp @@ -17,9 +17,8 @@ file CxxIcon.cpp, Signature.cpp, clang.cpp, - Codebase.cpp, - Visitor.cpp, AutoComplete.cpp, CurrentFile.cpp, + Visitor.cpp, Indexer.cpp; diff --git a/uppsrc/ide/clang/todo.txt b/uppsrc/ide/clang/todo.txt index a12d0b5b7..401ea53cf 100644 --- a/uppsrc/ide/clang/todo.txt +++ b/uppsrc/ide/clang/todo.txt @@ -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 Indexer::jobs; should be: Vector 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 diff --git a/uppsrc/ide/ide.cpp b/uppsrc/ide/ide.cpp index c57a7eda5..7ea05cc4f 100644 --- a/uppsrc/ide/ide.cpp +++ b/uppsrc/ide/ide.cpp @@ -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()); +} \ No newline at end of file diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index e49f36716..853931c0f 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -1244,7 +1244,9 @@ public: void MacroTarget(EscEscape& e); String GetAndroidSdkPath(); - + + void TriggerIndexer(); + typedef Ide CLASSNAME; enum { diff --git a/uppsrc/ide/ide.lay b/uppsrc/ide/ide.lay index 6d7946bc8..d27230e9b 100644 --- a/uppsrc/ide/ide.lay +++ b/uppsrc/ide/ide.lay @@ -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 diff --git a/uppsrc/ide/idefile.cpp b/uppsrc/ide/idefile.cpp index 50fa2d113..919241395 100644 --- a/uppsrc/ide/idefile.cpp +++ b/uppsrc/ide/idefile.cpp @@ -398,6 +398,7 @@ void Ide::SaveFile0(bool always) SyncUsc(); MakeTitle(); + TriggerIndexer(); } void Ide::FlushFile() { diff --git a/uppsrc/ide/main.cpp b/uppsrc/ide/main.cpp index de79d4ab7..f0fe014ee 100644 --- a/uppsrc/ide/main.cpp +++ b/uppsrc/ide/main.cpp @@ -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