#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& nn = CodeBase()[q]; if(cref && MakeCodeRef(p.current_scope, p.current_key) != cref || IsNull(p.current_name)) return false; Vector 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 { String path; int line; bool definition; }; Vector 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); }