From c80a55e5b465365c1c8dffe5b4516181f785b78b Mon Sep 17 00:00:00 2001 From: cxl Date: Sun, 31 May 2015 06:45:44 +0000 Subject: [PATCH] .cosmetics git-svn-id: svn://ultimatepp.org/upp/trunk@8491 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlLib/CtrlUtil.h | 1 + uppsrc/ide/Assist.cpp | 486 ------------------------------------- uppsrc/ide/ContextGoto.cpp | 376 ++++++++++++++++++++++++++++ uppsrc/ide/DCopy.cpp | 132 ++++++++++ uppsrc/ide/ide.upp | 2 + 5 files changed, 511 insertions(+), 486 deletions(-) create mode 100644 uppsrc/ide/ContextGoto.cpp create mode 100644 uppsrc/ide/DCopy.cpp diff --git a/uppsrc/CtrlLib/CtrlUtil.h b/uppsrc/CtrlLib/CtrlUtil.h index 7c8362934..512770d7d 100644 --- a/uppsrc/CtrlLib/CtrlUtil.h +++ b/uppsrc/CtrlLib/CtrlUtil.h @@ -57,6 +57,7 @@ struct Win32PrintDlg_; class PrinterJob { #ifdef GUI_WIN One pdlg; + bool Execute0(bool dodlg); #endif #ifdef PLATFORM_X11 Size pgsz; diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index c0c7634f3..83c10b953 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -884,492 +884,6 @@ String AssistEditor::MakeDefinition(const String& cls, const String& _n) return n; } -void AssistEditor::DCopy() -{ - String r; - int l, h; - bool decla = false; - if(!GetSelection(l, h)) { - int i = GetLine(GetCursor()); - l = GetPos(i); - h = l; - while(h < GetLength() && h - l < 1000) { - int c = GetChar(h); - if(c == ';') { - decla = true; - break; - } - if(c == '{') - break; - h++; - if(c == '\"') { - while(h < GetLength()) { - int c = GetChar(h); - if(c == '\"' || c == '\n') - break; - h++; - if(c == '\\' && h < GetLength()) - h++; - } - } - } - } - else - decla = true; - - Parser ctx; - Context(ctx, l); - String txt = Get(l, h - l); - StringStream ss(txt); - String cls = ctx.current_scope; - int best = 0; - const Index& ns = CodeBase().namespaces; - for(int i = 0; i < ns.GetCount(); i++) { - String h = ns[i] + "::"; - if(h.GetCount() > best && cls.StartsWith(h)) - best = h.GetCount(); - } - cls.Remove(0, best); - CppBase cpp; - Parser parser; // we do not need/want preprocessing here - parser.Do(ss, cpp, Null, Null, Null, CNULL, Split(cls, ':'), - Vector(), Index()); - - for(int i = 0; i < cpp.GetCount(); i++) { - const Array& n = cpp[i]; - bool decl = decla; - for(int j = 0; j < n.GetCount(); j++) - if(n[j].impl) - decl = false; - for(int j = 0; j < n.GetCount(); j++) { - const CppItem& m = n[j]; - if(m.IsCode()) { - if(decl) - r << MakeDefinition(cls, m.natural) << "\n{\n}\n\n"; - else { - if(cpp.IsType(i)) - r << String('\t', Split(cpp.GetKey(i), ':').GetCount()); - r << m.natural << ";\n"; - } - } - if(m.IsData()) { - String nat = m.natural; - if(cls.GetCount()) { - nat.Replace("static", ""); - nat = TrimLeft(nat); - const char *s = nat; - while(*s) { - if(iscib(*s)) { - const char *b = s; - while(iscid(*s)) s++; - String id(b, s); - if(m.name == id) { - if(cls.GetCount()) - r << cls << "::" << m.name << s; - else - r << m.name << s; - break; - } - r << id; - } - else - r << *s++; - } - } - else { - int q = nat.ReverseFind("::"); - if(q >= 0) { // Foo Class2 :: Class::variable; -> static Foo variable; - int e = q + 2; - for(;;) { - while(q >= 0 && nat[q - 1] == ' ') - q--; - if(q == 0 || !iscid(nat[q - 1])) - break; - while(q >= 0 && iscid(nat[q - 1])) - q--; - int w = nat.ReverseFind("::", q); - if(w < 0) - break; - q = w; - } - nat.Remove(q, e - q); - r << "static " << nat; - } - else - r << "extern " << nat; - } - r << ";\n"; - } - } - } - WriteClipboardText(r); -} - -bool GetIdScope(String& os, const String& scope, const String& id, Index& done) -{ - if(done.Find(scope) >= 0) - return Null; - done.Add(scope); - Vector tparam; - String n = ParseTemplatedType(scope, tparam); - int q = CodeBase().Find(n); - if(q < 0) - return Null; - const Array& m = CodeBase()[q]; - Vector r; - if(FindName(m, id) >= 0) { - os = n; - return true; - } - for(int i = 0; i < m.GetCount(); i++) { - const CppItem& im = m[i]; - if(im.IsType()) { - Vector b = Split(im.qptype, ';'); - ResolveTParam(b, tparam); - for(int i = 0; i < b.GetCount(); i++) { - if(GetIdScope(os, b[i], id, done)) - return true; - } - } - } - return false; -} - -bool GetIdScope(String& os, const String& scope, const String& id) -{ - Index done; - return GetIdScope(os, scope, id, done); -} - -bool IsPif(const String& l) -{ - return l.Find("#if") >= 0; -} - -bool IsPelse(const String& l) -{ - return l.Find("#el") >= 0; -} - -bool IsPendif(const String& l) -{ - return l.Find("#endif") >= 0; -} - -void Ide::FindId(const String& id) -{ - int pos = editor.GetCursor(); - int h = min(editor.GetLength(), pos + 4000); - for(;;) { - if(pos >= h || findarg(editor[pos], ';', '{', '}') >= 0) - break; - if(iscib(editor[pos])) { - int p0 = pos; - String tid; - while(pos < h && iscid(editor[pos])) { - tid.Cat(editor[pos]); - pos++; - } - if(tid == id) { - editor.SetCursor(p0); - return; - } - } - else - pos++; - } -} - -String RemoveTemplateParams(const String& s) -{ - Vector dummy; - return ParseTemplatedType(s, dummy); -} - -void Ide::ContextGoto0(int pos) -{ - if(designer) - return; - int li = editor.GetLine(pos); - String l = editor.GetUtf8Line(li); - if(IsPif(l) || IsPelse(l)) { - int lvl = 0; - while(li + 1 < editor.GetLineCount()) { - l = editor.GetUtf8Line(++li); - if(IsPif(l)) - lvl++; - if(IsPelse(l) && lvl == 0) - break; - if(IsPendif(l)) { - if(lvl == 0) break; - lvl--; - } - } - AddHistory(); - editor.SetCursor(editor.GetPos(li)); - return; - } - if(IsPendif(l)) { - int lvl = 0; - while(li - 1 >= 0) { - l = editor.GetUtf8Line(--li); - if(IsPif(l)) { - if(lvl == 0) break; - lvl--; - } - if(IsPendif(l)) - lvl++; - } - AddHistory(); - editor.SetCursor(editor.GetPos(li)); - return; - } - int cr = editor.Ch(pos); - int cl = editor.Ch(pos - 1); - if(!IsAlNum(cr)) { - if(islbrkt(cr)) { - AddHistory(); - editor.MoveNextBrk(false); - return; - } - if(isrbrkt(cr)) { - AddHistory(); - editor.MovePrevBrk(false); - return; - } - if(islbrkt(cl)) { - AddHistory(); - editor.MoveNextBrk(false); - return; - } - if(isrbrkt(cl)) { - AddHistory(); - editor.MovePrevBrk(false); - return; - } - } - CParser p(l); - if(p.Char('#') && p.Id("include")) { - String path = FindIncludeFile(p.GetPtr(), GetFileFolder(editfile)); - if(!IsNull(path)) { - AddHistory(); - EditFile(path); - } - return; - } - int q = pos; - while(iscid(editor.Ch(q - 1))) - q--; - String tp; - Vector xp = editor.ReadBack(q); // try to load expression lien "x[i]." or "ptr->" - Index type; - Parser parser; - int ci = pos; - for(;;) { - int c = editor.Ch(ci); - if(c == '{' && editor.Ch(ci + 1)) { - ci++; - break; - } - if(c == '}' || c == 0) - break; - ci++; - } - editor.Context(parser, ci); - - if(xp.GetCount()) { - type = editor.EvaluateExpressionType(parser, xp); - if(type.GetCount() == 0) - return; - } - - String id = editor.GetWord(pos); - if(id.GetCount() == 0) - return; - - String qual; // Try to load type qualification like Foo::Bar, Vector::Iterator - while(editor.Ch(q - 1) == ' ') - q--; - if(editor.Ch(q - 1) == ':' && editor.Ch(q - 2) == ':') { - q -= 3; - while(q >= 0) { - int c = editor.Ch(q); - if(iscid(c) || findarg(c, '<', '>', ':', ',', ' ') >= 0) { - if(c != ' ') - qual = (char)c + qual; - q--; - } - else - break; - } - } - - Vector scope; - Vector istype; // prefer type (e.g. struct Foo) over constructor (Foo::Foo()) - - for(int i = 0; i < type.GetCount(); i++) { // 'x.attr' - Index done; - String r; - if(GetIdScope(r, type[i], id, done)) { - Vector todo; - todo.Add(r); - while(scope.GetCount() < 100 && todo.GetCount()) { // Add base classes - String t = todo[0]; - todo.Remove(0); - if(t.EndsWith("::")) - t.Trim(t.GetCount() - 2); - scope.Add(t); - istype.Add(false); - ScopeInfo f(CodeBase(), t); // Try base classes too! - todo.Append(f.GetBases()); - } - } - } - - if(qual.GetCount()) { // Ctrl::MOUSELEFT, Vector::Iterator - Vector todo; - todo.Add(RemoveTemplateParams(Qualify(CodeBase(), parser.current_scope, qual + "::" + id, parser.context.namespace_using))); - while(scope.GetCount() < 100 && todo.GetCount()) { - String t = todo[0]; - if(t.EndsWith("::")) - t.Trim(t.GetCount() - 2); - todo.Remove(0); - if(CodeBase().Find(t) >= 0) { // Ctrl::MOUSELEFT - scope.Add(t); - istype.Add(true); - } - String tt = t; - tt << "::" << id; - if(CodeBase().Find(tt) >= 0) { // Vector::Iterator - scope.Add(tt); - istype.Add(true); - } - ScopeInfo f(CodeBase(), t); // Try base classes too! - todo.Append(f.GetBases()); - } - } - else { - Vector todo; - todo.Add(parser.current_scope); - while(scope.GetCount() < 100 && todo.GetCount()) { // Add base classes - String t = todo[0]; - todo.Remove(0); - if(t.EndsWith("::")) - t.Trim(t.GetCount() - 2); - scope.Add(t); - istype.Add(false); - ScopeInfo f(CodeBase(), t); // Try base classes too! - todo.Append(f.GetBases()); - } - q = parser.local.Find(id); - if(q >= 0) { // Try locals - AddHistory(); - editor.SetCursor(editor.GetPos(parser.local[q].line - 1)); - FindId(id); - return; - } - // Can be unqualified type name like 'String' - String t = RemoveTemplateParams(Qualify(CodeBase(), parser.current_scope, id, parser.context.namespace_using)); - if(CodeBase().Find(t) >= 0) { - scope.Add(t); - istype.Add(true); - } - } - - Index done; - String r; - if(GetIdScope(r, "", id, done)) { // global - scope.Add(r); - istype.Add(false); - } - - for(int j = 0; j < scope.GetCount(); j++) { - q = CodeBase().Find(scope[j]); - if(q >= 0) { - const Array& n = CodeBase()[q]; - for(int pass = 0; pass < 2; pass++) - for(int i = 0; i < n.GetCount(); i++) { - if((pass || !istype[j] || n[i].IsType()) && n[i].name == id) { - JumpToDefinition(n, i, scope[j]); - FindId(id); - return; - } - } - } - } -} - -void Ide::ContextGoto() -{ - ContextGoto0(editor.GetCursor()); -} - -void Ide::CtrlClick(int pos) -{ - ContextGoto0(pos); -} - -void Ide::JumpToDefinition(const Array& n, int q, const String& scope) -{ - String qitem = n[q].qitem; - int i = q; - int qml = 0; - int qcpp = -1; - int qcppml = 0; - int qimpl = -1; - int qimplml = 0; - String currentfile = editfile; - while(i < n.GetCount() && n[i].qitem == qitem) { - const CppItem& m = n[i]; - int ml = GetMatchLen(editfile, GetSourceFilePath(m.file)); - if(m.impl && ml > qimplml) { - qimplml = ml; - qimpl = i; - } - if((m.filetype == FILE_CPP || m.filetype == FILE_C) && ml > qcppml) { - qcpp = i; - qcppml = ml; - } - if(ml > qml) { - q = i; - qml = ml; - } - i++; - } - const CppItem& pos = n[qimpl >= 0 ? qimpl : qcpp >= 0 ? qcpp : q]; - String path = GetSourceFilePath(pos.file); - editastext.RemoveKey(path); - editashex.RemoveKey(path); - if(ToLower(GetFileExt(path)) == ".lay") { - AddHistory(); - EditFile(path); - LayDesigner *l = dynamic_cast(~designer); - if(l) { - if(scope.StartsWith("With")) - l->FindLayout(scope.Mid(4), pos.name); - } - else { - editor.SetCursor(editor.GetPos(pos.line - 1)); - editor.TopCursor(4); - editor.SetFocus(); - } - AddHistory(); - } - else - if(ToLower(GetFileExt(path)) == ".iml") { - AddHistory(); - EditFile(path); - IdeIconDes *l = dynamic_cast(~designer); - if(l) - l->FindId(pos.name); - else - editor.SetFocus(); - AddHistory(); - } - else - GotoCpp(pos); -} - void Ide::IdeGotoCodeRef(String coderef) { LLOG("IdeGotoLink " << coderef); diff --git a/uppsrc/ide/ContextGoto.cpp b/uppsrc/ide/ContextGoto.cpp new file mode 100644 index 000000000..2e8063d8b --- /dev/null +++ b/uppsrc/ide/ContextGoto.cpp @@ -0,0 +1,376 @@ +#include "ide.h" + +#if 0 +#define LDUMP(x) DDUMP(x) +#define LDUMPC(x) DDUMPC(x) +#define LLOG(x) DLOG(x) +#else +#define LDUMP(x) +#define LDUMPC(x) +#define LLOG(x) +#endif + +bool GetIdScope(String& os, const String& scope, const String& id, Index& done) +{ + if(done.Find(scope) >= 0) + return Null; + done.Add(scope); + Vector tparam; + String n = ParseTemplatedType(scope, tparam); + int q = CodeBase().Find(n); + if(q < 0) + return Null; + const Array& m = CodeBase()[q]; + Vector r; + if(FindName(m, id) >= 0) { + os = n; + return true; + } + for(int i = 0; i < m.GetCount(); i++) { + const CppItem& im = m[i]; + if(im.IsType()) { + Vector b = Split(im.qptype, ';'); + ResolveTParam(b, tparam); + for(int i = 0; i < b.GetCount(); i++) { + if(GetIdScope(os, b[i], id, done)) + return true; + } + } + } + return false; +} + +bool GetIdScope(String& os, const String& scope, const String& id) +{ + Index done; + return GetIdScope(os, scope, id, done); +} + +bool IsPif(const String& l) +{ + return l.Find("#if") >= 0; +} + +bool IsPelse(const String& l) +{ + return l.Find("#el") >= 0; +} + +bool IsPendif(const String& l) +{ + return l.Find("#endif") >= 0; +} + +void Ide::FindId(const String& id) +{ + int pos = editor.GetCursor(); + int h = min(editor.GetLength(), pos + 4000); + for(;;) { + if(pos >= h || findarg(editor[pos], ';', '{', '}') >= 0) + break; + if(iscib(editor[pos])) { + int p0 = pos; + String tid; + while(pos < h && iscid(editor[pos])) { + tid.Cat(editor[pos]); + pos++; + } + if(tid == id) { + editor.SetCursor(p0); + return; + } + } + else + pos++; + } +} + +String RemoveTemplateParams(const String& s) +{ + Vector dummy; + return ParseTemplatedType(s, dummy); +} + +void Ide::ContextGoto0(int pos) +{ + if(designer) + return; + int li = editor.GetLine(pos); + String l = editor.GetUtf8Line(li); + if(IsPif(l) || IsPelse(l)) { + int lvl = 0; + while(li + 1 < editor.GetLineCount()) { + l = editor.GetUtf8Line(++li); + if(IsPif(l)) + lvl++; + if(IsPelse(l) && lvl == 0) + break; + if(IsPendif(l)) { + if(lvl == 0) break; + lvl--; + } + } + AddHistory(); + editor.SetCursor(editor.GetPos(li)); + return; + } + if(IsPendif(l)) { + int lvl = 0; + while(li - 1 >= 0) { + l = editor.GetUtf8Line(--li); + if(IsPif(l)) { + if(lvl == 0) break; + lvl--; + } + if(IsPendif(l)) + lvl++; + } + AddHistory(); + editor.SetCursor(editor.GetPos(li)); + return; + } + int cr = editor.Ch(pos); + int cl = editor.Ch(pos - 1); + if(!IsAlNum(cr)) { + if(islbrkt(cr)) { + AddHistory(); + editor.MoveNextBrk(false); + return; + } + if(isrbrkt(cr)) { + AddHistory(); + editor.MovePrevBrk(false); + return; + } + if(islbrkt(cl)) { + AddHistory(); + editor.MoveNextBrk(false); + return; + } + if(isrbrkt(cl)) { + AddHistory(); + editor.MovePrevBrk(false); + return; + } + } + CParser p(l); + if(p.Char('#') && p.Id("include")) { + String path = FindIncludeFile(p.GetPtr(), GetFileFolder(editfile)); + if(!IsNull(path)) { + AddHistory(); + EditFile(path); + } + return; + } + int q = pos; + while(iscid(editor.Ch(q - 1))) + q--; + String tp; + Vector xp = editor.ReadBack(q); // try to load expression lien "x[i]." or "ptr->" + Index type; + Parser parser; + int ci = pos; + for(;;) { + int c = editor.Ch(ci); + if(c == '{' && editor.Ch(ci + 1)) { + ci++; + break; + } + if(c == '}' || c == 0) + break; + ci++; + } + editor.Context(parser, ci); + + if(xp.GetCount()) { + type = editor.EvaluateExpressionType(parser, xp); + if(type.GetCount() == 0) + return; + } + + String id = editor.GetWord(pos); + if(id.GetCount() == 0) + return; + + String qual; // Try to load type qualification like Foo::Bar, Vector::Iterator + while(editor.Ch(q - 1) == ' ') + q--; + if(editor.Ch(q - 1) == ':' && editor.Ch(q - 2) == ':') { + q -= 3; + while(q >= 0) { + int c = editor.Ch(q); + if(iscid(c) || findarg(c, '<', '>', ':', ',', ' ') >= 0) { + if(c != ' ') + qual = (char)c + qual; + q--; + } + else + break; + } + } + + Vector scope; + Vector istype; // prefer type (e.g. struct Foo) over constructor (Foo::Foo()) + + for(int i = 0; i < type.GetCount(); i++) { // 'x.attr' + Index done; + String r; + if(GetIdScope(r, type[i], id, done)) { + Vector todo; + todo.Add(r); + while(scope.GetCount() < 100 && todo.GetCount()) { // Add base classes + String t = todo[0]; + todo.Remove(0); + if(t.EndsWith("::")) + t.Trim(t.GetCount() - 2); + scope.Add(t); + istype.Add(false); + ScopeInfo f(CodeBase(), t); // Try base classes too! + todo.Append(f.GetBases()); + } + } + } + + if(qual.GetCount()) { // Ctrl::MOUSELEFT, Vector::Iterator + Vector todo; + todo.Add(RemoveTemplateParams(Qualify(CodeBase(), parser.current_scope, qual + "::" + id, parser.context.namespace_using))); + while(scope.GetCount() < 100 && todo.GetCount()) { + String t = todo[0]; + if(t.EndsWith("::")) + t.Trim(t.GetCount() - 2); + todo.Remove(0); + if(CodeBase().Find(t) >= 0) { // Ctrl::MOUSELEFT + scope.Add(t); + istype.Add(true); + } + String tt = t; + tt << "::" << id; + if(CodeBase().Find(tt) >= 0) { // Vector::Iterator + scope.Add(tt); + istype.Add(true); + } + ScopeInfo f(CodeBase(), t); // Try base classes too! + todo.Append(f.GetBases()); + } + } + else { + Vector todo; + todo.Add(parser.current_scope); + while(scope.GetCount() < 100 && todo.GetCount()) { // Add base classes + String t = todo[0]; + todo.Remove(0); + if(t.EndsWith("::")) + t.Trim(t.GetCount() - 2); + scope.Add(t); + istype.Add(false); + ScopeInfo f(CodeBase(), t); // Try base classes too! + todo.Append(f.GetBases()); + } + q = parser.local.Find(id); + if(q >= 0) { // Try locals + AddHistory(); + editor.SetCursor(editor.GetPos(parser.local[q].line - 1)); + FindId(id); + return; + } + // Can be unqualified type name like 'String' + String t = RemoveTemplateParams(Qualify(CodeBase(), parser.current_scope, id, parser.context.namespace_using)); + if(CodeBase().Find(t) >= 0) { + scope.Add(t); + istype.Add(true); + } + } + + Index done; + String r; + if(GetIdScope(r, "", id, done)) { // global + scope.Add(r); + istype.Add(false); + } + + for(int j = 0; j < scope.GetCount(); j++) { + q = CodeBase().Find(scope[j]); + if(q >= 0) { + const Array& n = CodeBase()[q]; + for(int pass = 0; pass < 2; pass++) + for(int i = 0; i < n.GetCount(); i++) { + if((pass || !istype[j] || n[i].IsType()) && n[i].name == id) { + JumpToDefinition(n, i, scope[j]); + FindId(id); + return; + } + } + } + } +} + +void Ide::ContextGoto() +{ + ContextGoto0(editor.GetCursor()); +} + +void Ide::CtrlClick(int pos) +{ + ContextGoto0(pos); +} + +void Ide::JumpToDefinition(const Array& n, int q, const String& scope) +{ + String qitem = n[q].qitem; + int i = q; + int qml = 0; + int qcpp = -1; + int qcppml = 0; + int qimpl = -1; + int qimplml = 0; + String currentfile = editfile; + while(i < n.GetCount() && n[i].qitem == qitem) { + const CppItem& m = n[i]; + int ml = GetMatchLen(editfile, GetSourceFilePath(m.file)); + if(m.impl && ml > qimplml) { + qimplml = ml; + qimpl = i; + } + if((m.filetype == FILE_CPP || m.filetype == FILE_C) && ml > qcppml) { + qcpp = i; + qcppml = ml; + } + if(ml > qml) { + q = i; + qml = ml; + } + i++; + } + const CppItem& pos = n[qimpl >= 0 ? qimpl : qcpp >= 0 ? qcpp : q]; + String path = GetSourceFilePath(pos.file); + editastext.RemoveKey(path); + editashex.RemoveKey(path); + if(ToLower(GetFileExt(path)) == ".lay") { + AddHistory(); + EditFile(path); + LayDesigner *l = dynamic_cast(~designer); + if(l) { + if(scope.StartsWith("With")) + l->FindLayout(scope.Mid(4), pos.name); + } + else { + editor.SetCursor(editor.GetPos(pos.line - 1)); + editor.TopCursor(4); + editor.SetFocus(); + } + AddHistory(); + } + else + if(ToLower(GetFileExt(path)) == ".iml") { + AddHistory(); + EditFile(path); + IdeIconDes *l = dynamic_cast(~designer); + if(l) + l->FindId(pos.name); + else + editor.SetFocus(); + AddHistory(); + } + else + GotoCpp(pos); +} diff --git a/uppsrc/ide/DCopy.cpp b/uppsrc/ide/DCopy.cpp new file mode 100644 index 000000000..67e244ea3 --- /dev/null +++ b/uppsrc/ide/DCopy.cpp @@ -0,0 +1,132 @@ +#include "ide.h" + +#if 0 +#define LDUMP(x) DDUMP(x) +#define LDUMPC(x) DDUMPC(x) +#define LLOG(x) DLOG(x) +#else +#define LDUMP(x) +#define LDUMPC(x) +#define LLOG(x) +#endif + +void AssistEditor::DCopy() +{ + String r; + int l, h; + bool decla = false; + if(!GetSelection(l, h)) { + int i = GetLine(GetCursor()); + l = GetPos(i); + h = l; + while(h < GetLength() && h - l < 1000) { + int c = GetChar(h); + if(c == ';') { + decla = true; + break; + } + if(c == '{') + break; + h++; + if(c == '\"') { + while(h < GetLength()) { + int c = GetChar(h); + if(c == '\"' || c == '\n') + break; + h++; + if(c == '\\' && h < GetLength()) + h++; + } + } + } + } + else + decla = true; + + Parser ctx; + Context(ctx, l); + String txt = Get(l, h - l); + StringStream ss(txt); + String cls = ctx.current_scope; + int best = 0; + const Index& ns = CodeBase().namespaces; + for(int i = 0; i < ns.GetCount(); i++) { + String h = ns[i] + "::"; + if(h.GetCount() > best && cls.StartsWith(h)) + best = h.GetCount(); + } + cls.Remove(0, best); + CppBase cpp; + Parser parser; // we do not need/want preprocessing here + parser.Do(ss, cpp, Null, Null, Null, CNULL, Split(cls, ':'), + Vector(), Index()); + + for(int i = 0; i < cpp.GetCount(); i++) { + const Array& n = cpp[i]; + bool decl = decla; + for(int j = 0; j < n.GetCount(); j++) + if(n[j].impl) + decl = false; + for(int j = 0; j < n.GetCount(); j++) { + const CppItem& m = n[j]; + if(m.IsCode()) { + if(decl) + r << MakeDefinition(cls, m.natural) << "\n{\n}\n\n"; + else { + if(cpp.IsType(i)) + r << String('\t', Split(cpp.GetKey(i), ':').GetCount()); + r << m.natural << ";\n"; + } + } + if(m.IsData()) { + String nat = m.natural; + if(cls.GetCount()) { + nat.Replace("static", ""); + nat = TrimLeft(nat); + const char *s = nat; + while(*s) { + if(iscib(*s)) { + const char *b = s; + while(iscid(*s)) s++; + String id(b, s); + if(m.name == id) { + if(cls.GetCount()) + r << cls << "::" << m.name << s; + else + r << m.name << s; + break; + } + r << id; + } + else + r << *s++; + } + } + else { + int q = nat.ReverseFind("::"); + if(q >= 0) { // Foo Class2 :: Class::variable; -> static Foo variable; + int e = q + 2; + for(;;) { + while(q >= 0 && nat[q - 1] == ' ') + q--; + if(q == 0 || !iscid(nat[q - 1])) + break; + while(q >= 0 && iscid(nat[q - 1])) + q--; + int w = nat.ReverseFind("::", q); + if(w < 0) + break; + q = w; + } + nat.Remove(q, e - q); + r << "static " << nat; + } + else + r << "extern " << nat; + } + r << ";\n"; + } + } + } + WriteClipboardText(r); +} diff --git a/uppsrc/ide/ide.upp b/uppsrc/ide/ide.upp index 2243de767..b662eeda4 100644 --- a/uppsrc/ide/ide.upp +++ b/uppsrc/ide/ide.upp @@ -45,6 +45,8 @@ file Cpp.cpp, Assist.h, Assist.cpp, + DCopy.cpp, + ContextGoto.cpp, ParamInfo.cpp, Navigator.cpp, Annotations.cpp,