mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-26 22:03:35 -06:00
151 lines
4.5 KiB
C++
151 lines
4.5 KiB
C++
#include "clang.h"
|
|
|
|
#define LLOG(x) // LOG(x)
|
|
|
|
bool current_file_parsing;
|
|
CoEvent current_file_event;
|
|
CurrentFileContext current_file;
|
|
int64 current_file_serial;
|
|
int64 current_file_done_serial;
|
|
|
|
Event<const CppFileInfo&> annotations_done;
|
|
|
|
void CurrentFileThread()
|
|
{
|
|
MemoryIgnoreLeaksBlock __;
|
|
|
|
CurrentFileContext parsed_file;
|
|
int64 serial;
|
|
|
|
Clang clang;
|
|
|
|
auto DoAnnotations = [&] {
|
|
if(!clang.tu || !annotations_done) return;
|
|
ClangVisitor v;
|
|
v.dolocals = true;
|
|
v.WhenFile = [&] (const String& path) { return path == current_file.filename; };
|
|
v.Do(clang.tu);
|
|
CppFileInfo f;
|
|
if(v.info.GetCount()) {
|
|
f = pick(v.info[0]);
|
|
f.items.RemoveIf([&](int i) { return f.items[i].pos.y < parsed_file.line_delta; });
|
|
for(AnnotationItem& m : f.items)
|
|
m.pos.y -= parsed_file.line_delta;
|
|
f.locals.RemoveIf([&](int i) { return f.locals[i].pos.y < parsed_file.line_delta; });
|
|
for(AnnotationItem& m : f.locals)
|
|
m.pos.y -= parsed_file.line_delta;
|
|
f.refs.RemoveIf([&](int i) { return f.refs[i].pos.y < parsed_file.line_delta; });
|
|
for(ReferenceItem& m : f.refs)
|
|
m.pos.y -= parsed_file.line_delta;
|
|
}
|
|
Ctrl::Call([&] {
|
|
if(parsed_file.filename == current_file.filename &&
|
|
parsed_file.real_filename == current_file.real_filename &&
|
|
parsed_file.includes == current_file.includes &&
|
|
serial == current_file_serial) {
|
|
annotations_done(f);
|
|
FileAnnotation fa;
|
|
fa.defines = parsed_file.defines;
|
|
fa.includes = parsed_file.includes;
|
|
fa.items = pick(f.items);
|
|
fa.time = Time::Low();
|
|
CodeIndex().GetAdd(NormalizePath(parsed_file.real_filename)) = pick(fa);
|
|
}
|
|
current_file_done_serial = serial;
|
|
});
|
|
};
|
|
|
|
while(!Thread::IsShutdownThreads()) {
|
|
bool was_parsing;
|
|
do {
|
|
was_parsing = false;
|
|
CurrentFileContext f;
|
|
int64 done_serial;
|
|
{
|
|
GuiLock __;
|
|
f = current_file;
|
|
serial = current_file_serial;
|
|
done_serial = current_file_done_serial;
|
|
}
|
|
if(f.filename.GetCount()) {
|
|
String fn = f.filename;
|
|
if(!IsSourceFile(fn))
|
|
fn.Cat(".cpp");
|
|
if(f.filename != parsed_file.filename || f.real_filename != parsed_file.real_filename ||
|
|
f.includes != parsed_file.includes || f.defines != parsed_file.defines ||
|
|
!clang.tu) { // TODO: same is in autocomplete
|
|
parsed_file = f;
|
|
int tm = msecs();
|
|
current_file_parsing = true;
|
|
clang.Parse(fn, f.content, f.includes, f.defines,
|
|
CXTranslationUnit_DetailedPreprocessingRecord|
|
|
// CXTranslationUnit_PrecompiledPreamble|
|
|
// CXTranslationUnit_CreatePreambleOnFirstParse|
|
|
CXTranslationUnit_SkipFunctionBodies|
|
|
CXTranslationUnit_LimitSkipFunctionBodiesToPreamble|
|
|
CXTranslationUnit_KeepGoing);
|
|
// DumpDiagnostics(clang.tu); _DBG_
|
|
PutVerbose(String() << "Current file parsed in " << msecs() - tm << " ms");
|
|
tm = msecs();
|
|
DoAnnotations();
|
|
PutVerbose(String() << "Current file parser output processed in " << msecs() - tm << " ms");
|
|
current_file_parsing = false;
|
|
was_parsing = true;
|
|
}
|
|
if(Thread::IsShutdownThreads()) break;
|
|
if(clang.tu && serial != done_serial) {
|
|
TIMESTOP("ReParse");
|
|
current_file_parsing = true;
|
|
int tm = msecs();
|
|
bool b = clang.ReParse(fn, f.content);
|
|
PutVerbose(String() << "Current file reparsed in " << msecs() - tm << " ms");
|
|
tm = msecs();
|
|
if(b)
|
|
DoAnnotations();
|
|
PutVerbose(String() << "Current file reparsed output processed in " << msecs() - tm << " ms");
|
|
current_file_parsing = false;
|
|
was_parsing = true;
|
|
}
|
|
}
|
|
}
|
|
while(was_parsing);
|
|
current_file_event.Wait();
|
|
LLOG("Current file Thread::IsShutdownThreads() " << Thread::IsShutdownThreads());
|
|
}
|
|
LLOG("Current file thread exit");
|
|
}
|
|
|
|
void SetCurrentFile(const CurrentFileContext& ctx, Event<const CppFileInfo&> done)
|
|
{
|
|
ONCELOCK {
|
|
MemoryIgnoreNonMainLeaks();
|
|
MemoryIgnoreNonUppThreadsLeaks(); // clangs leaks static memory in threads
|
|
Thread::Start([] { CurrentFileThread(); });
|
|
Thread::AtShutdown([] {
|
|
LLOG("Shutdown current file");
|
|
current_file_event.Broadcast();
|
|
});
|
|
}
|
|
GuiLock __;
|
|
current_file = ctx;
|
|
annotations_done = done;
|
|
current_file_event.Broadcast();
|
|
current_file_serial++;
|
|
}
|
|
|
|
bool IsCurrentFileDirty()
|
|
{
|
|
GuiLock __;
|
|
return current_file_serial != current_file_done_serial;
|
|
}
|
|
|
|
bool IsCurrentFileParsing()
|
|
{
|
|
return current_file_parsing;
|
|
}
|
|
|
|
void CancelCurrentFile()
|
|
{
|
|
GuiLock __;
|
|
annotations_done.Clear();
|
|
}
|