ide: Fixed problems in CleanupId

This commit is contained in:
Mirek Fidler 2025-06-18 15:42:48 +02:00
parent 9c0dd92628
commit 5a45cede81
11 changed files with 251 additions and 135 deletions

View file

@ -0,0 +1,50 @@
* C:\upp\out\autotest\CLANGx64.Debug.Debug_Full\ide_CleanupId.exe 18.06.2025 15:41:39, user: mirek
======
Foo1::operator<<(int)
id: Foo1::operator<<(int)
pretty: Foo1::operator<<(int)
======
Foo1::operator<(int)
id: Foo1::operator<(int)
pretty: Foo1::operator<(int)
======
Upp::Index<Upp::String>::Find(const Upp::String &k) const
id: Upp::Index::Find(const String&)const
pretty: Upp::Index<Upp::String>::Find(const Upp::String& k) const
======
clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, enum CXPrintingPolicyProperty Property, unsigned int Value) __attribute__((dllimport))
id: clang_PrintingPolicy_setProperty(CXPrintingPolicy,CXPrintingPolicyProperty,unsigned int)
pretty: clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, enum CXPrintingPolicyProperty Property, unsigned int Value)
======
Foo1::Method()
id: Foo1::Method()
pretty: Foo1::Method()
======
Foo3<int>::Foo3() noexcept
id: Foo3::Foo3()
pretty: Foo3<int>::Foo3()
======
Foo1::operator*(int)
id: Foo1::operator*(int)
pretty: Foo1::operator*(int)
======
main(int argc, const char *argv[])
id: main(int,const char*[])
pretty: main(int argc, const char *argv[])
======
Ns::EditText(int &s, const char *title, const char *label, int (*f)(int), int maxlen, bool notnull)
id: Ns::EditText(int&,const char*,const char*,int(*)(int),int,bool)
pretty: Ns::EditText(int& s, const char *title, const char *label, int (*f)(int), int maxlen, bool notnull)
======
template <class C> auto SubRange(C&& c, int pos, int count) -> decltype(SubRange(c.begin() + pos, count))
id: SubRange(C&&,int,int)
pretty: template <class C> auto SubRange(C&& c, int pos, int count)
======
inline void Foo()
id: Foo()
pretty: void Foo()
======
int (*test)(int (*test)())
id: int(*test)(int(*)())
pretty: int (*test)(int (*test)())

View file

@ -0,0 +1,36 @@
#include <ide/Core/Core.h>
using namespace Upp;
CONSOLE_APP_MAIN
{
StdLogSetup(LOG_COUT|LOG_FILE);
#if 0
String s = CleanupId("int (*test)(int (*test)())");
DDUMP(s);
return;
#endif
for(String s : {
"Foo1::operator<<(int)",
"Foo1::operator<(int)",
"Upp::Index<Upp::String>::Find(const Upp::String &k) const",
"clang_PrintingPolicy_setProperty(CXPrintingPolicy Policy, enum CXPrintingPolicyProperty Property, unsigned int Value) __attribute__((dllimport))",
"Foo1::Method()",
"Foo3<int>::Foo3() noexcept",
"Foo1::operator*(int)",
"main(int argc, const char *argv[])",
"Ns::EditText(int &s, const char *title, const char *label, int (*f)(int), int maxlen, bool notnull)",
"template <class C> auto SubRange(C&& c, int pos, int count) -> decltype(SubRange(c.begin() + pos, count))",
"inline void Foo()",
"int (*test)(int (*test)())"
}) {
DLOG("======");
DLOG(s);
DLOG("id: " << CleanupId(s));
DLOG("pretty: " << CleanupPretty(s));
}
CheckLogEtalon();
}

View file

@ -0,0 +1,11 @@
uses
Core,
ide/Core;
file
Etalon.log,
ide_CleanupId.cpp;
mainconfig
"" = "";

View file

@ -667,4 +667,33 @@ int GetRepoKind(const String& p);
int GetRepo(String& path);
String GetGitPath();
enum {
ITEM_TEXT,
ITEM_NAME,
ITEM_OPERATOR,
ITEM_CPP_TYPE,
ITEM_CPP,
ITEM_PNAME,
ITEM_TNAME,
ITEM_NUMBER,
ITEM_SIGN,
ITEM_UPP,
ITEM_TYPE,
ITEM_PTYPE = ITEM_TYPE + 10000,
};
struct ItemTextPart : Moveable<ItemTextPart> {
int pos;
int len;
int type;
int ii;
int pari;
};
String CleanupId(const char *s);
String CleanupPretty(const String& signature);
Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, int *fn_info = NULL);
#endif

