ultimatepp/uppsrc/ide/Swaps.cpp
2022-07-27 16:05:00 +02:00

126 lines
3.1 KiB
C++

#include "ide.h"
#define LLOG(x) // DLOG(x)
void AssistEditor::SwapSContext(ParserContext& p)
{
int i = GetCursor32();
if(Ch(i - 1) == ';')
i--;
else
for(;;) {
int c = Ch(i);
if(c == '{') {
i++;
break;
}
if(c == 0 || c == ';' || c == '}')
break;
i++;
}
Context(p, i);
}
bool Ide::SwapSIf(const char *cref)
{
if(designer || !editor.assist_active)
return false;
ParserContext p;
editor.SwapSContext(p);
CodeBaseLock __;
int q = CodeBase().Find(p.current_scope);
LLOG("SwapS scope: " << p.current_scope << ", name " << p.current_name << ", key " << p.current_key);
if(q < 0)
return false;
const Array<CppItem>& nn = CodeBase()[q];
if(cref && MakeCodeRef(p.current_scope, p.current_key) != cref || IsNull(p.current_name))
return false;
Vector<const CppItem *> n;
bool destructor = p.current_key.Find('~') >= 0;
for(int i = 0; i < nn.GetCount(); i++) {
const CppItem& m = nn[i];
if(m.name == p.current_name && destructor == (m.kind == DESTRUCTOR) && !m.IsType())
n.Add(&m);
}
if(!cref && n.GetCount() < 2)
for(int i = 0; i < nn.GetCount(); i++)
if(nn[i].IsType()) {
UnlockCodeBaseAll();
GotoCpp(nn[i]);
return false;
}
if(n.GetCount() == 0 || IsNull(editfile))
return false;
int file = GetSourceFileIndex(editfile);
int line = p.current.line;
LLOG("SwapS line: " << line);
int i;
for(i = 0; i < n.GetCount(); i++) {
LLOG("file: " << GetSourceFilePath(n[i]->file) << ", line: " << n[i]->line);
if(n[i]->file == file && n[i]->line == line) {
i++;
break;
}
}
CppItem m = *n[i % n.GetCount()];
UnlockCodeBaseAll();
GotoCpp(m);
return true;
}
void Ide::SwapS()
{
if(designer || !editor.assist_active)
return;
if(!editor.WaitCurrentFile())
return;
AnnotationItem cm = editor.FindCurrentAnnotation();
struct Sf : Moveable<Sf> {
String path;
int line;
bool definition;
};
Vector<Sf> set, list;
for(int pass = 0; pass < 3 && set.GetCount() < 2; pass++) {
set.Clear();
for(const auto& f : ~CodeIndex())
for(const AnnotationItem& m : f.value.items) {
if(pass == 0 ? m.id == cm.id :
pass == 1 ? m.nest == cm.nest && m.name == cm.name :
m.nest == cm.nest && IsStruct(m.kind)) {
Sf& sf = set.Add();
sf.path = f.key;
sf.line = m.line;
sf.definition = m.definition;
}
if(set.GetCount() > 20) // sanity
break;
}
if(set.GetCount() > 1)
break;
}
if(set.GetCount() == 0)
return;
Sort(set, [](const Sf& a, const Sf& b) {
return CombineCompare(a.path, b.path)(a.line, b.line) < 0;
});
bool deff = false;
for(;;) { // create a list of candidates alternating definition and declaration
int q = FindMatch(set, [&](const Sf& a) { return a.definition == deff; });
if(q >= 0) {
list.Add(set[q]);
set.Remove(q);
}
else
break;
deff = !deff;
}
list.Append(set); // add remaining items
int q = max(FindMatch(list, [&](const Sf& a) { return a.path == editfile && a.line == editor.GetCurrentLine(); }), 0);
q = (q + 1) % list.GetCount();
GotoPos(list[q].path, list[q].line);
}