From 0e8cde1f5df8ae3366c144394b721ef968fcb1d0 Mon Sep 17 00:00:00 2001 From: Mirek Fidler Date: Sun, 19 Oct 2025 09:38:39 +0200 Subject: [PATCH] Ide alt+c improvements --- uppsrc/ide/DCopy.cpp | 62 +++++++++++++++++++++------------------ uppsrc/ide/clang/clang.h | 1 + uppsrc/ide/clang/util.cpp | 5 ++++ upptst/ide_alt_c/ide.cpp | 9 ++++++ 4 files changed, 48 insertions(+), 29 deletions(-) diff --git a/uppsrc/ide/DCopy.cpp b/uppsrc/ide/DCopy.cpp index efc36c762..3a3e323c5 100644 --- a/uppsrc/ide/DCopy.cpp +++ b/uppsrc/ide/DCopy.cpp @@ -64,35 +64,36 @@ void AssistEditor::DCopy() bool in_id = false; const char *id_pos = nullptr; - const char *s = text; int lvl = 0; - while(*s) { - if(*s == '(') { - if(lvl == 0) { - fn_params_pos = s; - fn_name_pos = id_pos; + CParser p(text); + try { + while(!p.IsEof()) { + const char *ptr = p.GetPtr(); + if(p.Char('(')) { + if(lvl == 0) { + fn_params_pos = ptr; + fn_name_pos = id_pos; + } + lvl++; } - lvl++; - } - else - if(*s == ')') { - lvl--; - } - else - if(IsSpace(*s) || iscid(*s) || *s == ':') { - if(!in_id) { - id_pos = s; - in_id = true; + else + if(p.Char(')')) + lvl--; + else + if(p.IsId()) { + id_pos = p.GetPtr(); + do + p.ReadId(); + while(p.Char2(':', ':') && p.IsId()); + } + else { + id_pos = nullptr; + p.Skip(); } } - else { - in_id = false; - id_pos = nullptr; - } - - s++; } - + catch(CParser::Error) {} + String ret, name, params; if(fn_params_pos) { params = fn_params_pos; @@ -102,7 +103,7 @@ void AssistEditor::DCopy() } } - auto Clean = [](String& s) { // this can be slow + auto Clean = [](String& s) { // this is ok to be slow (hence Join/Split) s = Join(Split(TrimBoth(Filter(s, [](int c) { return c < 32 ? 32 : c; })), ' '), " "); }; @@ -117,16 +118,19 @@ void AssistEditor::DCopy() result << ret << ' ' << m.name << params << ";\n"; } else { + ret.TrimStart("static "); String cret; if(IsMethod(m.kind)) { // attempt to qualify local classes in return value type bool qualified = false; const char *begin = ret; String st = m.nest + "::"; VectorMap qname; - for(const AnnotationItem& m : annotations) - if(IsStruct(m.kind) && m.nest.StartsWith(st)) - qname.Add(m.name, m.nest); - + for(const AnnotationItem& am : annotations) { + if(IsStruct(am.kind) && am.nest.StartsWith(st)) + qname.Add(am.name, am.nest); + if(IsTypedef(am.kind) && am.nest == m.nest) + qname.Add(am.name, am.nest + "::" + am.name); + } try { CParser p(ret); while(!p.IsEof()) { diff --git a/uppsrc/ide/clang/clang.h b/uppsrc/ide/clang/clang.h index 9e049a247..b5127caa0 100644 --- a/uppsrc/ide/clang/clang.h +++ b/uppsrc/ide/clang/clang.h @@ -98,6 +98,7 @@ String SignatureQtf(const String& name, const String& pretty, int pari = INT_MAX String CppText(const String& name, const String& pretty); bool IsStruct(int kind); +bool IsTypedef(int kind); bool IsTemplate(int kind); bool IsFunction(int kind); bool IsMethod(int kind); diff --git a/uppsrc/ide/clang/util.cpp b/uppsrc/ide/clang/util.cpp index 1c32d807a..45271011d 100644 --- a/uppsrc/ide/clang/util.cpp +++ b/uppsrc/ide/clang/util.cpp @@ -68,6 +68,11 @@ bool IsHeaderFile(const String& path) return findarg(ext, ".h", ".hxx", ".hpp", ".hh") >= 0; } +bool IsTypedef(int kind) +{ + return kind == CXCursor_TypedefDecl; +} + bool IsStruct(int kind) { return findarg(kind, CXCursor_StructDecl, CXCursor_UnionDecl, CXCursor_ClassDecl, diff --git a/upptst/ide_alt_c/ide.cpp b/upptst/ide_alt_c/ide.cpp index 7a9a6682f..47d06d8d8 100644 --- a/upptst/ide_alt_c/ide.cpp +++ b/upptst/ide_alt_c/ide.cpp @@ -14,11 +14,20 @@ struct Foo { int Test(); }; struct Item { int foo; }; + + void Simple(); std::vector Bar2(const std::vector& price, String s); std::vector Bar(const std::vector& price, String s); std::vector Bar(const std::vector>& price, String s); std::vector Bar(const std::vector>& price, int x); + + typedef void (*PaintHook)(String s); + + static Vector& painthook(); + + static void InstallPaintHook(PaintHook hook, String s); + static void DeinstallPaintHook(PaintHook hook, String s); }; namespace Test {