mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-16 14:16:09 -06:00
168 lines
4.6 KiB
C++
168 lines
4.6 KiB
C++
#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
|
|
|
|
#define LTIMING(x) // DTIMING(x)
|
|
|
|
String ResolveTParam(const String& type, const Vector<String>& tparam)
|
|
{
|
|
CodeBaseLock __;
|
|
return ResolveTParam(CodeBase(), type, tparam);
|
|
}
|
|
|
|
void ResolveTParam(Vector<String>& type, const Vector<String>& tparam)
|
|
{
|
|
CodeBaseLock __;
|
|
return ResolveTParam(CodeBase(), type, tparam);
|
|
}
|
|
|
|
String Qualify(const String& scope, const String& type, const String& usings)
|
|
{
|
|
CodeBaseLock __;
|
|
return Qualify(CodeBase(), scope, type, usings);
|
|
}
|
|
|
|
void AssistScanError(int line, const String& text)
|
|
{
|
|
#ifdef _DEBUG
|
|
PutVerbose(String().Cat() << "(" << line << "): " << text);
|
|
#endif
|
|
}
|
|
|
|
void AssistEditor::Context(ParserContext& parser, int pos)
|
|
{
|
|
LTIMING("Context");
|
|
LLOG("---------- Context " << path);
|
|
|
|
theide->ScanFile(true);
|
|
|
|
parser = AssistParse(Get(0, pos), theide->editfile, AssistScanError);
|
|
inbody = parser.IsInBody();
|
|
#ifdef _DEBUG
|
|
PutVerbose("body: " + AsString(inbody));
|
|
PutVerbose("scope: " + AsString(parser.current_scope));
|
|
PutVerbose("using: " + AsString(parser.context.namespace_using));
|
|
for(int i = 0; i < parser.local.GetCount(); i++)
|
|
PutVerbose(parser.local.GetKey(i) + ": " + parser.local[i].type);
|
|
#endif
|
|
}
|
|
|
|
Index<String> AssistEditor::EvaluateExpressionType(const ParserContext& parser, const Vector<String>& xp)
|
|
{
|
|
CodeBaseLock __;
|
|
return GetExpressionType(CodeBase(), parser, xp);
|
|
}
|
|
|
|
void AssistEditor::AssistItemAdd(const String& scope, const CppItem& m, int typei)
|
|
{
|
|
if(!iscib(*m.name) || m.name.GetCount() == 0)
|
|
return;
|
|
CppItemInfo& f = assist_item.Add();
|
|
f.typei = typei;
|
|
f.scope = scope;
|
|
(CppItem&)f = m;
|
|
}
|
|
|
|
void AssistEditor::GatherItems(const String& type, bool only_public, Index<String>& in_types, bool types)
|
|
{
|
|
LTIMING("GatherItems");
|
|
LLOG("---- GatherItems " << type);
|
|
CodeBaseLock __;
|
|
if(in_types.Find(type) >= 0) {
|
|
LLOG("-> recursion, exiting");
|
|
return;
|
|
}
|
|
in_types.Add(type);
|
|
Vector<String> tparam;
|
|
String ntp = ParseTemplatedType(ResolveTParam(type, tparam), tparam);
|
|
int q = CodeBase().Find(ntp);
|
|
if(q < 0) {
|
|
ntp.Replace("*", ""); // * can be part of type as result of template substitution
|
|
q = CodeBase().Find(ntp);
|
|
}
|
|
if(q >= 0) {
|
|
if(types) {
|
|
if(ntp.GetCount())
|
|
ntp << "::";
|
|
int typei = assist_type.FindAdd("<types>");
|
|
for(int i = 0; i < CodeBase().GetCount(); i++) {
|
|
String nest = CodeBase().GetKey(i);
|
|
if(nest.GetLength() > ntp.GetLength() && // Subscope of scope
|
|
memcmp(~ntp, ~nest, ntp.GetLength()) == 0 && // e.g. Upp:: -> Upp::String
|
|
nest.Find("::", ntp.GetLength()) < 0) { // but not Upp::String::Buffer
|
|
Array<CppItem>& n = CodeBase()[i];
|
|
for(int i = 0; i < n.GetCount(); i++) {
|
|
const CppItem& m = n[i];
|
|
if(m.IsType())
|
|
AssistItemAdd(nest, m, typei);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
const Array<CppItem>& n = CodeBase()[q];
|
|
String base;
|
|
int typei = assist_type.FindAdd(ntp);
|
|
bool op = only_public;
|
|
for(int i = 0; i < n.GetCount(); i++)
|
|
if(n[i].kind == FRIENDCLASS)
|
|
op = false;
|
|
for(int i = 0; i < n.GetCount(); i++) {
|
|
const CppItem& im = n[i];
|
|
if(im.kind == STRUCT || im.kind == STRUCTTEMPLATE)
|
|
base << im.qptype << ';';
|
|
if((im.IsCode() || !thisback && (im.IsData() || im.IsMacro() && IsNull(type)))
|
|
&& (!op || im.access == PUBLIC)) {
|
|
AssistItemAdd(ntp, im, typei);
|
|
}
|
|
}
|
|
if(!thisback) {
|
|
Vector<String> b = Split(base, ';');
|
|
Index<String> h;
|
|
for(int i = 0; i < b.GetCount(); i++)
|
|
h.FindAdd(b[i]);
|
|
b = h.PickKeys();
|
|
ResolveTParam(b, tparam);
|
|
for(int i = 0; i < b.GetCount(); i++)
|
|
if(b[i].GetCount())
|
|
GatherItems(b[i], only_public, in_types, types);
|
|
}
|
|
}
|
|
in_types.Drop();
|
|
}
|
|
|
|
bool OrderAssistItems(const CppItemInfo& a, const CppItemInfo& b)
|
|
{
|
|
return CombineCompare(a.uname, b.uname)(a.typei, b.typei)(a.qitem, b.qitem)(a.impl, b.impl)(a.filetype, b.filetype)(a.line, b.line) < 0;
|
|
}
|
|
|
|
void AssistEditor::RemoveDuplicates()
|
|
{
|
|
LTIMING("RemoveDuplicates");
|
|
{ LTIMING("Sort");
|
|
Upp::Sort(assist_item, OrderAssistItems);
|
|
}
|
|
Vector<int> remove;
|
|
{
|
|
LTIMING("Find duplicates");
|
|
int i = 0;
|
|
while(i < assist_item.GetCount()) { // Remove identical items
|
|
int ii = i;
|
|
i++;
|
|
while(i < assist_item.GetCount()
|
|
&& assist_item[ii].typei == assist_item[i].typei
|
|
&& assist_item[ii].qitem == assist_item[i].qitem
|
|
&& assist_item[ii].scope == assist_item[i].scope)
|
|
remove.Add(i++);
|
|
}
|
|
}
|
|
LTIMING("Final remove");
|
|
assist_item.Remove(remove);
|
|
}
|