Pull symbol resolution code out into dsymbol folder
This commit is contained in:
parent
4cc67f0ea2
commit
ae83e447a4
|
@ -117,7 +117,7 @@ A line containing the string "calltips", followed by zero or more lines, each
|
||||||
containing a call tip for an overload of the given function.
|
containing a call tip for an overload of the given function.
|
||||||
##### Example output
|
##### Example output
|
||||||
calltips
|
calltips
|
||||||
ACSymbol findSymbolInCurrentScope(size_t cursorPosition, string name)
|
Symbol findSymbolInCurrentScope(size_t cursorPosition, string name)
|
||||||
|
|
||||||
## Doc comment display
|
## Doc comment display
|
||||||
```dcd-client --doc -c 4298```
|
```dcd-client --doc -c 4298```
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
module dsymbol.builtin.names;
|
||||||
|
|
||||||
|
import std.d.lexer;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
|
||||||
|
package immutable(istring[24]) builtinTypeNames;
|
||||||
|
|
||||||
|
/// Constants for buit-in or dummy symbol names
|
||||||
|
immutable istring IMPORT_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring WITH_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring CONSTRUCTOR_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring DESTRUCTOR_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring ARGPTR_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring ARGUMENTS_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring THIS_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring SUPER_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring UNITTEST_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring DOUBLE_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring FLOAT_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring IDOUBLE_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring IFLOAT_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring INT_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring LONG_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring REAL_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring IREAL_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring UINT_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring ULONG_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring CHAR_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring DSTRING_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring STRING_LITERAL_SYMBOL_NAME;
|
||||||
|
/// ditto
|
||||||
|
immutable istring WSTRING_LITERAL_SYMBOL_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates the IDs for built-in types into an interned string.
|
||||||
|
*/
|
||||||
|
istring getBuiltinTypeName(IdType id) nothrow pure @nogc @safe
|
||||||
|
{
|
||||||
|
switch (id)
|
||||||
|
{
|
||||||
|
case tok!"int": return builtinTypeNames[0];
|
||||||
|
case tok!"uint": return builtinTypeNames[1];
|
||||||
|
case tok!"double": return builtinTypeNames[2];
|
||||||
|
case tok!"idouble": return builtinTypeNames[3];
|
||||||
|
case tok!"float": return builtinTypeNames[4];
|
||||||
|
case tok!"ifloat": return builtinTypeNames[5];
|
||||||
|
case tok!"short": return builtinTypeNames[6];
|
||||||
|
case tok!"ushort": return builtinTypeNames[7];
|
||||||
|
case tok!"long": return builtinTypeNames[8];
|
||||||
|
case tok!"ulong": return builtinTypeNames[9];
|
||||||
|
case tok!"char": return builtinTypeNames[10];
|
||||||
|
case tok!"wchar": return builtinTypeNames[11];
|
||||||
|
case tok!"dchar": return builtinTypeNames[12];
|
||||||
|
case tok!"bool": return builtinTypeNames[13];
|
||||||
|
case tok!"void": return builtinTypeNames[14];
|
||||||
|
case tok!"cent": return builtinTypeNames[15];
|
||||||
|
case tok!"ucent": return builtinTypeNames[16];
|
||||||
|
case tok!"real": return builtinTypeNames[17];
|
||||||
|
case tok!"ireal": return builtinTypeNames[18];
|
||||||
|
case tok!"byte": return builtinTypeNames[19];
|
||||||
|
case tok!"ubyte": return builtinTypeNames[20];
|
||||||
|
case tok!"cdouble": return builtinTypeNames[21];
|
||||||
|
case tok!"cfloat": return builtinTypeNames[22];
|
||||||
|
case tok!"creal": return builtinTypeNames[23];
|
||||||
|
default: assert (false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes builtin types and the various properties of builtin types
|
||||||
|
*/
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
builtinTypeNames[0] = internString("int");
|
||||||
|
builtinTypeNames[1] = internString("uint");
|
||||||
|
builtinTypeNames[2] = internString("double");
|
||||||
|
builtinTypeNames[3] = internString("idouble");
|
||||||
|
builtinTypeNames[4] = internString("float");
|
||||||
|
builtinTypeNames[5] = internString("ifloat");
|
||||||
|
builtinTypeNames[6] = internString("short");
|
||||||
|
builtinTypeNames[7] = internString("ushort");
|
||||||
|
builtinTypeNames[8] = internString("long");
|
||||||
|
builtinTypeNames[9] = internString("ulong");
|
||||||
|
builtinTypeNames[10] = internString("char");
|
||||||
|
builtinTypeNames[11] = internString("wchar");
|
||||||
|
builtinTypeNames[12] = internString("dchar");
|
||||||
|
builtinTypeNames[13] = internString("bool");
|
||||||
|
builtinTypeNames[14] = internString("void");
|
||||||
|
builtinTypeNames[15] = internString("cent");
|
||||||
|
builtinTypeNames[16] = internString("ucent");
|
||||||
|
builtinTypeNames[17] = internString("real");
|
||||||
|
builtinTypeNames[18] = internString("ireal");
|
||||||
|
builtinTypeNames[19] = internString("byte");
|
||||||
|
builtinTypeNames[20] = internString("ubyte");
|
||||||
|
builtinTypeNames[21] = internString("cdouble");
|
||||||
|
builtinTypeNames[22] = internString("cfloat");
|
||||||
|
builtinTypeNames[23] = internString("creal");
|
||||||
|
|
||||||
|
IMPORT_SYMBOL_NAME = internString("public");
|
||||||
|
WITH_SYMBOL_NAME = internString("with");
|
||||||
|
CONSTRUCTOR_SYMBOL_NAME = internString("*constructor*");
|
||||||
|
DESTRUCTOR_SYMBOL_NAME = internString("~this");
|
||||||
|
ARGPTR_SYMBOL_NAME = internString("_argptr");
|
||||||
|
ARGUMENTS_SYMBOL_NAME = internString("_arguments");
|
||||||
|
THIS_SYMBOL_NAME = internString("this");
|
||||||
|
SUPER_SYMBOL_NAME = internString("super");
|
||||||
|
UNITTEST_SYMBOL_NAME = internString("*unittest*");
|
||||||
|
DOUBLE_LITERAL_SYMBOL_NAME = internString("*double");
|
||||||
|
FLOAT_LITERAL_SYMBOL_NAME = internString("*float");
|
||||||
|
IDOUBLE_LITERAL_SYMBOL_NAME = internString("*idouble");
|
||||||
|
IFLOAT_LITERAL_SYMBOL_NAME = internString("*ifloat");
|
||||||
|
INT_LITERAL_SYMBOL_NAME = internString("*int");
|
||||||
|
LONG_LITERAL_SYMBOL_NAME = internString("*long");
|
||||||
|
REAL_LITERAL_SYMBOL_NAME = internString("*real");
|
||||||
|
IREAL_LITERAL_SYMBOL_NAME = internString("*ireal");
|
||||||
|
UINT_LITERAL_SYMBOL_NAME = internString("*uint");
|
||||||
|
ULONG_LITERAL_SYMBOL_NAME = internString("*ulong");
|
||||||
|
CHAR_LITERAL_SYMBOL_NAME = internString("*char");
|
||||||
|
DSTRING_LITERAL_SYMBOL_NAME = internString("*dstring");
|
||||||
|
STRING_LITERAL_SYMBOL_NAME = internString("*string");
|
||||||
|
WSTRING_LITERAL_SYMBOL_NAME = internString("*wstring");
|
||||||
|
}
|
|
@ -0,0 +1,235 @@
|
||||||
|
module dsymbol.builtin.symbols;
|
||||||
|
|
||||||
|
import dsymbol.symbol;
|
||||||
|
import dsymbol.builtin.names;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
import containers.ttree;
|
||||||
|
import std.allocator;
|
||||||
|
import std.d.lexer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Symbols for the built in types
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) builtinSymbols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array properties
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) arraySymbols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Associative array properties
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) assocArraySymbols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Struct, enum, union, class, and interface properties
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) aggregateSymbols;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class properties
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) classSymbols;
|
||||||
|
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
auto bool_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[13], CompletionKind.keyword);
|
||||||
|
auto int_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[0], CompletionKind.keyword);
|
||||||
|
auto long_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[8], CompletionKind.keyword);
|
||||||
|
auto byte_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[19], CompletionKind.keyword);
|
||||||
|
auto char_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[10], CompletionKind.keyword);
|
||||||
|
auto dchar_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[12], CompletionKind.keyword);
|
||||||
|
auto short_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[6], CompletionKind.keyword);
|
||||||
|
auto ubyte_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[20], CompletionKind.keyword);
|
||||||
|
auto uint_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[1], CompletionKind.keyword);
|
||||||
|
auto ulong_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[9], CompletionKind.keyword);
|
||||||
|
auto ushort_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[7], CompletionKind.keyword);
|
||||||
|
auto wchar_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[11], CompletionKind.keyword);
|
||||||
|
|
||||||
|
auto alignof_ = allocate!DSymbol(Mallocator.it, internString("alignof"), CompletionKind.keyword);
|
||||||
|
auto mangleof_ = allocate!DSymbol(Mallocator.it, internString("mangleof"), CompletionKind.keyword);
|
||||||
|
auto sizeof_ = allocate!DSymbol(Mallocator.it, internString("sizeof"), CompletionKind.keyword);
|
||||||
|
auto stringof_ = allocate!DSymbol(Mallocator.it, internString("init"), CompletionKind.keyword);
|
||||||
|
auto init = allocate!DSymbol(Mallocator.it, internString("stringof"), CompletionKind.keyword);
|
||||||
|
|
||||||
|
arraySymbols.insert(alignof_);
|
||||||
|
arraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("dup"), CompletionKind.keyword));
|
||||||
|
arraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("idup"), CompletionKind.keyword));
|
||||||
|
arraySymbols.insert(init);
|
||||||
|
arraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("length"), CompletionKind.keyword, ulong_));
|
||||||
|
arraySymbols.insert(mangleof_);
|
||||||
|
arraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("ptr"), CompletionKind.keyword));
|
||||||
|
arraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("reverse"), CompletionKind.keyword));
|
||||||
|
arraySymbols.insert(sizeof_);
|
||||||
|
arraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("sort"), CompletionKind.keyword));
|
||||||
|
arraySymbols.insert(stringof_);
|
||||||
|
|
||||||
|
assocArraySymbols.insert(alignof_);
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("byKey"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("byValue"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("dup"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("get"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("init"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("keys"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("length"), CompletionKind.keyword, ulong_));
|
||||||
|
assocArraySymbols.insert(mangleof_);
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("rehash"), CompletionKind.keyword));
|
||||||
|
assocArraySymbols.insert(sizeof_);
|
||||||
|
assocArraySymbols.insert(stringof_);
|
||||||
|
assocArraySymbols.insert(init);
|
||||||
|
assocArraySymbols.insert(allocate!DSymbol(Mallocator.it, internString("values"), CompletionKind.keyword));
|
||||||
|
|
||||||
|
DSymbol*[11] integralTypeArray;
|
||||||
|
integralTypeArray[0] = bool_;
|
||||||
|
integralTypeArray[1] = int_;
|
||||||
|
integralTypeArray[2] = long_;
|
||||||
|
integralTypeArray[3] = byte_;
|
||||||
|
integralTypeArray[4] = char_;
|
||||||
|
integralTypeArray[4] = dchar_;
|
||||||
|
integralTypeArray[5] = short_;
|
||||||
|
integralTypeArray[6] = ubyte_;
|
||||||
|
integralTypeArray[7] = uint_;
|
||||||
|
integralTypeArray[8] = ulong_;
|
||||||
|
integralTypeArray[9] = ushort_;
|
||||||
|
integralTypeArray[10] = wchar_;
|
||||||
|
|
||||||
|
foreach (s; integralTypeArray)
|
||||||
|
{
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("init"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("min"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("max"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(alignof_);
|
||||||
|
s.parts.insert(sizeof_);
|
||||||
|
s.parts.insert(stringof_);
|
||||||
|
s.parts.insert(mangleof_);
|
||||||
|
s.parts.insert(init);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cdouble_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[21], CompletionKind.keyword);
|
||||||
|
auto cent_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[15], CompletionKind.keyword);
|
||||||
|
auto cfloat_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[22], CompletionKind.keyword);
|
||||||
|
auto creal_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[23], CompletionKind.keyword);
|
||||||
|
auto double_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[2], CompletionKind.keyword);
|
||||||
|
auto float_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[4], CompletionKind.keyword);
|
||||||
|
auto idouble_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[3], CompletionKind.keyword);
|
||||||
|
auto ifloat_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[5], CompletionKind.keyword);
|
||||||
|
auto ireal_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[18], CompletionKind.keyword);
|
||||||
|
auto real_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[17], CompletionKind.keyword);
|
||||||
|
auto ucent_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[16], CompletionKind.keyword);
|
||||||
|
|
||||||
|
DSymbol*[11] floatTypeArray;
|
||||||
|
floatTypeArray[0] = cdouble_;
|
||||||
|
floatTypeArray[1] = cent_;
|
||||||
|
floatTypeArray[2] = cfloat_;
|
||||||
|
floatTypeArray[3] = creal_;
|
||||||
|
floatTypeArray[4] = double_;
|
||||||
|
floatTypeArray[5] = float_;
|
||||||
|
floatTypeArray[6] = idouble_;
|
||||||
|
floatTypeArray[7] = ifloat_;
|
||||||
|
floatTypeArray[8] = ireal_;
|
||||||
|
floatTypeArray[9] = real_;
|
||||||
|
floatTypeArray[10] = ucent_;
|
||||||
|
|
||||||
|
foreach (s; floatTypeArray)
|
||||||
|
{
|
||||||
|
s.parts.insert(alignof_);
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("dig"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("epsilon"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("infinity"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("init"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(mangleof_);
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("mant_dig"), CompletionKind.keyword, int_));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("max"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("max_10_exp"), CompletionKind.keyword, int_));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("max_exp"), CompletionKind.keyword, int_));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("min"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("min_exp"), CompletionKind.keyword, int_));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("min_10_exp"), CompletionKind.keyword, int_));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("min_normal"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(allocate!DSymbol(Mallocator.it, internString("nan"), CompletionKind.keyword, s));
|
||||||
|
s.parts.insert(sizeof_);
|
||||||
|
s.parts.insert(stringof_);
|
||||||
|
}
|
||||||
|
|
||||||
|
aggregateSymbols.insert(allocate!DSymbol(Mallocator.it, internString("tupleof"), CompletionKind.keyword));
|
||||||
|
aggregateSymbols.insert(mangleof_);
|
||||||
|
aggregateSymbols.insert(alignof_);
|
||||||
|
aggregateSymbols.insert(sizeof_);
|
||||||
|
aggregateSymbols.insert(stringof_);
|
||||||
|
aggregateSymbols.insert(init);
|
||||||
|
|
||||||
|
classSymbols.insert(allocate!DSymbol(Mallocator.it, internString("classInfo"), CompletionKind.variableName));
|
||||||
|
classSymbols.insert(allocate!DSymbol(Mallocator.it, internString("tupleof"), CompletionKind.variableName));
|
||||||
|
classSymbols.insert(allocate!DSymbol(Mallocator.it, internString("__vptr"), CompletionKind.variableName));
|
||||||
|
classSymbols.insert(allocate!DSymbol(Mallocator.it, internString("__monitor"), CompletionKind.variableName));
|
||||||
|
classSymbols.insert(mangleof_);
|
||||||
|
classSymbols.insert(alignof_);
|
||||||
|
classSymbols.insert(sizeof_);
|
||||||
|
classSymbols.insert(stringof_);
|
||||||
|
classSymbols.insert(init);
|
||||||
|
|
||||||
|
ireal_.parts.insert(allocate!DSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, real_));
|
||||||
|
ifloat_.parts.insert(allocate!DSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, float_));
|
||||||
|
idouble_.parts.insert(allocate!DSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, double_));
|
||||||
|
ireal_.parts.insert(allocate!DSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, real_));
|
||||||
|
ifloat_.parts.insert(allocate!DSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, float_));
|
||||||
|
idouble_.parts.insert(allocate!DSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, double_));
|
||||||
|
|
||||||
|
auto void_ = allocate!DSymbol(Mallocator.it, builtinTypeNames[14], CompletionKind.keyword);
|
||||||
|
|
||||||
|
builtinSymbols.insert(bool_);
|
||||||
|
bool_.type = bool_;
|
||||||
|
builtinSymbols.insert(int_);
|
||||||
|
int_.type = int_;
|
||||||
|
builtinSymbols.insert(long_);
|
||||||
|
long_.type = long_;
|
||||||
|
builtinSymbols.insert(byte_);
|
||||||
|
byte_.type = byte_;
|
||||||
|
builtinSymbols.insert(char_);
|
||||||
|
char_.type = char_;
|
||||||
|
builtinSymbols.insert(dchar_);
|
||||||
|
dchar_.type = dchar_;
|
||||||
|
builtinSymbols.insert(short_);
|
||||||
|
short_.type = short_;
|
||||||
|
builtinSymbols.insert(ubyte_);
|
||||||
|
ubyte_.type = ubyte_;
|
||||||
|
builtinSymbols.insert(uint_);
|
||||||
|
uint_.type = uint_;
|
||||||
|
builtinSymbols.insert(ulong_);
|
||||||
|
ulong_.type = ulong_;
|
||||||
|
builtinSymbols.insert(ushort_);
|
||||||
|
ushort_.type = ushort_;
|
||||||
|
builtinSymbols.insert(wchar_);
|
||||||
|
wchar_.type = wchar_;
|
||||||
|
builtinSymbols.insert(cdouble_);
|
||||||
|
cdouble_.type = cdouble_;
|
||||||
|
builtinSymbols.insert(cent_);
|
||||||
|
cent_.type = cent_;
|
||||||
|
builtinSymbols.insert(cfloat_);
|
||||||
|
cfloat_.type = cfloat_;
|
||||||
|
builtinSymbols.insert(creal_);
|
||||||
|
creal_.type = creal_;
|
||||||
|
builtinSymbols.insert(double_);
|
||||||
|
double_.type = double_;
|
||||||
|
builtinSymbols.insert(float_);
|
||||||
|
float_.type = float_;
|
||||||
|
builtinSymbols.insert(idouble_);
|
||||||
|
idouble_.type = idouble_;
|
||||||
|
builtinSymbols.insert(ifloat_);
|
||||||
|
ifloat_.type = ifloat_;
|
||||||
|
builtinSymbols.insert(ireal_);
|
||||||
|
ireal_.type = ireal_;
|
||||||
|
builtinSymbols.insert(real_);
|
||||||
|
real_.type = real_;
|
||||||
|
builtinSymbols.insert(ucent_);
|
||||||
|
ucent_.type = ucent_;
|
||||||
|
builtinSymbols.insert(void_);
|
||||||
|
void_.type = void_;
|
||||||
|
|
||||||
|
|
||||||
|
foreach (s; ["__DATE__", "__EOF__", "__TIME__", "__TIMESTAMP__", "__VENDOR__",
|
||||||
|
"__VERSION__", "__FUNCTION__", "__PRETTY_FUNCTION__", "__MODULE__",
|
||||||
|
"__FILE__", "__LINE__"])
|
||||||
|
builtinSymbols.insert(allocate!DSymbol(Mallocator.it, internString(s), CompletionKind.keyword));
|
||||||
|
}
|
|
@ -16,19 +16,20 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module conversion.astconverter;
|
module dsymbol.conversion.astconverter;
|
||||||
|
|
||||||
import actypes;
|
import dsymbol.conversion.first;
|
||||||
import conversion.first;
|
import dsymbol.conversion.second;
|
||||||
import conversion.second;
|
import dsymbol.conversion.third;
|
||||||
import conversion.third;
|
import dsymbol.scope_;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
import dsymbol.symbol;
|
||||||
import memory.allocators;
|
import memory.allocators;
|
||||||
import std.allocator;
|
import std.allocator;
|
||||||
import std.d.ast;
|
import std.d.ast;
|
||||||
import std.d.lexer;
|
import std.d.lexer;
|
||||||
import std.d.parser;
|
import std.d.parser;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
import string_interning;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by autocompletion.
|
* Used by autocompletion.
|
|
@ -16,21 +16,25 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module conversion.first;
|
module dsymbol.conversion.first;
|
||||||
|
|
||||||
import actypes;
|
import containers.unrolledlist;
|
||||||
import std.d.formatter;
|
import dsymbol.builtin.names;
|
||||||
import std.allocator;
|
import dsymbol.builtin.symbols;
|
||||||
|
import dsymbol.import_;
|
||||||
|
import dsymbol.scope_;
|
||||||
|
import dsymbol.semantic;
|
||||||
|
import dsymbol.semantic;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
import dsymbol.symbol;
|
||||||
import memory.allocators;
|
import memory.allocators;
|
||||||
import memory.appender;
|
import memory.appender;
|
||||||
import messages;
|
import messages;
|
||||||
import semantic;
|
import std.allocator;
|
||||||
import std.d.ast;
|
import std.d.ast;
|
||||||
|
import std.d.formatter;
|
||||||
import std.d.lexer;
|
import std.d.lexer;
|
||||||
import std.typecons;
|
import std.typecons;
|
||||||
import stupidlog;
|
|
||||||
import containers.unrolledlist;
|
|
||||||
import string_interning;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* First Pass handles the following:
|
* First Pass handles the following:
|
||||||
|
@ -325,7 +329,7 @@ final class FirstPass : ASTVisitor
|
||||||
Scope* s = allocate!Scope(semanticAllocator, structBody.startLocation, structBody.endLocation);
|
Scope* s = allocate!Scope(semanticAllocator, structBody.startLocation, structBody.endLocation);
|
||||||
// Log.trace("Added scope ", s.startLocation, " ", s.endLocation);
|
// Log.trace("Added scope ", s.startLocation, " ", s.endLocation);
|
||||||
|
|
||||||
ACSymbol* thisSymbol = allocate!ACSymbol(symbolAllocator,
|
DSymbol* thisSymbol = allocate!DSymbol(symbolAllocator,
|
||||||
THIS_SYMBOL_NAME, CompletionKind.variableName, currentSymbol.acSymbol);
|
THIS_SYMBOL_NAME, CompletionKind.variableName, currentSymbol.acSymbol);
|
||||||
thisSymbol.location = s.startLocation;
|
thisSymbol.location = s.startLocation;
|
||||||
thisSymbol.symbolFile = symbolFile;
|
thisSymbol.symbolFile = symbolFile;
|
||||||
|
@ -705,7 +709,7 @@ private:
|
||||||
}
|
}
|
||||||
body
|
body
|
||||||
{
|
{
|
||||||
ACSymbol* acSymbol = allocate!ACSymbol(symbolAllocator, name, kind);
|
DSymbol* acSymbol = allocate!DSymbol(symbolAllocator, name, kind);
|
||||||
acSymbol.location = location;
|
acSymbol.location = location;
|
||||||
acSymbol.symbolFile = symbolFile;
|
acSymbol.symbolFile = symbolFile;
|
||||||
symbolsAllocated++;
|
symbolsAllocated++;
|
|
@ -16,15 +16,17 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module conversion.second;
|
module dsymbol.conversion.second;
|
||||||
|
|
||||||
import conversion.first;
|
import dsymbol.conversion.first;
|
||||||
import actypes;
|
import dsymbol.semantic;
|
||||||
import semantic;
|
import dsymbol.string_interning;
|
||||||
import messages;
|
import dsymbol.symbol;
|
||||||
|
import dsymbol.scope_;
|
||||||
|
import dsymbol.import_;
|
||||||
|
import dsymbol.builtin.symbols;
|
||||||
|
import dsymbol.builtin.names;
|
||||||
import std.allocator;
|
import std.allocator;
|
||||||
import stupidlog;
|
|
||||||
import string_interning;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Second pass handles the following:
|
* Second pass handles the following:
|
||||||
|
@ -79,7 +81,7 @@ private:
|
||||||
/**
|
/**
|
||||||
* Assigns symbols to scopes based on their location.
|
* Assigns symbols to scopes based on their location.
|
||||||
*/
|
*/
|
||||||
void assignToScopes(ACSymbol* currentSymbol)
|
void assignToScopes(DSymbol* currentSymbol)
|
||||||
{
|
{
|
||||||
if (currentSymbol.kind != CompletionKind.moduleName)
|
if (currentSymbol.kind != CompletionKind.moduleName)
|
||||||
{
|
{
|
||||||
|
@ -102,8 +104,8 @@ private:
|
||||||
* Returns: A package symbol that can be used for auto-completing qualified
|
* Returns: A package symbol that can be used for auto-completing qualified
|
||||||
* symbol names.
|
* symbol names.
|
||||||
*/
|
*/
|
||||||
ACSymbol* createImportSymbols(ImportInformation* info, Scope* currentScope,
|
DSymbol* createImportSymbols(ImportInformation* info, Scope* currentScope,
|
||||||
ACSymbol* moduleSymbol)
|
DSymbol* moduleSymbol)
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert (info !is null);
|
assert (info !is null);
|
||||||
|
@ -116,14 +118,14 @@ private:
|
||||||
immutable istring firstPart = info.importParts[].front;
|
immutable istring firstPart = info.importParts[].front;
|
||||||
|
|
||||||
// top-level package symbol
|
// top-level package symbol
|
||||||
ACSymbol* firstSymbol = void;
|
DSymbol* firstSymbol = void;
|
||||||
ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
|
DSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
|
||||||
if (symbols.length > 0)
|
if (symbols.length > 0)
|
||||||
firstSymbol = symbols[0];
|
firstSymbol = symbols[0];
|
||||||
else
|
else
|
||||||
firstSymbol = allocate!ACSymbol(symbolAllocator, firstPart,
|
firstSymbol = allocate!DSymbol(symbolAllocator, firstPart,
|
||||||
CompletionKind.packageName);
|
CompletionKind.packageName);
|
||||||
ACSymbol* currentSymbol = firstSymbol;
|
DSymbol* currentSymbol = firstSymbol;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
foreach (importPart; info.importParts[])
|
foreach (importPart; info.importParts[])
|
||||||
{
|
{
|
||||||
|
@ -133,7 +135,7 @@ private:
|
||||||
if (i + 2 >= info.importParts.length) // Skip the last item as it's the module name
|
if (i + 2 >= info.importParts.length) // Skip the last item as it's the module name
|
||||||
break;
|
break;
|
||||||
symbols = currentSymbol.getPartsByName(importPart);
|
symbols = currentSymbol.getPartsByName(importPart);
|
||||||
ACSymbol* s = null;
|
DSymbol* s = null;
|
||||||
foreach (sy; symbols)
|
foreach (sy; symbols)
|
||||||
{
|
{
|
||||||
if (sy.kind == CompletionKind.packageName)
|
if (sy.kind == CompletionKind.packageName)
|
||||||
|
@ -143,7 +145,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s is null)
|
if (s is null)
|
||||||
s = allocate!ACSymbol(symbolAllocator, importPart, CompletionKind.packageName);
|
s = allocate!DSymbol(symbolAllocator, importPart, CompletionKind.packageName);
|
||||||
currentSymbol.parts.insert(s);
|
currentSymbol.parts.insert(s);
|
||||||
currentSymbol = s;
|
currentSymbol = s;
|
||||||
}
|
}
|
||||||
|
@ -157,25 +159,25 @@ private:
|
||||||
*/
|
*/
|
||||||
void resolveImports(Scope* currentScope)
|
void resolveImports(Scope* currentScope)
|
||||||
{
|
{
|
||||||
import modulecache : ModuleCache;
|
import dsymbol.modulecache : ModuleCache;
|
||||||
foreach (importInfo; currentScope.importInformation[])
|
foreach (importInfo; currentScope.importInformation[])
|
||||||
{
|
{
|
||||||
// Get symbol for the imported module
|
// Get symbol for the imported module
|
||||||
immutable string moduleAbsPath = ModuleCache.resolveImportLoctation(
|
immutable string moduleAbsPath = ModuleCache.resolveImportLoctation(
|
||||||
importInfo.modulePath);
|
importInfo.modulePath);
|
||||||
ACSymbol* symbol = moduleAbsPath is null ? null
|
DSymbol* symbol = moduleAbsPath is null ? null
|
||||||
: ModuleCache.getModuleSymbol(moduleAbsPath);
|
: ModuleCache.getModuleSymbol(moduleAbsPath);
|
||||||
if (symbol is null)
|
if (symbol is null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol);
|
DSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol);
|
||||||
|
|
||||||
// if this is a selective import
|
// if this is a selective import
|
||||||
if (importInfo.importedSymbols.length == 0)
|
if (importInfo.importedSymbols.length == 0)
|
||||||
{
|
{
|
||||||
// if this import is at module scope
|
// if this import is at module scope
|
||||||
if (importInfo.isPublic && currentScope.parent is null)
|
if (importInfo.isPublic && currentScope.parent is null)
|
||||||
rootSymbol.acSymbol.parts.insert(allocate!ACSymbol(symbolAllocator,
|
rootSymbol.acSymbol.parts.insert(allocate!DSymbol(symbolAllocator,
|
||||||
IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, symbol));
|
IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, symbol));
|
||||||
else
|
else
|
||||||
currentScope.symbols.insert(symbol.parts[]);
|
currentScope.symbols.insert(symbol.parts[]);
|
||||||
|
@ -186,8 +188,8 @@ private:
|
||||||
{
|
{
|
||||||
// Handle selective and renamed imports
|
// Handle selective and renamed imports
|
||||||
|
|
||||||
ACSymbol needle = ACSymbol(tup[1]);
|
DSymbol needle = DSymbol(tup[1]);
|
||||||
ACSymbol* sym;
|
DSymbol* sym;
|
||||||
auto r = symbol.parts.equalRange(&needle);
|
auto r = symbol.parts.equalRange(&needle);
|
||||||
if (r.empty) foreach (sy; symbol.parts[])
|
if (r.empty) foreach (sy; symbol.parts[])
|
||||||
{
|
{
|
||||||
|
@ -204,7 +206,7 @@ private:
|
||||||
continue;
|
continue;
|
||||||
if (tup[0] !is null)
|
if (tup[0] !is null)
|
||||||
{
|
{
|
||||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, tup[0],
|
DSymbol* s = allocate!DSymbol(symbolAllocator, tup[0],
|
||||||
sym.kind, sym.type);
|
sym.kind, sym.type);
|
||||||
s.parts.insert(sym.parts[]);
|
s.parts.insert(sym.parts[]);
|
||||||
s.callTip = sym.callTip;
|
s.callTip = sym.callTip;
|
|
@ -16,17 +16,19 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module conversion.third;
|
module dsymbol.conversion.third;
|
||||||
|
|
||||||
import std.d.ast;
|
import dsymbol.conversion.second;
|
||||||
import std.d.lexer;
|
import dsymbol.semantic;
|
||||||
import conversion.second;
|
import dsymbol.string_interning;
|
||||||
import semantic;
|
import dsymbol.symbol;
|
||||||
import actypes;
|
import dsymbol.scope_;
|
||||||
|
import dsymbol.builtin.names;
|
||||||
|
import dsymbol.builtin.symbols;
|
||||||
import messages;
|
import messages;
|
||||||
import std.allocator;
|
import std.allocator;
|
||||||
import string_interning;
|
import std.d.ast;
|
||||||
import stupidlog;
|
import std.d.lexer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Third pass handles the following:
|
* Third pass handles the following:
|
||||||
|
@ -73,13 +75,13 @@ public:
|
||||||
Scope* moduleScope;
|
Scope* moduleScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Symbol allocator
|
* The symbol allocator
|
||||||
*/
|
*/
|
||||||
CAllocator symbolAllocator;
|
CAllocator symbolAllocator;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
bool shouldFollowtype(const ACSymbol* t, const SemanticSymbol* currentSymbol)
|
bool shouldFollowtype(const DSymbol* t, const SemanticSymbol* currentSymbol)
|
||||||
{
|
{
|
||||||
if (t is null)
|
if (t is null)
|
||||||
return false;
|
return false;
|
||||||
|
@ -107,7 +109,7 @@ private:
|
||||||
case memberVariableName:
|
case memberVariableName:
|
||||||
case functionName:
|
case functionName:
|
||||||
case aliasName:
|
case aliasName:
|
||||||
ACSymbol* t = resolveType(currentSymbol.initializer,
|
DSymbol* t = resolveType(currentSymbol.initializer,
|
||||||
currentSymbol.type, currentSymbol.acSymbol.location);
|
currentSymbol.type, currentSymbol.acSymbol.location);
|
||||||
while (shouldFollowtype(t, currentSymbol))
|
while (shouldFollowtype(t, currentSymbol))
|
||||||
t = t.type;
|
t = t.type;
|
||||||
|
@ -155,7 +157,7 @@ private:
|
||||||
import std.algorithm : filter;
|
import std.algorithm : filter;
|
||||||
outer: foreach (istring[] base; currentSymbol.baseClasses)
|
outer: foreach (istring[] base; currentSymbol.baseClasses)
|
||||||
{
|
{
|
||||||
ACSymbol* baseClass;
|
DSymbol* baseClass;
|
||||||
if (base.length == 0)
|
if (base.length == 0)
|
||||||
continue;
|
continue;
|
||||||
auto symbolScope = moduleScope.getScopeByCursor(currentSymbol.acSymbol.location);
|
auto symbolScope = moduleScope.getScopeByCursor(currentSymbol.acSymbol.location);
|
||||||
|
@ -177,7 +179,7 @@ private:
|
||||||
a => a.name.ptr != CONSTRUCTOR_SYMBOL_NAME.ptr));
|
a => a.name.ptr != CONSTRUCTOR_SYMBOL_NAME.ptr));
|
||||||
if (baseClass.kind == CompletionKind.className)
|
if (baseClass.kind == CompletionKind.className)
|
||||||
{
|
{
|
||||||
auto s = allocate!ACSymbol(symbolAllocator,
|
auto s = allocate!DSymbol(symbolAllocator,
|
||||||
SUPER_SYMBOL_NAME, CompletionKind.variableName, baseClass);
|
SUPER_SYMBOL_NAME, CompletionKind.variableName, baseClass);
|
||||||
symbolScope.symbols.insert(s);
|
symbolScope.symbols.insert(s);
|
||||||
}
|
}
|
||||||
|
@ -191,7 +193,7 @@ private:
|
||||||
auto parts = currentSymbol.acSymbol.getPartsByName(aliasThis);
|
auto parts = currentSymbol.acSymbol.getPartsByName(aliasThis);
|
||||||
if (parts.length == 0 || parts[0].type is null)
|
if (parts.length == 0 || parts[0].type is null)
|
||||||
continue;
|
continue;
|
||||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, IMPORT_SYMBOL_NAME,
|
DSymbol* s = allocate!DSymbol(symbolAllocator, IMPORT_SYMBOL_NAME,
|
||||||
CompletionKind.importSymbol);
|
CompletionKind.importSymbol);
|
||||||
s.type = parts[0].type;
|
s.type = parts[0].type;
|
||||||
currentSymbol.acSymbol.parts.insert(s);
|
currentSymbol.acSymbol.parts.insert(s);
|
||||||
|
@ -222,7 +224,7 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ACSymbol* resolveInitializerType(I)(ref const I initializer, size_t location)
|
DSymbol* resolveInitializerType(I)(ref const I initializer, size_t location)
|
||||||
{
|
{
|
||||||
if (initializer.empty)
|
if (initializer.empty)
|
||||||
return null;
|
return null;
|
||||||
|
@ -256,7 +258,7 @@ private:
|
||||||
s = s.type;
|
s = s.type;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ACSymbol*[] f = s.getPartsByName(internString("front"));
|
DSymbol*[] f = s.getPartsByName(internString("front"));
|
||||||
if (f.length > 0)
|
if (f.length > 0)
|
||||||
s = f[0].type;
|
s = f[0].type;
|
||||||
else
|
else
|
||||||
|
@ -280,13 +282,13 @@ private:
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACSymbol* resolveType(I)(ref const I initializer, const Type t, size_t location)
|
DSymbol* resolveType(I)(ref const I initializer, const Type t, size_t location)
|
||||||
{
|
{
|
||||||
if (t is null)
|
if (t is null)
|
||||||
return resolveInitializerType(initializer, location);
|
return resolveInitializerType(initializer, location);
|
||||||
if (t.type2 is null)
|
if (t.type2 is null)
|
||||||
return null;
|
return null;
|
||||||
ACSymbol* s;
|
DSymbol* s;
|
||||||
if (t.type2.builtinType != tok!"")
|
if (t.type2.builtinType != tok!"")
|
||||||
s = convertBuiltinType(t.type2);
|
s = convertBuiltinType(t.type2);
|
||||||
else if (t.type2.typeConstructor != tok!"")
|
else if (t.type2.typeConstructor != tok!"")
|
||||||
|
@ -333,13 +335,13 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ACSymbol* processSuffix(ACSymbol* symbol, const TypeSuffix suffix, const Type t)
|
DSymbol* processSuffix(DSymbol* symbol, const TypeSuffix suffix, const Type t)
|
||||||
{
|
{
|
||||||
if (suffix.star.type != tok!"")
|
if (suffix.star.type != tok!"")
|
||||||
return symbol;
|
return symbol;
|
||||||
if (suffix.array || suffix.type)
|
if (suffix.array || suffix.type)
|
||||||
{
|
{
|
||||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, istring(null));
|
DSymbol* s = allocate!DSymbol(symbolAllocator, istring(null));
|
||||||
s.parts.insert(suffix.array ? arraySymbols[]
|
s.parts.insert(suffix.array ? arraySymbols[]
|
||||||
: assocArraySymbols[]);
|
: assocArraySymbols[]);
|
||||||
s.type = symbol;
|
s.type = symbol;
|
||||||
|
@ -348,10 +350,10 @@ private:
|
||||||
}
|
}
|
||||||
if (suffix.parameters)
|
if (suffix.parameters)
|
||||||
{
|
{
|
||||||
import conversion.first : formatNode;
|
import dsymbol.conversion.first : formatNode;
|
||||||
import memory.allocators : QuickAllocator;
|
import memory.allocators : QuickAllocator;
|
||||||
import memory.appender : Appender;
|
import memory.appender : Appender;
|
||||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, istring(null));
|
DSymbol* s = allocate!DSymbol(symbolAllocator, istring(null));
|
||||||
s.type = symbol;
|
s.type = symbol;
|
||||||
s.qualifier = SymbolQualifier.func;
|
s.qualifier = SymbolQualifier.func;
|
||||||
QuickAllocator!1024 q;
|
QuickAllocator!1024 q;
|
||||||
|
@ -364,10 +366,10 @@ private:
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
ACSymbol* convertBuiltinType(const Type2 type2)
|
DSymbol* convertBuiltinType(const Type2 type2)
|
||||||
{
|
{
|
||||||
istring stringRepresentation = getBuiltinTypeName(type2.builtinType);
|
istring stringRepresentation = getBuiltinTypeName(type2.builtinType);
|
||||||
ACSymbol s = ACSymbol(stringRepresentation);
|
DSymbol s = DSymbol(stringRepresentation);
|
||||||
assert(s.name.ptr == stringRepresentation.ptr);
|
assert(s.name.ptr == stringRepresentation.ptr);
|
||||||
return builtinSymbols.equalRange(&s).front();
|
return builtinSymbols.equalRange(&s).front();
|
||||||
}
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* This file is part of DCD, a development tool for the D programming language.
|
||||||
|
* Copyright (C) 2014 Brian Schott
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module dsymbol.import_;
|
||||||
|
|
||||||
|
import containers.unrolledlist;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
import std.typecons;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Import information
|
||||||
|
*/
|
||||||
|
struct ImportInformation
|
||||||
|
{
|
||||||
|
/// Import statement parts
|
||||||
|
UnrolledList!istring importParts;
|
||||||
|
/// module relative path
|
||||||
|
istring modulePath;
|
||||||
|
/// symbols to import from this module
|
||||||
|
UnrolledList!(Tuple!(istring, istring), false) importedSymbols;
|
||||||
|
/// true if the import is public
|
||||||
|
bool isPublic;
|
||||||
|
}
|
|
@ -16,8 +16,20 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module modulecache;
|
module dsymbol.modulecache;
|
||||||
|
|
||||||
|
import containers.dynamicarray;
|
||||||
|
import containers.hashset;
|
||||||
|
import containers.ttree;
|
||||||
|
import containers.unrolledlist;
|
||||||
|
import dsymbol.conversion.astconverter;
|
||||||
|
import dsymbol.conversion.first;
|
||||||
|
import dsymbol.conversion.second;
|
||||||
|
import dsymbol.conversion.third;
|
||||||
|
import dsymbol.scope_;
|
||||||
|
import dsymbol.semantic;
|
||||||
|
import dsymbol.symbol;
|
||||||
|
import memory.allocators;
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
import std.allocator;
|
import std.allocator;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
@ -25,27 +37,16 @@ import std.d.ast;
|
||||||
import std.datetime;
|
import std.datetime;
|
||||||
import std.d.lexer;
|
import std.d.lexer;
|
||||||
import std.d.parser;
|
import std.d.parser;
|
||||||
|
import std.experimental.logger;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.lexer;
|
import std.lexer;
|
||||||
import std.path;
|
import std.path;
|
||||||
|
|
||||||
import actypes;
|
|
||||||
import semantic;
|
|
||||||
import memory.allocators;
|
|
||||||
import containers.ttree;
|
|
||||||
import containers.hashset;
|
|
||||||
import containers.unrolledlist;
|
|
||||||
import conversion.astconverter;
|
|
||||||
import conversion.first;
|
|
||||||
import conversion.second;
|
|
||||||
import conversion.third;
|
|
||||||
import containers.dynamicarray;
|
|
||||||
import stupidlog;
|
|
||||||
import messages;
|
import messages;
|
||||||
|
|
||||||
private struct CacheEntry
|
private struct CacheEntry
|
||||||
{
|
{
|
||||||
ACSymbol* symbol;
|
DSymbol* symbol;
|
||||||
SysTime modificationTime;
|
SysTime modificationTime;
|
||||||
string path;
|
string path;
|
||||||
|
|
||||||
|
@ -81,7 +82,7 @@ bool existanceCheck(A)(A path)
|
||||||
{
|
{
|
||||||
if (path.exists())
|
if (path.exists())
|
||||||
return true;
|
return true;
|
||||||
Log.error("Cannot cache modules in ", path, " because it does not exist");
|
warning("Cannot cache modules in ", path, " because it does not exist");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,7 +106,7 @@ struct ModuleCache
|
||||||
*/
|
*/
|
||||||
static void addImportPaths(string[] paths)
|
static void addImportPaths(string[] paths)
|
||||||
{
|
{
|
||||||
import string_interning : internString;
|
import dsymbol.string_interning : internString;
|
||||||
import std.array : array;
|
import std.array : array;
|
||||||
auto newPaths = paths.filter!(a => existanceCheck(a) && !importPaths[].canFind(a)).map!(internString).array;
|
auto newPaths = paths.filter!(a => existanceCheck(a) && !importPaths[].canFind(a)).map!(internString).array;
|
||||||
importPaths.insert(newPaths);
|
importPaths.insert(newPaths);
|
||||||
|
@ -124,7 +125,7 @@ struct ModuleCache
|
||||||
/// TODO: Implement
|
/// TODO: Implement
|
||||||
static void clear()
|
static void clear()
|
||||||
{
|
{
|
||||||
Log.info("ModuleCache.clear is not yet implemented.");
|
info("ModuleCache.clear is not yet implemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -133,9 +134,9 @@ struct ModuleCache
|
||||||
* Returns:
|
* Returns:
|
||||||
* The symbols defined in the given module
|
* The symbols defined in the given module
|
||||||
*/
|
*/
|
||||||
static ACSymbol* getModuleSymbol(string location)
|
static DSymbol* getModuleSymbol(string location)
|
||||||
{
|
{
|
||||||
import string_interning : internString;
|
import dsymbol.string_interning : internString;
|
||||||
import std.stdio : File;
|
import std.stdio : File;
|
||||||
import std.typecons : scoped;
|
import std.typecons : scoped;
|
||||||
|
|
||||||
|
@ -155,7 +156,7 @@ struct ModuleCache
|
||||||
|
|
||||||
recursionGuard.insert(cachedLocation);
|
recursionGuard.insert(cachedLocation);
|
||||||
|
|
||||||
ACSymbol* symbol;
|
DSymbol* symbol;
|
||||||
File f = File(cachedLocation);
|
File f = File(cachedLocation);
|
||||||
immutable fileSize = cast(size_t) f.size;
|
immutable fileSize = cast(size_t) f.size;
|
||||||
if (fileSize == 0)
|
if (fileSize == 0)
|
|
@ -0,0 +1,196 @@
|
||||||
|
/**
|
||||||
|
* This file is part of DCD, a development tool for the D programming language.
|
||||||
|
* Copyright (C) 2014 Brian Schott
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module dsymbol.scope_;
|
||||||
|
|
||||||
|
import dsymbol.symbol;
|
||||||
|
import dsymbol.import_;
|
||||||
|
import dsymbol.builtin.names;
|
||||||
|
import containers.ttree;
|
||||||
|
import containers.unrolledlist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains symbols and supports lookup of symbols by cursor position.
|
||||||
|
*/
|
||||||
|
struct Scope
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* begin = the beginning byte index
|
||||||
|
* end = the ending byte index
|
||||||
|
*/
|
||||||
|
this (size_t begin, size_t end)
|
||||||
|
{
|
||||||
|
this.startLocation = begin;
|
||||||
|
this.endLocation = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
~this()
|
||||||
|
{
|
||||||
|
foreach (info; importInformation[])
|
||||||
|
typeid(ImportInformation).destroy(info);
|
||||||
|
foreach (child; children[])
|
||||||
|
typeid(Scope).destroy(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* cursorPosition = the cursor position in bytes
|
||||||
|
* Returns:
|
||||||
|
* the innermost scope that contains the given cursor position
|
||||||
|
*/
|
||||||
|
Scope* getScopeByCursor(size_t cursorPosition) const
|
||||||
|
{
|
||||||
|
if (cursorPosition < startLocation) return null;
|
||||||
|
if (cursorPosition > endLocation) return null;
|
||||||
|
foreach (child; children[])
|
||||||
|
{
|
||||||
|
auto childScope = child.getScopeByCursor(cursorPosition);
|
||||||
|
if (childScope !is null)
|
||||||
|
return childScope;
|
||||||
|
}
|
||||||
|
return cast(typeof(return)) &this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* cursorPosition = the cursor position in bytes
|
||||||
|
* Returns:
|
||||||
|
* all symbols in the scope containing the cursor position, as well as
|
||||||
|
* the symbols in parent scopes of that scope.
|
||||||
|
*/
|
||||||
|
DSymbol*[] getSymbolsInCursorScope(size_t cursorPosition) const
|
||||||
|
{
|
||||||
|
import std.array : array;
|
||||||
|
|
||||||
|
auto s = getScopeByCursor(cursorPosition);
|
||||||
|
if (s is null)
|
||||||
|
return [];
|
||||||
|
UnrolledList!(DSymbol*) symbols;
|
||||||
|
Scope* sc = s;
|
||||||
|
while (sc !is null)
|
||||||
|
{
|
||||||
|
foreach (item; sc.symbols[])
|
||||||
|
{
|
||||||
|
if (item.type !is null && (item.kind == CompletionKind.importSymbol
|
||||||
|
|| item.kind == CompletionKind.withSymbol))
|
||||||
|
{
|
||||||
|
foreach (i; item.type.parts[])
|
||||||
|
symbols.insert(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
symbols.insert(item);
|
||||||
|
}
|
||||||
|
sc = sc.parent;
|
||||||
|
}
|
||||||
|
return array(symbols[]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* name = the symbol name to search for
|
||||||
|
* Returns:
|
||||||
|
* all symbols in this scope or parent scopes with the given name
|
||||||
|
*/
|
||||||
|
DSymbol*[] getSymbolsByName(istring name) const
|
||||||
|
{
|
||||||
|
import std.array : array, appender;
|
||||||
|
|
||||||
|
DSymbol s = DSymbol(name);
|
||||||
|
auto er = symbols.equalRange(&s);
|
||||||
|
if (!er.empty)
|
||||||
|
return array(er);
|
||||||
|
|
||||||
|
// Check symbols from "with" statement
|
||||||
|
DSymbol ir2 = DSymbol(WITH_SYMBOL_NAME);
|
||||||
|
auto r2 = symbols.equalRange(&ir2);
|
||||||
|
if (!r2.empty)
|
||||||
|
{
|
||||||
|
auto app = appender!(DSymbol*[])();
|
||||||
|
foreach (e; r2)
|
||||||
|
{
|
||||||
|
if (e.type is null)
|
||||||
|
continue;
|
||||||
|
foreach (withSymbol; e.type.parts.equalRange(&s))
|
||||||
|
app.put(withSymbol);
|
||||||
|
}
|
||||||
|
if (app.data.length > 0)
|
||||||
|
return app.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check imported symbols
|
||||||
|
DSymbol ir = DSymbol(IMPORT_SYMBOL_NAME);
|
||||||
|
auto r = symbols.equalRange(&ir);
|
||||||
|
if (!r.empty)
|
||||||
|
{
|
||||||
|
auto app = appender!(DSymbol*[])();
|
||||||
|
foreach (e; r)
|
||||||
|
foreach (importedSymbol; e.type.parts.equalRange(&s))
|
||||||
|
app.put(importedSymbol);
|
||||||
|
if (app.data.length > 0)
|
||||||
|
return app.data;
|
||||||
|
}
|
||||||
|
if (parent is null)
|
||||||
|
return [];
|
||||||
|
return parent.getSymbolsByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* name = the symbol name to search for
|
||||||
|
* cursorPosition = the cursor position in bytes
|
||||||
|
* Returns:
|
||||||
|
* all symbols with the given name in the scope containing the cursor
|
||||||
|
* and its parent scopes
|
||||||
|
*/
|
||||||
|
DSymbol*[] getSymbolsByNameAndCursor(istring name, size_t cursorPosition) const
|
||||||
|
{
|
||||||
|
auto s = getScopeByCursor(cursorPosition);
|
||||||
|
if (s is null)
|
||||||
|
return [];
|
||||||
|
return s.getSymbolsByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an array of symbols that are present at global scope
|
||||||
|
*/
|
||||||
|
DSymbol*[] getSymbolsAtGlobalScope(istring name) const
|
||||||
|
{
|
||||||
|
if (parent !is null)
|
||||||
|
return parent.getSymbolsAtGlobalScope(name);
|
||||||
|
return getSymbolsByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Imports contained in this scope
|
||||||
|
UnrolledList!(ImportInformation*) importInformation;
|
||||||
|
|
||||||
|
/// The scope that contains this one
|
||||||
|
Scope* parent;
|
||||||
|
|
||||||
|
/// Child scopes
|
||||||
|
UnrolledList!(Scope*, false) children;
|
||||||
|
|
||||||
|
/// Start location of this scope in bytes
|
||||||
|
size_t startLocation;
|
||||||
|
|
||||||
|
/// End location of this scope in bytes
|
||||||
|
size_t endLocation;
|
||||||
|
|
||||||
|
/// Symbols contained in this scope
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) symbols;
|
||||||
|
}
|
|
@ -16,18 +16,15 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module semantic;
|
module dsymbol.semantic;
|
||||||
|
|
||||||
import messages;
|
import dsymbol.symbol;
|
||||||
import actypes;
|
|
||||||
import std.d.ast;
|
import std.d.ast;
|
||||||
import std.d.lexer;
|
import std.d.lexer;
|
||||||
import stupidlog;
|
|
||||||
import containers.unrolledlist;
|
import containers.unrolledlist;
|
||||||
import string_interning;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Intermediate form between ACSymbol and the AST classes. Stores enough
|
* Intermediate form between DSymbol and the AST classes. Stores enough
|
||||||
* information to resolve things like base classes and alias this.
|
* information to resolve things like base classes and alias this.
|
||||||
*/
|
*/
|
||||||
struct SemanticSymbol
|
struct SemanticSymbol
|
||||||
|
@ -46,7 +43,7 @@ public:
|
||||||
* symbolFile = the file name for this symbol
|
* symbolFile = the file name for this symbol
|
||||||
* location = the location of this symbol
|
* location = the location of this symbol
|
||||||
*/
|
*/
|
||||||
this(ACSymbol* acSymbol, const Type type = null)
|
this(DSymbol* acSymbol, const Type type = null)
|
||||||
{
|
{
|
||||||
this.acSymbol = acSymbol;
|
this.acSymbol = acSymbol;
|
||||||
this.type = type;
|
this.type = type;
|
||||||
|
@ -68,7 +65,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Autocompletion symbol
|
/// Autocompletion symbol
|
||||||
ACSymbol* acSymbol;
|
DSymbol* acSymbol;
|
||||||
|
|
||||||
/// Base classes
|
/// Base classes
|
||||||
UnrolledList!(istring[]) baseClasses;
|
UnrolledList!(istring[]) baseClasses;
|
||||||
|
@ -107,6 +104,7 @@ Type argumentsType;
|
||||||
|
|
||||||
static this()
|
static this()
|
||||||
{
|
{
|
||||||
|
import dsymbol.string_interning : internString;
|
||||||
import std.allocator : allocate, Mallocator;
|
import std.allocator : allocate, Mallocator;
|
||||||
// _argptr has type void*
|
// _argptr has type void*
|
||||||
argptrType = allocate!Type(Mallocator.it);
|
argptrType = allocate!Type(Mallocator.it);
|
|
@ -16,7 +16,7 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
module string_interning;
|
module dsymbol.string_interning;
|
||||||
|
|
||||||
import std.d.lexer;
|
import std.d.lexer;
|
||||||
|
|
||||||
|
@ -38,6 +38,11 @@ alias istring = InternedString;
|
||||||
//private size_t[string] dupCheck;
|
//private size_t[string] dupCheck;
|
||||||
private StringCache stringCache = void;
|
private StringCache stringCache = void;
|
||||||
|
|
||||||
|
void checkStringCache()
|
||||||
|
{
|
||||||
|
stringCache.sanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
private struct InternedString
|
private struct InternedString
|
||||||
{
|
{
|
||||||
void opAssign(T)(T other) if (is(Unqual!T == istring))
|
void opAssign(T)(T other) if (is(Unqual!T == istring))
|
|
@ -0,0 +1,56 @@
|
||||||
|
/**
|
||||||
|
* This file is part of DCD, a development tool for the D programming language.
|
||||||
|
* Copyright (C) 2014 Brian Schott
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module string_interning;
|
||||||
|
|
||||||
|
import std.d.lexer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interns the given string and returns the interned version.
|
||||||
|
*/
|
||||||
|
istring internString(string s) nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
return istring(stringCache.intern(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
static this()
|
||||||
|
{
|
||||||
|
stringCache = StringCache(StringCache.defaultBucketCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
alias istring = InternedString;
|
||||||
|
|
||||||
|
//private size_t[string] dupCheck;
|
||||||
|
private StringCache stringCache = void;
|
||||||
|
|
||||||
|
void checkStringCache()
|
||||||
|
{
|
||||||
|
stringCache.sanityCheck();
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct InternedString
|
||||||
|
{
|
||||||
|
void opAssign(T)(T other) if (is(Unqual!T == istring))
|
||||||
|
{
|
||||||
|
this.data = other.data;
|
||||||
|
}
|
||||||
|
string data;
|
||||||
|
alias data this;
|
||||||
|
private:
|
||||||
|
import std.traits : Unqual;
|
||||||
|
}
|
|
@ -0,0 +1,288 @@
|
||||||
|
/**
|
||||||
|
* This file is part of DCD, a development tool for the D programming language.
|
||||||
|
* Copyright (C) 2014 Brian Schott
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module dsymbol.symbol;
|
||||||
|
|
||||||
|
import std.algorithm;
|
||||||
|
import std.array;
|
||||||
|
import std.container;
|
||||||
|
import std.typecons;
|
||||||
|
import std.allocator;
|
||||||
|
|
||||||
|
import containers.ttree;
|
||||||
|
import containers.unrolledlist;
|
||||||
|
import containers.slist;
|
||||||
|
import std.d.lexer;
|
||||||
|
|
||||||
|
import dsymbol.builtin.names;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
public import dsymbol.string_interning : istring;
|
||||||
|
|
||||||
|
import std.range : isOutputRange;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Identifies the kind of the item in an identifier completion list
|
||||||
|
*/
|
||||||
|
enum CompletionKind : char
|
||||||
|
{
|
||||||
|
/// Invalid completion kind. This is used internally and will never
|
||||||
|
/// be returned in a completion response.
|
||||||
|
dummy = '?',
|
||||||
|
|
||||||
|
/// Import symbol. This is used internally and will never
|
||||||
|
/// be returned in a completion response.
|
||||||
|
importSymbol = '*',
|
||||||
|
|
||||||
|
/// With symbol. This is used internally and will never
|
||||||
|
/// be returned in a completion response.
|
||||||
|
withSymbol = 'w',
|
||||||
|
|
||||||
|
/// class names
|
||||||
|
className = 'c',
|
||||||
|
|
||||||
|
/// interface names
|
||||||
|
interfaceName = 'i',
|
||||||
|
|
||||||
|
/// structure names
|
||||||
|
structName = 's',
|
||||||
|
|
||||||
|
/// union name
|
||||||
|
unionName = 'u',
|
||||||
|
|
||||||
|
/// variable name
|
||||||
|
variableName = 'v',
|
||||||
|
|
||||||
|
/// member variable
|
||||||
|
memberVariableName = 'm',
|
||||||
|
|
||||||
|
/// keyword, built-in version, scope statement
|
||||||
|
keyword = 'k',
|
||||||
|
|
||||||
|
/// function or method
|
||||||
|
functionName = 'f',
|
||||||
|
|
||||||
|
/// enum name
|
||||||
|
enumName = 'g',
|
||||||
|
|
||||||
|
/// enum member
|
||||||
|
enumMember = 'e',
|
||||||
|
|
||||||
|
/// package name
|
||||||
|
packageName = 'P',
|
||||||
|
|
||||||
|
/// module name
|
||||||
|
moduleName = 'M',
|
||||||
|
|
||||||
|
/// array
|
||||||
|
array = 'a',
|
||||||
|
|
||||||
|
/// associative array
|
||||||
|
assocArray = 'A',
|
||||||
|
|
||||||
|
/// alias name
|
||||||
|
aliasName = 'l',
|
||||||
|
|
||||||
|
/// template name
|
||||||
|
templateName = 't',
|
||||||
|
|
||||||
|
/// mixin template name
|
||||||
|
mixinTemplateName = 'T'
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Any special information about a variable declaration symbol.
|
||||||
|
*/
|
||||||
|
enum SymbolQualifier : ubyte
|
||||||
|
{
|
||||||
|
/// _none
|
||||||
|
none,
|
||||||
|
/// the symbol is an array
|
||||||
|
array,
|
||||||
|
/// the symbol is a associative array
|
||||||
|
assocArray,
|
||||||
|
/// the symbol is a function or delegate pointer
|
||||||
|
func
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Autocompletion symbol
|
||||||
|
*/
|
||||||
|
struct DSymbol
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copying is disabled.
|
||||||
|
*/
|
||||||
|
@disable this();
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
@disable this(this);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* name = the symbol's name
|
||||||
|
*/
|
||||||
|
this(string name) nothrow @safe
|
||||||
|
{
|
||||||
|
this.name = name is null ? istring(null) : internString(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
this(istring name) nothrow @safe
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* name = the symbol's name
|
||||||
|
* kind = the symbol's completion kind
|
||||||
|
*/
|
||||||
|
this(string name, CompletionKind kind) nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
this.name = name is null ? istring(name) : internString(name);
|
||||||
|
this.kind = kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
this(istring name, CompletionKind kind) nothrow @safe @nogc
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.kind = kind;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Params:
|
||||||
|
* name = the symbol's name
|
||||||
|
* kind = the symbol's completion kind
|
||||||
|
* resolvedType = the resolved type of the symbol
|
||||||
|
*/
|
||||||
|
this(string name, CompletionKind kind, DSymbol* type)
|
||||||
|
{
|
||||||
|
this.name = name is null ? istring(name) : internString(name);
|
||||||
|
this.kind = kind;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// ditto
|
||||||
|
this(istring name, CompletionKind kind, DSymbol* type)
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
this.kind = kind;
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
int opCmp(ref const DSymbol other) const pure nothrow @safe
|
||||||
|
{
|
||||||
|
// Compare the pointers because the strings have been interned.
|
||||||
|
// Identical strings MUST have the same address
|
||||||
|
int r = name.ptr > other.name.ptr;
|
||||||
|
if (name.ptr < other.name.ptr)
|
||||||
|
r = -1;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool opEquals(ref const DSymbol other) const pure nothrow @safe
|
||||||
|
{
|
||||||
|
return other.name.ptr == this.name.ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t toHash() const pure nothrow @safe
|
||||||
|
{
|
||||||
|
return (cast(size_t) name.ptr) * 27_644_437;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets all parts whose name matches the given string.
|
||||||
|
*/
|
||||||
|
DSymbol*[] getPartsByName(istring name) const
|
||||||
|
{
|
||||||
|
import std.range : chain;
|
||||||
|
DSymbol s = DSymbol(name);
|
||||||
|
DSymbol p = DSymbol(IMPORT_SYMBOL_NAME);
|
||||||
|
auto app = appender!(DSymbol*[])();
|
||||||
|
foreach (part; parts.equalRange(&s))
|
||||||
|
app.put(part);
|
||||||
|
foreach (im; parts.equalRange(&p))
|
||||||
|
app.put(im.type.getPartsByName(name));
|
||||||
|
return app.data();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds all parts and parts of parts with the given name to the given output
|
||||||
|
* range.
|
||||||
|
*/
|
||||||
|
void getAllPartsNamed(OR)(string name, ref OR outputRange) const
|
||||||
|
if (isOutputRange!(OR, DSymbol*))
|
||||||
|
{
|
||||||
|
foreach (part; parts[])
|
||||||
|
{
|
||||||
|
if (part.name == name)
|
||||||
|
outputRange.put(part);
|
||||||
|
part.getAllPartsNamed(name, outputRange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSymbol's name
|
||||||
|
*/
|
||||||
|
istring name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Symbols that compose this symbol, such as enum members, class variables,
|
||||||
|
* methods, etc.
|
||||||
|
*/
|
||||||
|
TTree!(DSymbol*, true, "a < b", false) parts;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calltip to display if this is a function
|
||||||
|
*/
|
||||||
|
istring callTip;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module containing the symbol.
|
||||||
|
*/
|
||||||
|
istring symbolFile;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Documentation for the symbol.
|
||||||
|
*/
|
||||||
|
istring doc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The symbol that represents the type.
|
||||||
|
*/
|
||||||
|
DSymbol* type;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSymbol location
|
||||||
|
*/
|
||||||
|
size_t location;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The kind of symbol
|
||||||
|
*/
|
||||||
|
CompletionKind kind;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DSymbol qualifier
|
||||||
|
*/
|
||||||
|
SymbolQualifier qualifier;
|
||||||
|
}
|
|
@ -1 +1 @@
|
||||||
Subproject commit 32f6d638e38888e1bb11cf43e93fe2d11132a98f
|
Subproject commit b490677106450153a6b270a37369a40a40b34689
|
26
makefile
26
makefile
|
@ -26,10 +26,9 @@ clean:
|
||||||
rm -f *.o
|
rm -f *.o
|
||||||
rm -rf $(OBJ_DIR)
|
rm -rf $(OBJ_DIR)
|
||||||
|
|
||||||
CLIENT_SRC := src/client.d\
|
CLIENT_SRC := \
|
||||||
src/messages.d\
|
$(shell find src/common -name "*.d")\
|
||||||
src/stupidlog.d\
|
$(shell find src/client -name "*.d")\
|
||||||
src/dcd_version.d\
|
|
||||||
msgpack-d/src/msgpack.d
|
msgpack-d/src/msgpack.d
|
||||||
|
|
||||||
DMD_CLIENT_FLAGS := -Imsgpack-d/src\
|
DMD_CLIENT_FLAGS := -Imsgpack-d/src\
|
||||||
|
@ -55,20 +54,10 @@ LDC_CLIENT_FLAGS := -Imsgpack-d/src\
|
||||||
-oq\
|
-oq\
|
||||||
-of=bin/dcd-client
|
-of=bin/dcd-client
|
||||||
|
|
||||||
SERVER_SRC := src/actypes.d\
|
SERVER_SRC := \
|
||||||
src/conversion/astconverter.d\
|
$(shell find src/common -name "*.d")\
|
||||||
src/conversion/first.d\
|
$(shell find src/server -name "*.d")\
|
||||||
src/conversion/second.d\
|
$(shell find dsymbol/src -name "*.d")\
|
||||||
src/conversion/third.d\
|
|
||||||
src/autocomplete.d\
|
|
||||||
src/constants.d\
|
|
||||||
src/messages.d\
|
|
||||||
src/modulecache.d\
|
|
||||||
src/semantic.d\
|
|
||||||
src/server.d\
|
|
||||||
src/stupidlog.d\
|
|
||||||
src/string_interning.d\
|
|
||||||
src/dcd_version.d\
|
|
||||||
libdparse/src/std/d/ast.d\
|
libdparse/src/std/d/ast.d\
|
||||||
libdparse/src/std/d/entities.d\
|
libdparse/src/std/d/entities.d\
|
||||||
libdparse/src/std/d/lexer.d\
|
libdparse/src/std/d/lexer.d\
|
||||||
|
@ -93,6 +82,7 @@ SERVER_OBJS = $(SERVER_SRC:%.d=$(OBJ_DIR)/%.o)
|
||||||
DMD_SERVER_FLAGS := -Icontainers/src\
|
DMD_SERVER_FLAGS := -Icontainers/src\
|
||||||
-Imsgpack-d/src\
|
-Imsgpack-d/src\
|
||||||
-Ilibdparse/src\
|
-Ilibdparse/src\
|
||||||
|
-Idsymbol/src\
|
||||||
-J.\
|
-J.\
|
||||||
-wi\
|
-wi\
|
||||||
-O\
|
-O\
|
||||||
|
|
766
src/actypes.d
766
src/actypes.d
|
@ -1,766 +0,0 @@
|
||||||
/**
|
|
||||||
* This file is part of DCD, a development tool for the D programming language.
|
|
||||||
* Copyright (C) 2014 Brian Schott
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module actypes;
|
|
||||||
|
|
||||||
import std.algorithm;
|
|
||||||
import std.array;
|
|
||||||
import std.container;
|
|
||||||
import std.typecons;
|
|
||||||
import std.allocator;
|
|
||||||
|
|
||||||
import containers.ttree;
|
|
||||||
import containers.unrolledlist;
|
|
||||||
import containers.slist;
|
|
||||||
import std.d.lexer;
|
|
||||||
|
|
||||||
import messages;
|
|
||||||
import string_interning;
|
|
||||||
public import string_interning : istring;
|
|
||||||
|
|
||||||
import std.range : isOutputRange;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Any special information about a variable declaration symbol.
|
|
||||||
*/
|
|
||||||
enum SymbolQualifier : ubyte
|
|
||||||
{
|
|
||||||
/// _none
|
|
||||||
none,
|
|
||||||
/// the symbol is an array
|
|
||||||
array,
|
|
||||||
/// the symbol is a associative array
|
|
||||||
assocArray,
|
|
||||||
/// the symbol is a function or delegate pointer
|
|
||||||
func
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Autocompletion symbol
|
|
||||||
*/
|
|
||||||
struct ACSymbol
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copying is disabled.
|
|
||||||
*/
|
|
||||||
@disable this();
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
@disable this(this);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* name = the symbol's name
|
|
||||||
*/
|
|
||||||
this(string name) nothrow @safe
|
|
||||||
{
|
|
||||||
this.name = name is null ? istring(null) : internString(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
this(istring name) nothrow @safe
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* name = the symbol's name
|
|
||||||
* kind = the symbol's completion kind
|
|
||||||
*/
|
|
||||||
this(string name, CompletionKind kind) nothrow @safe @nogc
|
|
||||||
{
|
|
||||||
this.name = name is null ? istring(name) : internString(name);
|
|
||||||
this.kind = kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
this(istring name, CompletionKind kind) nothrow @safe @nogc
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
this.kind = kind;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* name = the symbol's name
|
|
||||||
* kind = the symbol's completion kind
|
|
||||||
* resolvedType = the resolved type of the symbol
|
|
||||||
*/
|
|
||||||
this(string name, CompletionKind kind, ACSymbol* type)
|
|
||||||
{
|
|
||||||
this.name = name is null ? istring(name) : internString(name);
|
|
||||||
this.kind = kind;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// ditto
|
|
||||||
this(istring name, CompletionKind kind, ACSymbol* type)
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
this.kind = kind;
|
|
||||||
this.type = type;
|
|
||||||
}
|
|
||||||
|
|
||||||
int opCmp(ref const ACSymbol other) const pure nothrow @safe
|
|
||||||
{
|
|
||||||
// Compare the pointers because the strings have been interned.
|
|
||||||
// Identical strings MUST have the same address
|
|
||||||
int r = name.ptr > other.name.ptr;
|
|
||||||
if (name.ptr < other.name.ptr)
|
|
||||||
r = -1;
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool opEquals(ref const ACSymbol other) const pure nothrow @safe
|
|
||||||
{
|
|
||||||
return other.name.ptr == this.name.ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t toHash() const pure nothrow @safe
|
|
||||||
{
|
|
||||||
return (cast(size_t) name.ptr) * 27_644_437;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets all parts whose name matches the given string.
|
|
||||||
*/
|
|
||||||
ACSymbol*[] getPartsByName(istring name) const
|
|
||||||
{
|
|
||||||
import std.range : chain;
|
|
||||||
ACSymbol s = ACSymbol(name);
|
|
||||||
ACSymbol p = ACSymbol(IMPORT_SYMBOL_NAME);
|
|
||||||
auto app = appender!(ACSymbol*[])();
|
|
||||||
foreach (part; parts.equalRange(&s))
|
|
||||||
app.put(part);
|
|
||||||
foreach (im; parts.equalRange(&p))
|
|
||||||
app.put(im.type.getPartsByName(name));
|
|
||||||
return app.data();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds all parts and parts of parts with the given name to the given output
|
|
||||||
* range.
|
|
||||||
*/
|
|
||||||
void getAllPartsNamed(OR)(string name, ref OR outputRange) const
|
|
||||||
if (isOutputRange!(OR, ACSymbol*))
|
|
||||||
{
|
|
||||||
foreach (part; parts[])
|
|
||||||
{
|
|
||||||
if (part.name == name)
|
|
||||||
outputRange.put(part);
|
|
||||||
part.getAllPartsNamed(name, outputRange);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Symbol's name
|
|
||||||
*/
|
|
||||||
istring name;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Symbols that compose this symbol, such as enum members, class variables,
|
|
||||||
* methods, etc.
|
|
||||||
*/
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) parts;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calltip to display if this is a function
|
|
||||||
*/
|
|
||||||
istring callTip;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module containing the symbol.
|
|
||||||
*/
|
|
||||||
istring symbolFile;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Documentation for the symbol.
|
|
||||||
*/
|
|
||||||
istring doc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The symbol that represents the type.
|
|
||||||
*/
|
|
||||||
ACSymbol* type;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Symbol location
|
|
||||||
*/
|
|
||||||
size_t location;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The kind of symbol
|
|
||||||
*/
|
|
||||||
CompletionKind kind;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Symbol qualifier
|
|
||||||
*/
|
|
||||||
SymbolQualifier qualifier;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Contains symbols and supports lookup of symbols by cursor position.
|
|
||||||
*/
|
|
||||||
struct Scope
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* begin = the beginning byte index
|
|
||||||
* end = the ending byte index
|
|
||||||
*/
|
|
||||||
this (size_t begin, size_t end)
|
|
||||||
{
|
|
||||||
this.startLocation = begin;
|
|
||||||
this.endLocation = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
~this()
|
|
||||||
{
|
|
||||||
foreach (info; importInformation[])
|
|
||||||
typeid(ImportInformation).destroy(info);
|
|
||||||
foreach (child; children[])
|
|
||||||
typeid(Scope).destroy(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* cursorPosition = the cursor position in bytes
|
|
||||||
* Returns:
|
|
||||||
* the innermost scope that contains the given cursor position
|
|
||||||
*/
|
|
||||||
Scope* getScopeByCursor(size_t cursorPosition) const
|
|
||||||
{
|
|
||||||
if (cursorPosition < startLocation) return null;
|
|
||||||
if (cursorPosition > endLocation) return null;
|
|
||||||
foreach (child; children[])
|
|
||||||
{
|
|
||||||
auto childScope = child.getScopeByCursor(cursorPosition);
|
|
||||||
if (childScope !is null)
|
|
||||||
return childScope;
|
|
||||||
}
|
|
||||||
return cast(typeof(return)) &this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* cursorPosition = the cursor position in bytes
|
|
||||||
* Returns:
|
|
||||||
* all symbols in the scope containing the cursor position, as well as
|
|
||||||
* the symbols in parent scopes of that scope.
|
|
||||||
*/
|
|
||||||
ACSymbol*[] getSymbolsInCursorScope(size_t cursorPosition) const
|
|
||||||
{
|
|
||||||
auto s = getScopeByCursor(cursorPosition);
|
|
||||||
if (s is null)
|
|
||||||
return [];
|
|
||||||
UnrolledList!(ACSymbol*) symbols;
|
|
||||||
Scope* sc = s;
|
|
||||||
while (sc !is null)
|
|
||||||
{
|
|
||||||
foreach (item; sc.symbols[])
|
|
||||||
{
|
|
||||||
if (item.type !is null && (item.kind == CompletionKind.importSymbol
|
|
||||||
|| item.kind == CompletionKind.withSymbol))
|
|
||||||
{
|
|
||||||
foreach (i; item.type.parts[])
|
|
||||||
symbols.insert(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
symbols.insert(item);
|
|
||||||
}
|
|
||||||
sc = sc.parent;
|
|
||||||
}
|
|
||||||
return array(symbols[]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* name = the symbol name to search for
|
|
||||||
* Returns:
|
|
||||||
* all symbols in this scope or parent scopes with the given name
|
|
||||||
*/
|
|
||||||
ACSymbol*[] getSymbolsByName(istring name) const
|
|
||||||
{
|
|
||||||
ACSymbol s = ACSymbol(name);
|
|
||||||
auto er = symbols.equalRange(&s);
|
|
||||||
if (!er.empty)
|
|
||||||
return array(er);
|
|
||||||
|
|
||||||
// Check symbols from "with" statement
|
|
||||||
ACSymbol ir2 = ACSymbol(WITH_SYMBOL_NAME);
|
|
||||||
auto r2 = symbols.equalRange(&ir2);
|
|
||||||
if (!r2.empty)
|
|
||||||
{
|
|
||||||
auto app = appender!(ACSymbol*[])();
|
|
||||||
foreach (e; r2)
|
|
||||||
{
|
|
||||||
if (e.type is null)
|
|
||||||
continue;
|
|
||||||
foreach (withSymbol; e.type.parts.equalRange(&s))
|
|
||||||
app.put(withSymbol);
|
|
||||||
}
|
|
||||||
if (app.data.length > 0)
|
|
||||||
return app.data;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check imported symbols
|
|
||||||
ACSymbol ir = ACSymbol(IMPORT_SYMBOL_NAME);
|
|
||||||
auto r = symbols.equalRange(&ir);
|
|
||||||
if (!r.empty)
|
|
||||||
{
|
|
||||||
auto app = appender!(ACSymbol*[])();
|
|
||||||
foreach (e; r)
|
|
||||||
foreach (importedSymbol; e.type.parts.equalRange(&s))
|
|
||||||
app.put(importedSymbol);
|
|
||||||
if (app.data.length > 0)
|
|
||||||
return app.data;
|
|
||||||
}
|
|
||||||
if (parent is null)
|
|
||||||
return [];
|
|
||||||
return parent.getSymbolsByName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Params:
|
|
||||||
* name = the symbol name to search for
|
|
||||||
* cursorPosition = the cursor position in bytes
|
|
||||||
* Returns:
|
|
||||||
* all symbols with the given name in the scope containing the cursor
|
|
||||||
* and its parent scopes
|
|
||||||
*/
|
|
||||||
ACSymbol*[] getSymbolsByNameAndCursor(istring name, size_t cursorPosition) const
|
|
||||||
{
|
|
||||||
auto s = getScopeByCursor(cursorPosition);
|
|
||||||
if (s is null)
|
|
||||||
return [];
|
|
||||||
return s.getSymbolsByName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of symbols that are present at global scope
|
|
||||||
*/
|
|
||||||
ACSymbol*[] getSymbolsAtGlobalScope(istring name) const
|
|
||||||
{
|
|
||||||
if (parent !is null)
|
|
||||||
return parent.getSymbolsAtGlobalScope(name);
|
|
||||||
return getSymbolsByName(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Imports contained in this scope
|
|
||||||
UnrolledList!(ImportInformation*) importInformation;
|
|
||||||
|
|
||||||
/// The scope that contains this one
|
|
||||||
Scope* parent;
|
|
||||||
|
|
||||||
/// Child scopes
|
|
||||||
UnrolledList!(Scope*, false) children;
|
|
||||||
|
|
||||||
/// Start location of this scope in bytes
|
|
||||||
size_t startLocation;
|
|
||||||
|
|
||||||
/// End location of this scope in bytes
|
|
||||||
size_t endLocation;
|
|
||||||
|
|
||||||
/// Symbols contained in this scope
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) symbols;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Import information
|
|
||||||
*/
|
|
||||||
struct ImportInformation
|
|
||||||
{
|
|
||||||
/// Import statement parts
|
|
||||||
UnrolledList!istring importParts;
|
|
||||||
/// module relative path
|
|
||||||
istring modulePath;
|
|
||||||
/// symbols to import from this module
|
|
||||||
UnrolledList!(Tuple!(istring, istring), false) importedSymbols;
|
|
||||||
/// true if the import is public
|
|
||||||
bool isPublic;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Symbols for the built in types
|
|
||||||
*/
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) builtinSymbols;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Array properties
|
|
||||||
*/
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) arraySymbols;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Associative array properties
|
|
||||||
*/
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) assocArraySymbols;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Struct, enum, union, class, and interface properties
|
|
||||||
*/
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) aggregateSymbols;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class properties
|
|
||||||
*/
|
|
||||||
TTree!(ACSymbol*, true, "a < b", false) classSymbols;
|
|
||||||
|
|
||||||
private immutable(istring[24]) builtinTypeNames;
|
|
||||||
|
|
||||||
/// Constants for buit-in or dummy symbol names
|
|
||||||
immutable istring IMPORT_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring WITH_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring CONSTRUCTOR_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring DESTRUCTOR_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring ARGPTR_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring ARGUMENTS_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring THIS_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring SUPER_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring UNITTEST_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring DOUBLE_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring FLOAT_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring IDOUBLE_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring IFLOAT_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring INT_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring LONG_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring REAL_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring IREAL_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring UINT_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring ULONG_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring CHAR_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring DSTRING_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring STRING_LITERAL_SYMBOL_NAME;
|
|
||||||
/// ditto
|
|
||||||
immutable istring WSTRING_LITERAL_SYMBOL_NAME;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Translates the IDs for built-in types into an interned string.
|
|
||||||
*/
|
|
||||||
istring getBuiltinTypeName(IdType id) nothrow pure @nogc @safe
|
|
||||||
{
|
|
||||||
switch (id)
|
|
||||||
{
|
|
||||||
case tok!"int": return builtinTypeNames[0];
|
|
||||||
case tok!"uint": return builtinTypeNames[1];
|
|
||||||
case tok!"double": return builtinTypeNames[2];
|
|
||||||
case tok!"idouble": return builtinTypeNames[3];
|
|
||||||
case tok!"float": return builtinTypeNames[4];
|
|
||||||
case tok!"ifloat": return builtinTypeNames[5];
|
|
||||||
case tok!"short": return builtinTypeNames[6];
|
|
||||||
case tok!"ushort": return builtinTypeNames[7];
|
|
||||||
case tok!"long": return builtinTypeNames[8];
|
|
||||||
case tok!"ulong": return builtinTypeNames[9];
|
|
||||||
case tok!"char": return builtinTypeNames[10];
|
|
||||||
case tok!"wchar": return builtinTypeNames[11];
|
|
||||||
case tok!"dchar": return builtinTypeNames[12];
|
|
||||||
case tok!"bool": return builtinTypeNames[13];
|
|
||||||
case tok!"void": return builtinTypeNames[14];
|
|
||||||
case tok!"cent": return builtinTypeNames[15];
|
|
||||||
case tok!"ucent": return builtinTypeNames[16];
|
|
||||||
case tok!"real": return builtinTypeNames[17];
|
|
||||||
case tok!"ireal": return builtinTypeNames[18];
|
|
||||||
case tok!"byte": return builtinTypeNames[19];
|
|
||||||
case tok!"ubyte": return builtinTypeNames[20];
|
|
||||||
case tok!"cdouble": return builtinTypeNames[21];
|
|
||||||
case tok!"cfloat": return builtinTypeNames[22];
|
|
||||||
case tok!"creal": return builtinTypeNames[23];
|
|
||||||
default: assert (false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes builtin types and the various properties of builtin types
|
|
||||||
*/
|
|
||||||
static this()
|
|
||||||
{
|
|
||||||
builtinTypeNames[0] = internString("int");
|
|
||||||
builtinTypeNames[1] = internString("uint");
|
|
||||||
builtinTypeNames[2] = internString("double");
|
|
||||||
builtinTypeNames[3] = internString("idouble");
|
|
||||||
builtinTypeNames[4] = internString("float");
|
|
||||||
builtinTypeNames[5] = internString("ifloat");
|
|
||||||
builtinTypeNames[6] = internString("short");
|
|
||||||
builtinTypeNames[7] = internString("ushort");
|
|
||||||
builtinTypeNames[8] = internString("long");
|
|
||||||
builtinTypeNames[9] = internString("ulong");
|
|
||||||
builtinTypeNames[10] = internString("char");
|
|
||||||
builtinTypeNames[11] = internString("wchar");
|
|
||||||
builtinTypeNames[12] = internString("dchar");
|
|
||||||
builtinTypeNames[13] = internString("bool");
|
|
||||||
builtinTypeNames[14] = internString("void");
|
|
||||||
builtinTypeNames[15] = internString("cent");
|
|
||||||
builtinTypeNames[16] = internString("ucent");
|
|
||||||
builtinTypeNames[17] = internString("real");
|
|
||||||
builtinTypeNames[18] = internString("ireal");
|
|
||||||
builtinTypeNames[19] = internString("byte");
|
|
||||||
builtinTypeNames[20] = internString("ubyte");
|
|
||||||
builtinTypeNames[21] = internString("cdouble");
|
|
||||||
builtinTypeNames[22] = internString("cfloat");
|
|
||||||
builtinTypeNames[23] = internString("creal");
|
|
||||||
|
|
||||||
IMPORT_SYMBOL_NAME = internString("public");
|
|
||||||
WITH_SYMBOL_NAME = internString("with");
|
|
||||||
CONSTRUCTOR_SYMBOL_NAME = internString("*constructor*");
|
|
||||||
DESTRUCTOR_SYMBOL_NAME = internString("~this");
|
|
||||||
ARGPTR_SYMBOL_NAME = internString("_argptr");
|
|
||||||
ARGUMENTS_SYMBOL_NAME = internString("_arguments");
|
|
||||||
THIS_SYMBOL_NAME = internString("this");
|
|
||||||
SUPER_SYMBOL_NAME = internString("super");
|
|
||||||
UNITTEST_SYMBOL_NAME = internString("*unittest*");
|
|
||||||
DOUBLE_LITERAL_SYMBOL_NAME = internString("*double");
|
|
||||||
FLOAT_LITERAL_SYMBOL_NAME = internString("*float");
|
|
||||||
IDOUBLE_LITERAL_SYMBOL_NAME = internString("*idouble");
|
|
||||||
IFLOAT_LITERAL_SYMBOL_NAME = internString("*ifloat");
|
|
||||||
INT_LITERAL_SYMBOL_NAME = internString("*int");
|
|
||||||
LONG_LITERAL_SYMBOL_NAME = internString("*long");
|
|
||||||
REAL_LITERAL_SYMBOL_NAME = internString("*real");
|
|
||||||
IREAL_LITERAL_SYMBOL_NAME = internString("*ireal");
|
|
||||||
UINT_LITERAL_SYMBOL_NAME = internString("*uint");
|
|
||||||
ULONG_LITERAL_SYMBOL_NAME = internString("*ulong");
|
|
||||||
CHAR_LITERAL_SYMBOL_NAME = internString("*char");
|
|
||||||
DSTRING_LITERAL_SYMBOL_NAME = internString("*dstring");
|
|
||||||
STRING_LITERAL_SYMBOL_NAME = internString("*string");
|
|
||||||
WSTRING_LITERAL_SYMBOL_NAME = internString("*wstring");
|
|
||||||
|
|
||||||
auto bool_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[13], CompletionKind.keyword);
|
|
||||||
auto int_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[0], CompletionKind.keyword);
|
|
||||||
auto long_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[8], CompletionKind.keyword);
|
|
||||||
auto byte_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[19], CompletionKind.keyword);
|
|
||||||
auto char_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[10], CompletionKind.keyword);
|
|
||||||
auto dchar_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[12], CompletionKind.keyword);
|
|
||||||
auto short_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[6], CompletionKind.keyword);
|
|
||||||
auto ubyte_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[20], CompletionKind.keyword);
|
|
||||||
auto uint_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[1], CompletionKind.keyword);
|
|
||||||
auto ulong_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[9], CompletionKind.keyword);
|
|
||||||
auto ushort_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[7], CompletionKind.keyword);
|
|
||||||
auto wchar_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[11], CompletionKind.keyword);
|
|
||||||
|
|
||||||
auto alignof_ = allocate!ACSymbol(Mallocator.it, internString("alignof"), CompletionKind.keyword);
|
|
||||||
auto mangleof_ = allocate!ACSymbol(Mallocator.it, internString("mangleof"), CompletionKind.keyword);
|
|
||||||
auto sizeof_ = allocate!ACSymbol(Mallocator.it, internString("sizeof"), CompletionKind.keyword);
|
|
||||||
auto stringof_ = allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword);
|
|
||||||
auto init = allocate!ACSymbol(Mallocator.it, internString("stringof"), CompletionKind.keyword);
|
|
||||||
|
|
||||||
arraySymbols.insert(alignof_);
|
|
||||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("dup"), CompletionKind.keyword));
|
|
||||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("idup"), CompletionKind.keyword));
|
|
||||||
arraySymbols.insert(init);
|
|
||||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("length"), CompletionKind.keyword, ulong_));
|
|
||||||
arraySymbols.insert(mangleof_);
|
|
||||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("ptr"), CompletionKind.keyword));
|
|
||||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("reverse"), CompletionKind.keyword));
|
|
||||||
arraySymbols.insert(sizeof_);
|
|
||||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("sort"), CompletionKind.keyword));
|
|
||||||
arraySymbols.insert(stringof_);
|
|
||||||
|
|
||||||
assocArraySymbols.insert(alignof_);
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("byKey"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("byValue"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("dup"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("get"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("keys"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("length"), CompletionKind.keyword, ulong_));
|
|
||||||
assocArraySymbols.insert(mangleof_);
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("rehash"), CompletionKind.keyword));
|
|
||||||
assocArraySymbols.insert(sizeof_);
|
|
||||||
assocArraySymbols.insert(stringof_);
|
|
||||||
assocArraySymbols.insert(init);
|
|
||||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("values"), CompletionKind.keyword));
|
|
||||||
|
|
||||||
ACSymbol*[11] integralTypeArray;
|
|
||||||
integralTypeArray[0] = bool_;
|
|
||||||
integralTypeArray[1] = int_;
|
|
||||||
integralTypeArray[2] = long_;
|
|
||||||
integralTypeArray[3] = byte_;
|
|
||||||
integralTypeArray[4] = char_;
|
|
||||||
integralTypeArray[4] = dchar_;
|
|
||||||
integralTypeArray[5] = short_;
|
|
||||||
integralTypeArray[6] = ubyte_;
|
|
||||||
integralTypeArray[7] = uint_;
|
|
||||||
integralTypeArray[8] = ulong_;
|
|
||||||
integralTypeArray[9] = ushort_;
|
|
||||||
integralTypeArray[10] = wchar_;
|
|
||||||
|
|
||||||
foreach (s; integralTypeArray)
|
|
||||||
{
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("max"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(alignof_);
|
|
||||||
s.parts.insert(sizeof_);
|
|
||||||
s.parts.insert(stringof_);
|
|
||||||
s.parts.insert(mangleof_);
|
|
||||||
s.parts.insert(init);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto cdouble_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[21], CompletionKind.keyword);
|
|
||||||
auto cent_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[15], CompletionKind.keyword);
|
|
||||||
auto cfloat_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[22], CompletionKind.keyword);
|
|
||||||
auto creal_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[23], CompletionKind.keyword);
|
|
||||||
auto double_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[2], CompletionKind.keyword);
|
|
||||||
auto float_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[4], CompletionKind.keyword);
|
|
||||||
auto idouble_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[3], CompletionKind.keyword);
|
|
||||||
auto ifloat_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[5], CompletionKind.keyword);
|
|
||||||
auto ireal_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[18], CompletionKind.keyword);
|
|
||||||
auto real_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[17], CompletionKind.keyword);
|
|
||||||
auto ucent_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[16], CompletionKind.keyword);
|
|
||||||
|
|
||||||
ACSymbol*[11] floatTypeArray;
|
|
||||||
floatTypeArray[0] = cdouble_;
|
|
||||||
floatTypeArray[1] = cent_;
|
|
||||||
floatTypeArray[2] = cfloat_;
|
|
||||||
floatTypeArray[3] = creal_;
|
|
||||||
floatTypeArray[4] = double_;
|
|
||||||
floatTypeArray[5] = float_;
|
|
||||||
floatTypeArray[6] = idouble_;
|
|
||||||
floatTypeArray[7] = ifloat_;
|
|
||||||
floatTypeArray[8] = ireal_;
|
|
||||||
floatTypeArray[9] = real_;
|
|
||||||
floatTypeArray[10] = ucent_;
|
|
||||||
|
|
||||||
foreach (s; floatTypeArray)
|
|
||||||
{
|
|
||||||
s.parts.insert(alignof_);
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("dig"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("epsilon"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("infinity"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(mangleof_);
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("mant_dig"), CompletionKind.keyword, int_));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("max"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("max_10_exp"), CompletionKind.keyword, int_));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("max_exp"), CompletionKind.keyword, int_));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min_exp"), CompletionKind.keyword, int_));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min_10_exp"), CompletionKind.keyword, int_));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min_normal"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("nan"), CompletionKind.keyword, s));
|
|
||||||
s.parts.insert(sizeof_);
|
|
||||||
s.parts.insert(stringof_);
|
|
||||||
}
|
|
||||||
|
|
||||||
aggregateSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("tupleof"), CompletionKind.keyword));
|
|
||||||
aggregateSymbols.insert(mangleof_);
|
|
||||||
aggregateSymbols.insert(alignof_);
|
|
||||||
aggregateSymbols.insert(sizeof_);
|
|
||||||
aggregateSymbols.insert(stringof_);
|
|
||||||
aggregateSymbols.insert(init);
|
|
||||||
|
|
||||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("classInfo"), CompletionKind.variableName));
|
|
||||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("tupleof"), CompletionKind.variableName));
|
|
||||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("__vptr"), CompletionKind.variableName));
|
|
||||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("__monitor"), CompletionKind.variableName));
|
|
||||||
classSymbols.insert(mangleof_);
|
|
||||||
classSymbols.insert(alignof_);
|
|
||||||
classSymbols.insert(sizeof_);
|
|
||||||
classSymbols.insert(stringof_);
|
|
||||||
classSymbols.insert(init);
|
|
||||||
|
|
||||||
ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, real_));
|
|
||||||
ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, float_));
|
|
||||||
idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, double_));
|
|
||||||
ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, real_));
|
|
||||||
ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, float_));
|
|
||||||
idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, double_));
|
|
||||||
|
|
||||||
auto void_ = allocate!ACSymbol(Mallocator.it, builtinTypeNames[14], CompletionKind.keyword);
|
|
||||||
|
|
||||||
builtinSymbols.insert(bool_);
|
|
||||||
bool_.type = bool_;
|
|
||||||
builtinSymbols.insert(int_);
|
|
||||||
int_.type = int_;
|
|
||||||
builtinSymbols.insert(long_);
|
|
||||||
long_.type = long_;
|
|
||||||
builtinSymbols.insert(byte_);
|
|
||||||
byte_.type = byte_;
|
|
||||||
builtinSymbols.insert(char_);
|
|
||||||
char_.type = char_;
|
|
||||||
builtinSymbols.insert(dchar_);
|
|
||||||
dchar_.type = dchar_;
|
|
||||||
builtinSymbols.insert(short_);
|
|
||||||
short_.type = short_;
|
|
||||||
builtinSymbols.insert(ubyte_);
|
|
||||||
ubyte_.type = ubyte_;
|
|
||||||
builtinSymbols.insert(uint_);
|
|
||||||
uint_.type = uint_;
|
|
||||||
builtinSymbols.insert(ulong_);
|
|
||||||
ulong_.type = ulong_;
|
|
||||||
builtinSymbols.insert(ushort_);
|
|
||||||
ushort_.type = ushort_;
|
|
||||||
builtinSymbols.insert(wchar_);
|
|
||||||
wchar_.type = wchar_;
|
|
||||||
builtinSymbols.insert(cdouble_);
|
|
||||||
cdouble_.type = cdouble_;
|
|
||||||
builtinSymbols.insert(cent_);
|
|
||||||
cent_.type = cent_;
|
|
||||||
builtinSymbols.insert(cfloat_);
|
|
||||||
cfloat_.type = cfloat_;
|
|
||||||
builtinSymbols.insert(creal_);
|
|
||||||
creal_.type = creal_;
|
|
||||||
builtinSymbols.insert(double_);
|
|
||||||
double_.type = double_;
|
|
||||||
builtinSymbols.insert(float_);
|
|
||||||
float_.type = float_;
|
|
||||||
builtinSymbols.insert(idouble_);
|
|
||||||
idouble_.type = idouble_;
|
|
||||||
builtinSymbols.insert(ifloat_);
|
|
||||||
ifloat_.type = ifloat_;
|
|
||||||
builtinSymbols.insert(ireal_);
|
|
||||||
ireal_.type = ireal_;
|
|
||||||
builtinSymbols.insert(real_);
|
|
||||||
real_.type = real_;
|
|
||||||
builtinSymbols.insert(ucent_);
|
|
||||||
ucent_.type = ucent_;
|
|
||||||
builtinSymbols.insert(void_);
|
|
||||||
void_.type = void_;
|
|
||||||
|
|
||||||
|
|
||||||
foreach (s; ["__DATE__", "__EOF__", "__TIME__", "__TIMESTAMP__", "__VENDOR__",
|
|
||||||
"__VERSION__", "__FUNCTION__", "__PRETTY_FUNCTION__", "__MODULE__",
|
|
||||||
"__FILE__", "__LINE__"])
|
|
||||||
builtinSymbols.insert(allocate!ACSymbol(Mallocator.it, internString(s), CompletionKind.keyword));
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,10 +28,10 @@ import std.path;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.string;
|
import std.string;
|
||||||
|
import std.experimental.logger;
|
||||||
|
|
||||||
import msgpack;
|
import msgpack;
|
||||||
import messages;
|
import messages;
|
||||||
import stupidlog;
|
|
||||||
import dcd_version;
|
import dcd_version;
|
||||||
|
|
||||||
int main(string[] args)
|
int main(string[] args)
|
||||||
|
@ -58,7 +58,7 @@ int main(string[] args)
|
||||||
}
|
}
|
||||||
catch (ConvException e)
|
catch (ConvException e)
|
||||||
{
|
{
|
||||||
Log.fatal(e.msg);
|
fatal(e.msg);
|
||||||
printHelp(args[0]);
|
printHelp(args[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
|
@ -18,75 +18,6 @@
|
||||||
|
|
||||||
module messages;
|
module messages;
|
||||||
|
|
||||||
/**
|
|
||||||
* Identifies the kind of the item in an identifier completion list
|
|
||||||
*/
|
|
||||||
enum CompletionKind : char
|
|
||||||
{
|
|
||||||
/// Invalid completion kind. This is used internally and will never
|
|
||||||
/// be returned in a completion response.
|
|
||||||
dummy = '?',
|
|
||||||
|
|
||||||
/// Import symbol. This is used internally and will never
|
|
||||||
/// be returned in a completion response.
|
|
||||||
importSymbol = '*',
|
|
||||||
|
|
||||||
/// With symbol. This is used internally and will never
|
|
||||||
/// be returned in a completion response.
|
|
||||||
withSymbol = 'w',
|
|
||||||
|
|
||||||
/// class names
|
|
||||||
className = 'c',
|
|
||||||
|
|
||||||
/// interface names
|
|
||||||
interfaceName = 'i',
|
|
||||||
|
|
||||||
/// structure names
|
|
||||||
structName = 's',
|
|
||||||
|
|
||||||
/// union name
|
|
||||||
unionName = 'u',
|
|
||||||
|
|
||||||
/// variable name
|
|
||||||
variableName = 'v',
|
|
||||||
|
|
||||||
/// member variable
|
|
||||||
memberVariableName = 'm',
|
|
||||||
|
|
||||||
/// keyword, built-in version, scope statement
|
|
||||||
keyword = 'k',
|
|
||||||
|
|
||||||
/// function or method
|
|
||||||
functionName = 'f',
|
|
||||||
|
|
||||||
/// enum name
|
|
||||||
enumName = 'g',
|
|
||||||
|
|
||||||
/// enum member
|
|
||||||
enumMember = 'e',
|
|
||||||
|
|
||||||
/// package name
|
|
||||||
packageName = 'P',
|
|
||||||
|
|
||||||
/// module name
|
|
||||||
moduleName = 'M',
|
|
||||||
|
|
||||||
/// array
|
|
||||||
array = 'a',
|
|
||||||
|
|
||||||
/// associative array
|
|
||||||
assocArray = 'A',
|
|
||||||
|
|
||||||
/// alias name
|
|
||||||
aliasName = 'l',
|
|
||||||
|
|
||||||
/// template name
|
|
||||||
templateName = 't',
|
|
||||||
|
|
||||||
/// mixin template name
|
|
||||||
mixinTemplateName = 'T'
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The type of completion list being returned
|
* The type of completion list being returned
|
||||||
*/
|
*/
|
|
@ -19,28 +19,34 @@
|
||||||
module autocomplete;
|
module autocomplete;
|
||||||
|
|
||||||
import std.algorithm;
|
import std.algorithm;
|
||||||
|
import std.allocator;
|
||||||
import std.array;
|
import std.array;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
|
import std.experimental.logger;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.path;
|
import std.path;
|
||||||
import std.range;
|
import std.range;
|
||||||
import std.stdio;
|
import std.stdio;
|
||||||
|
import std.string;
|
||||||
|
import std.typecons;
|
||||||
import std.uni;
|
import std.uni;
|
||||||
|
|
||||||
import std.d.ast;
|
import std.d.ast;
|
||||||
import std.d.lexer;
|
import std.d.lexer;
|
||||||
import std.d.parser;
|
import std.d.parser;
|
||||||
import std.string;
|
|
||||||
import std.typecons;
|
|
||||||
import memory.allocators;
|
|
||||||
import std.allocator;
|
|
||||||
|
|
||||||
import messages;
|
import dsymbol.conversion.astconverter;
|
||||||
import actypes;
|
import dsymbol.modulecache;
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
import dsymbol.symbol;
|
||||||
|
import dsymbol.scope_;
|
||||||
|
import dsymbol.builtin.names;
|
||||||
|
import dsymbol.builtin.symbols;
|
||||||
|
|
||||||
|
import memory.allocators;
|
||||||
|
|
||||||
import constants;
|
import constants;
|
||||||
import modulecache;
|
import messages;
|
||||||
import conversion.astconverter;
|
|
||||||
import stupidlog;
|
|
||||||
import string_interning;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets documentation for the symbol at the cursor
|
* Gets documentation for the symbol at the cursor
|
||||||
|
@ -51,14 +57,14 @@ import string_interning;
|
||||||
*/
|
*/
|
||||||
public AutocompleteResponse getDoc(const AutocompleteRequest request)
|
public AutocompleteResponse getDoc(const AutocompleteRequest request)
|
||||||
{
|
{
|
||||||
// Log.trace("Getting doc comments");
|
// trace("Getting doc comments");
|
||||||
AutocompleteResponse response;
|
AutocompleteResponse response;
|
||||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||||
auto cache = StringCache(StringCache.defaultBucketCount);
|
auto cache = StringCache(StringCache.defaultBucketCount);
|
||||||
ACSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc,
|
DSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc,
|
||||||
allocator, &cache);
|
allocator, &cache);
|
||||||
if (symbols.length == 0)
|
if (symbols.length == 0)
|
||||||
Log.error("Could not find symbol");
|
warning("Could not find symbol");
|
||||||
else foreach (symbol; symbols.filter!(a => !a.doc.empty))
|
else foreach (symbol; symbols.filter!(a => !a.doc.empty))
|
||||||
response.docComments ~= formatComment(symbol.doc);
|
response.docComments ~= formatComment(symbol.doc);
|
||||||
return response;
|
return response;
|
||||||
|
@ -76,7 +82,7 @@ public AutocompleteResponse findDeclaration(const AutocompleteRequest request)
|
||||||
AutocompleteResponse response;
|
AutocompleteResponse response;
|
||||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||||
auto cache = StringCache(StringCache.defaultBucketCount);
|
auto cache = StringCache(StringCache.defaultBucketCount);
|
||||||
ACSymbol*[] symbols = getSymbolsForCompletion(request,
|
DSymbol*[] symbols = getSymbolsForCompletion(request,
|
||||||
CompletionType.location, allocator, &cache);
|
CompletionType.location, allocator, &cache);
|
||||||
if (symbols.length > 0)
|
if (symbols.length > 0)
|
||||||
{
|
{
|
||||||
|
@ -84,7 +90,7 @@ public AutocompleteResponse findDeclaration(const AutocompleteRequest request)
|
||||||
response.symbolFilePath = symbols[0].symbolFile.idup;
|
response.symbolFilePath = symbols[0].symbolFile.idup;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Log.error("Could not find symbol declaration");
|
warning("Could not find symbol declaration");
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,14 +149,14 @@ public AutocompleteResponse symbolSearch(const AutocompleteRequest request)
|
||||||
|
|
||||||
static struct SearchResults
|
static struct SearchResults
|
||||||
{
|
{
|
||||||
void put(ACSymbol* symbol)
|
void put(DSymbol* symbol)
|
||||||
{
|
{
|
||||||
tree.insert(SearchResult(symbol));
|
tree.insert(SearchResult(symbol));
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct SearchResult
|
static struct SearchResult
|
||||||
{
|
{
|
||||||
ACSymbol* symbol;
|
DSymbol* symbol;
|
||||||
|
|
||||||
int opCmp(ref const SearchResult other) const pure nothrow
|
int opCmp(ref const SearchResult other) const pure nothrow
|
||||||
{
|
{
|
||||||
|
@ -322,7 +328,7 @@ auto getTokensBeforeCursor(const(ubyte[]) sourceCode, size_t cursorPosition,
|
||||||
* all symbols that should be considered for the autocomplete list based on
|
* all symbols that should be considered for the autocomplete list based on
|
||||||
* the request's source code, cursor position, and completion type.
|
* the request's source code, cursor position, and completion type.
|
||||||
*/
|
*/
|
||||||
ACSymbol*[] getSymbolsForCompletion(const AutocompleteRequest request,
|
DSymbol*[] getSymbolsForCompletion(const AutocompleteRequest request,
|
||||||
const CompletionType type, CAllocator allocator, StringCache* cache)
|
const CompletionType type, CAllocator allocator, StringCache* cache)
|
||||||
{
|
{
|
||||||
const(Token)[] tokenArray;
|
const(Token)[] tokenArray;
|
||||||
|
@ -525,7 +531,7 @@ body
|
||||||
string resolvedLocation = ModuleCache.resolveImportLoctation(path);
|
string resolvedLocation = ModuleCache.resolveImportLoctation(path);
|
||||||
if (resolvedLocation is null)
|
if (resolvedLocation is null)
|
||||||
{
|
{
|
||||||
Log.error("Could not resolve location of ", path);
|
warning("Could not resolve location of ", path);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
auto symbols = ModuleCache.getModuleSymbol(resolvedLocation);
|
auto symbols = ModuleCache.getModuleSymbol(resolvedLocation);
|
||||||
|
@ -533,9 +539,9 @@ body
|
||||||
import containers.hashset : HashSet;
|
import containers.hashset : HashSet;
|
||||||
HashSet!string h;
|
HashSet!string h;
|
||||||
|
|
||||||
void addSymbolToResponses(ACSymbol* sy)
|
void addSymbolToResponses(DSymbol* sy)
|
||||||
{
|
{
|
||||||
auto a = ACSymbol(sy.name);
|
auto a = DSymbol(sy.name);
|
||||||
if (!builtinSymbols.contains(&a) && sy.name !is null && !h.contains(sy.name)
|
if (!builtinSymbols.contains(&a) && sy.name !is null && !h.contains(sy.name)
|
||||||
&& sy.name != CONSTRUCTOR_SYMBOL_NAME)
|
&& sy.name != CONSTRUCTOR_SYMBOL_NAME)
|
||||||
{
|
{
|
||||||
|
@ -610,17 +616,17 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found)
|
if (!found)
|
||||||
Log.error("Could not find ", moduleParts);
|
warning("Could not find ", moduleParts);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
DSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
T tokens, size_t cursorPosition, CompletionType completionType)
|
T tokens, size_t cursorPosition, CompletionType completionType)
|
||||||
{
|
{
|
||||||
// Find the symbol corresponding to the beginning of the chain
|
// Find the symbol corresponding to the beginning of the chain
|
||||||
ACSymbol*[] symbols;
|
DSymbol*[] symbols;
|
||||||
if (tokens.length == 0)
|
if (tokens.length == 0)
|
||||||
return [];
|
return [];
|
||||||
if (tokens[0] == tok!"." && tokens.length > 1)
|
if (tokens[0] == tok!"." && tokens.length > 1)
|
||||||
|
@ -633,7 +639,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
|
|
||||||
if (symbols.length == 0)
|
if (symbols.length == 0)
|
||||||
{
|
{
|
||||||
Log.error("Could not find declaration of ", stringToken(tokens[0]),
|
warning("Could not find declaration of ", stringToken(tokens[0]),
|
||||||
" from position ", cursorPosition);
|
" from position ", cursorPosition);
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
@ -759,7 +765,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||||
skip();
|
skip();
|
||||||
Parser p = new Parser();
|
Parser p = new Parser();
|
||||||
p.setTokens(tokens[h .. i].array());
|
p.setTokens(tokens[h .. i].array());
|
||||||
ACSymbol*[] overloads;
|
DSymbol*[] overloads;
|
||||||
if (p.isSliceExpression())
|
if (p.isSliceExpression())
|
||||||
overloads = symbols[0].getPartsByName(internString("opSlice"));
|
overloads = symbols[0].getPartsByName(internString("opSlice"));
|
||||||
else
|
else
|
||||||
|
@ -805,7 +811,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
|
||||||
if (tokens.length == 0)
|
if (tokens.length == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ACSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens,
|
DSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens,
|
||||||
cursorPosition, completionType);
|
cursorPosition, completionType);
|
||||||
|
|
||||||
if (symbols.length == 0)
|
if (symbols.length == 0)
|
||||||
|
@ -904,7 +910,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string generateStructConstructorCalltip(const ACSymbol* symbol)
|
string generateStructConstructorCalltip(const DSymbol* symbol)
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
assert (symbol.kind == CompletionKind.structName);
|
assert (symbol.kind == CompletionKind.structName);
|
|
@ -30,16 +30,18 @@ import std.datetime;
|
||||||
import std.conv;
|
import std.conv;
|
||||||
import std.allocator;
|
import std.allocator;
|
||||||
import std.exception : enforce;
|
import std.exception : enforce;
|
||||||
|
import std.experimental.logger;
|
||||||
|
|
||||||
import core.memory;
|
import core.memory;
|
||||||
|
|
||||||
import msgpack;
|
import msgpack;
|
||||||
|
|
||||||
|
import dsymbol.string_interning;
|
||||||
|
|
||||||
import messages;
|
import messages;
|
||||||
import autocomplete;
|
import autocomplete;
|
||||||
import modulecache;
|
import dsymbol.modulecache;
|
||||||
import stupidlog;
|
import dsymbol.symbol;
|
||||||
import actypes;
|
|
||||||
import core.memory;
|
import core.memory;
|
||||||
import dcd_version;
|
import dcd_version;
|
||||||
|
|
||||||
|
@ -53,12 +55,9 @@ version(OSX) version = useXDG;
|
||||||
|
|
||||||
int main(string[] args)
|
int main(string[] args)
|
||||||
{
|
{
|
||||||
Log.info("Starting up...");
|
info("Starting up...");
|
||||||
StopWatch sw = StopWatch(AutoStart.yes);
|
StopWatch sw = StopWatch(AutoStart.yes);
|
||||||
|
|
||||||
Log.output = stdout;
|
|
||||||
Log.level = LogLevel.trace;
|
|
||||||
|
|
||||||
ushort port = 9166;
|
ushort port = 9166;
|
||||||
bool help;
|
bool help;
|
||||||
bool printVersion;
|
bool printVersion;
|
||||||
|
@ -71,7 +70,7 @@ int main(string[] args)
|
||||||
}
|
}
|
||||||
catch (ConvException e)
|
catch (ConvException e)
|
||||||
{
|
{
|
||||||
Log.fatal(e.msg);
|
fatal(e.msg);
|
||||||
printHelp(args[0]);
|
printHelp(args[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -100,21 +99,21 @@ int main(string[] args)
|
||||||
socket.listen(0);
|
socket.listen(0);
|
||||||
scope (exit)
|
scope (exit)
|
||||||
{
|
{
|
||||||
Log.info("Shutting down sockets...");
|
info("Shutting down sockets...");
|
||||||
socket.shutdown(SocketShutdown.BOTH);
|
socket.shutdown(SocketShutdown.BOTH);
|
||||||
socket.close();
|
socket.close();
|
||||||
Log.info("Sockets shut down.");
|
info("Sockets shut down.");
|
||||||
}
|
}
|
||||||
|
|
||||||
ModuleCache.addImportPaths(importPaths);
|
ModuleCache.addImportPaths(importPaths);
|
||||||
Log.info("Import directories: ", ModuleCache.getImportPaths());
|
info("Import directories: ", ModuleCache.getImportPaths());
|
||||||
|
|
||||||
ubyte[] buffer = cast(ubyte[]) Mallocator.it.allocate(1024 * 1024 * 4); // 4 megabytes should be enough for anybody...
|
ubyte[] buffer = cast(ubyte[]) Mallocator.it.allocate(1024 * 1024 * 4); // 4 megabytes should be enough for anybody...
|
||||||
scope(exit) Mallocator.it.deallocate(buffer);
|
scope(exit) Mallocator.it.deallocate(buffer);
|
||||||
|
|
||||||
sw.stop();
|
sw.stop();
|
||||||
Log.info(ModuleCache.symbolsAllocated, " symbols cached.");
|
info(ModuleCache.symbolsAllocated, " symbols cached.");
|
||||||
Log.info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds.");
|
info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds.");
|
||||||
import core.memory : GC;
|
import core.memory : GC;
|
||||||
GC.minimize();
|
GC.minimize();
|
||||||
|
|
||||||
|
@ -165,7 +164,7 @@ int main(string[] args)
|
||||||
|
|
||||||
if (bytesReceived == Socket.ERROR)
|
if (bytesReceived == Socket.ERROR)
|
||||||
{
|
{
|
||||||
Log.error("Socket recieve failed");
|
warning("Socket recieve failed");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,12 +172,12 @@ int main(string[] args)
|
||||||
msgpack.unpack(buffer[size_t.sizeof .. bytesReceived], request);
|
msgpack.unpack(buffer[size_t.sizeof .. bytesReceived], request);
|
||||||
if (request.kind & RequestKind.clearCache)
|
if (request.kind & RequestKind.clearCache)
|
||||||
{
|
{
|
||||||
Log.info("Clearing cache.");
|
info("Clearing cache.");
|
||||||
ModuleCache.clear();
|
ModuleCache.clear();
|
||||||
}
|
}
|
||||||
else if (request.kind & RequestKind.shutdown)
|
else if (request.kind & RequestKind.shutdown)
|
||||||
{
|
{
|
||||||
Log.info("Shutting down.");
|
info("Shutting down.");
|
||||||
break serverLoop;
|
break serverLoop;
|
||||||
}
|
}
|
||||||
else if (request.kind & RequestKind.query)
|
else if (request.kind & RequestKind.query)
|
||||||
|
@ -195,14 +194,14 @@ int main(string[] args)
|
||||||
}
|
}
|
||||||
if (request.kind & RequestKind.autocomplete)
|
if (request.kind & RequestKind.autocomplete)
|
||||||
{
|
{
|
||||||
Log.info("Getting completions");
|
info("Getting completions");
|
||||||
AutocompleteResponse response = complete(request);
|
AutocompleteResponse response = complete(request);
|
||||||
ubyte[] responseBytes = msgpack.pack(response);
|
ubyte[] responseBytes = msgpack.pack(response);
|
||||||
s.send(responseBytes);
|
s.send(responseBytes);
|
||||||
}
|
}
|
||||||
else if (request.kind & RequestKind.doc)
|
else if (request.kind & RequestKind.doc)
|
||||||
{
|
{
|
||||||
Log.info("Getting doc comment");
|
info("Getting doc comment");
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AutocompleteResponse response = getDoc(request);
|
AutocompleteResponse response = getDoc(request);
|
||||||
|
@ -211,7 +210,7 @@ int main(string[] args)
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.error("Could not get DDoc information", e.msg);
|
warning("Could not get DDoc information", e.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (request.kind & RequestKind.symbolLocation)
|
else if (request.kind & RequestKind.symbolLocation)
|
||||||
|
@ -224,7 +223,7 @@ int main(string[] args)
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.error("Could not get symbol location", e.msg);
|
warning("Could not get symbol location", e.msg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (request.kind & RequestKind.search)
|
else if (request.kind & RequestKind.search)
|
||||||
|
@ -233,7 +232,7 @@ int main(string[] args)
|
||||||
ubyte[] responseBytes = msgpack.pack(response);
|
ubyte[] responseBytes = msgpack.pack(response);
|
||||||
s.send(responseBytes);
|
s.send(responseBytes);
|
||||||
}
|
}
|
||||||
Log.info("Request processed in ", requestWatch.peek().to!("msecs", float), " milliseconds");
|
info("Request processed in ", requestWatch.peek().to!("msecs", float), " milliseconds");
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -283,11 +282,11 @@ void warnAboutOldConfigLocation()
|
||||||
version (linux) if ("~/.config/dcd".expandTilde().exists()
|
version (linux) if ("~/.config/dcd".expandTilde().exists()
|
||||||
&& "~/.config/dcd".expandTilde().isFile())
|
&& "~/.config/dcd".expandTilde().isFile())
|
||||||
{
|
{
|
||||||
Log.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
Log.error("!! Upgrade warning:");
|
warning("!! Upgrade warning:");
|
||||||
Log.error("!! '~/.config/dcd' should be moved to '$XDG_CONFIG_HOME/dcd/dcd.conf'");
|
warning("!! '~/.config/dcd' should be moved to '$XDG_CONFIG_HOME/dcd/dcd.conf'");
|
||||||
Log.error("!! or '$HOME/.config/dcd/dcd.conf'");
|
warning("!! or '$HOME/.config/dcd/dcd.conf'");
|
||||||
Log.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -300,7 +299,7 @@ string[] loadConfiguredImportDirs()
|
||||||
immutable string configLocation = getConfigurationLocation();
|
immutable string configLocation = getConfigurationLocation();
|
||||||
if (!configLocation.exists())
|
if (!configLocation.exists())
|
||||||
return [];
|
return [];
|
||||||
Log.info("Loading configuration from ", configLocation);
|
info("Loading configuration from ", configLocation);
|
||||||
File f = File(configLocation, "rt");
|
File f = File(configLocation, "rt");
|
||||||
return f.byLine(KeepTerminator.no)
|
return f.byLine(KeepTerminator.no)
|
||||||
.filter!(a => a.length > 0 && existanceCheck(a))
|
.filter!(a => a.length > 0 && existanceCheck(a))
|
103
src/stupidlog.d
103
src/stupidlog.d
|
@ -1,103 +0,0 @@
|
||||||
/**
|
|
||||||
* This file is part of DCD, a development tool for the D programming language.
|
|
||||||
* Copyright (C) 2014 Brian Schott
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
module stupidlog;
|
|
||||||
|
|
||||||
import std.stdio;
|
|
||||||
import core.vararg;
|
|
||||||
|
|
||||||
enum LogLevel : uint
|
|
||||||
{
|
|
||||||
fatal = 0,
|
|
||||||
error,
|
|
||||||
info,
|
|
||||||
trace
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Log
|
|
||||||
{
|
|
||||||
static void trace(T...)(T args)
|
|
||||||
{
|
|
||||||
if (level < LogLevel.trace) return;
|
|
||||||
version(Windows)
|
|
||||||
{
|
|
||||||
output.writeln("[trace] ", args);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (output is stdout)
|
|
||||||
output.writeln("[\033[01;36mtrace\033[0m] ", args);
|
|
||||||
else
|
|
||||||
output.writeln("[trace] ", args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void info(T...)(T args)
|
|
||||||
{
|
|
||||||
if (level < LogLevel.info) return;
|
|
||||||
version (Windows)
|
|
||||||
{
|
|
||||||
output.writeln("[info ] ", args);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (output is stdout)
|
|
||||||
output.writeln("[\033[01;32minfo\033[0m ] ", args);
|
|
||||||
else
|
|
||||||
output.writeln("[info ] ", args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void error(T...)(T args)
|
|
||||||
{
|
|
||||||
if (level < LogLevel.error) return;
|
|
||||||
version(Windows)
|
|
||||||
{
|
|
||||||
output.writeln("[error] ", args);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (output is stdout)
|
|
||||||
output.writeln("[\033[01;31merror\033[0m] ", args);
|
|
||||||
else
|
|
||||||
output.writeln("[error] ", args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void fatal(T...)(T args)
|
|
||||||
{
|
|
||||||
version(Windows)
|
|
||||||
{
|
|
||||||
output.writeln("[fatal] ", args);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (output is stdout)
|
|
||||||
output.writeln("[\033[01;35mfatal\033[0m] ", args);
|
|
||||||
else
|
|
||||||
output.writeln("[fatal] ", args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static LogLevel level;
|
|
||||||
static File output;
|
|
||||||
}
|
|
Loading…
Reference in New Issue