View file

@ -20,6 +20,7 @@ file
Workspace.cpp,
usc.cpp,
BinObj.cpp,
Signature.cpp,
Host readonly separator,
Host.h,
Host.cpp,

View file

@ -1,4 +1,4 @@
#include "clang.h"
#include "Core.h"
#define LTIMING(x)
@ -47,12 +47,12 @@ bool IsBasicType(const String& id)
bool IsIgnored(const String& id)
{
static Index<String> kt = { "class", "struct", "union", "noexcept", "override", "final", "template", "enum" };
static Index<String> kt = { "class", "struct", "union", "noexcept", "override", "final", "template", "enum", "__attribute__" };
return kt.Find(id) >= 0;
}
String CleanupId(const char *s)
{ // removes unnecessary spaces, removes parameter names
{ // removes unnecessary spaces, removes parameter names, makes clang ids consistent
StringBuffer mm;
bool was_param_type = false;
bool was_id = false;
@ -82,7 +82,8 @@ String CleanupId(const char *s)
};
String id;
while(iscid(*s) || *s == ':') {
for(;;) {
if(iscid(*s)) {
id.Cat(*s++);
if(*s == '<') {
if(id.GetCount() == 8 && IsOperator(id))
@ -95,6 +96,19 @@ String CleanupId(const char *s)
SkipT(); // Skip template arguments like in Foo<Bar>::Method() -> Foo::Method
}
}
else
if(*s == ':' && s[1] == ':') {
if(inparams)
id.Clear(); // remove qualification from parameters (it is inconsistent with libclang)
else {
id.Cat(':');
id.Cat(':');
}
s += 2;
}
else
break;
}
if(id == s_attribute) {
while(*s == ' ')
s++;
@ -160,8 +174,9 @@ String CleanupId(const char *s)
was_param_type = false;
operator_def = false;
}
if(s[1] == '*') { // function pointer, e.g. int(*)(int)
if(s[1] == '*' && inparams) { // function pointer, e.g. int(*)(int)
was_param_type = false; // prevent skipping ^^^
mm.Cat('(');
while(*s && *s != ')') {
if(*s == '*') // exclude any names
mm.Cat(*s);
@ -467,93 +482,3 @@ String SignatureQtf(const String& name, const String& pretty, int pari)
}
return qtf + "]";
}
String GetClass(const AnnotationItem& m)
{
String cls = m.id;
int q;
if(m.kind == CXCursor_Constructor) {
q = cls.Find("::" + m.name + "(");
if(q >= 0)
q += 2;
}
else
if(m.kind == CXCursor_Destructor) {
q = cls.Find('~');
}
else
q = FindId(cls, m.name);
if(q >= 0) {
cls.Trim(q);
if(m.nspace.GetCount())
cls.TrimStart(m.nspace + "::");
return cls;
}
return Null;
}
String GetNameFromId(const String& id)
{
String name;
try {
CParser p(id);
while(!p.IsEof())
if(p.IsId())
name = p.ReadId();
else
if(!p.Char(':'))
break;
}
catch(CParser::Error) {}
return name;
}
String MakeDefinition(const AnnotationItem& m, const String& klass)
{
String result;
String pretty = m.pretty;
pretty.TrimStart("static ");
int q = FindId(pretty, m.name);
if(q < 0)
result << pretty;
else
result << pretty.Mid(0, q) << klass << pretty.Mid(q);
const char *s = result;
int lvl = 0;
String r;
while(*s) {
if(*s == '(')
lvl++;
if(*s == ')')
lvl--;
if(lvl == 1 && *s == '=') { // skip default parameter
while(r.GetCount() && s[-1] == ' ') {
s--;
r.TrimLast();
}
while(*s) {
if((*s == ',' || *s == ')') && lvl == 1) {
r.Cat(*s++);
break;
}
if(*s == '(')
lvl++;
if(*s == ')')
lvl--;
s++;
}
}
else
r.Cat(*s++);
}
r << "\n{\n}\n\n";
return r;
}
String MakeDefinition(const AnnotationItem& m)
{
return MakeDefinition(m, GetClass(m));
}

View file

@ -120,6 +120,10 @@ void Ide::Usage(const String& id, const String& name, Point ref_pos)
if(IsNull(id))
return;
DDUMP(name);
DDUMP(id);
DDUMP(ref_pos);
ResetFileLine();
int li = editor.GetCursorLine();

View file

@ -100,32 +100,6 @@ bool IsFunction(int kind);
bool IsVariable(int kind);
int FindId(const String& s, const String& id);
enum {
ITEM_TEXT,
ITEM_NAME,
ITEM_OPERATOR,
ITEM_CPP_TYPE,
ITEM_CPP,
ITEM_PNAME,
ITEM_TNAME,
ITEM_NUMBER,
ITEM_SIGN,
ITEM_UPP,
ITEM_TYPE,
ITEM_PTYPE = ITEM_TYPE + 10000,
};
struct ItemTextPart : Moveable<ItemTextPart> {
int pos;
int len;
int type;
int ii;
int pari;
};
Vector<ItemTextPart> ParsePretty(const String& name, const String& signature, int *fn_info = NULL);
struct AutoCompleteItem : Moveable<AutoCompleteItem> {
String parent;
String name;
@ -211,9 +185,6 @@ void Diagnostics(CXTranslationUnit tu, Stream& out);
inline bool IsWarning(int q) { return q == CXDiagnostic_Warning; }
inline bool IsError(int q) { return findarg(q, CXDiagnostic_Error, CXDiagnostic_Fatal) >= 0; }
String CleanupId(const char *s);
String CleanupPretty(const String& signature);
bool IsCppSourceFile(const String& path);
bool IsSourceFile(const String& path);
bool IsHeaderFile(const String& path);

View file

@ -14,7 +14,6 @@ file
libclang.cpp,
util.cpp,
macros.cpp,
Signature.cpp,
clang.cpp,
Visitor.cpp,
CurrentFile.cpp,

View file

@ -104,3 +104,93 @@ int FindId(const String& s, const String& id) {
q++;
}
};
String GetClass(const AnnotationItem& m)
{
String cls = m.id;
int q;
if(m.kind == CXCursor_Constructor) {
q = cls.Find("::" + m.name + "(");
if(q >= 0)
q += 2;
}
else
if(m.kind == CXCursor_Destructor) {
q = cls.Find('~');
}
else
q = FindId(cls, m.name);
if(q >= 0) {
cls.Trim(q);
if(m.nspace.GetCount())
cls.TrimStart(m.nspace + "::");
return cls;
}
return Null;
}
String GetNameFromId(const String& id)
{
String name;
try {
CParser p(id);
while(!p.IsEof())
if(p.IsId())
name = p.ReadId();
else
if(!p.Char(':'))
break;
}
catch(CParser::Error) {}
return name;
}
String MakeDefinition(const AnnotationItem& m, const String& klass)
{
String result;
String pretty = m.pretty;
pretty.TrimStart("static ");
int q = FindId(pretty, m.name);
if(q < 0)
result << pretty;
else
result << pretty.Mid(0, q) << klass << pretty.Mid(q);
const char *s = result;
int lvl = 0;
String r;
while(*s) {
if(*s == '(')
lvl++;
if(*s == ')')
lvl--;
if(lvl == 1 && *s == '=') { // skip default parameter
while(r.GetCount() && s[-1] == ' ') {
s--;
r.TrimLast();
}
while(*s) {
if((*s == ',' || *s == ')') && lvl == 1) {
r.Cat(*s++);
break;
}
if(*s == '(')
lvl++;
if(*s == ')')
lvl--;
s++;
}
}
else
r.Cat(*s++);
}
r << "\n{\n}\n\n";
return r;
}
String MakeDefinition(const AnnotationItem& m)
{
return MakeDefinition(m, GetClass(m));
}

View file

@ -27,8 +27,8 @@ CONSOLE_APP_MAIN
}) {
DLOG("======");
DLOG(s);
DLOG(CleanupId(s));
DLOG(CleanupPretty(s));
DLOG("id: " << CleanupId(s));
DLOG("pretty: " << CleanupPretty(s));
}
CheckLogEtalon();