From ae83e447a48f102d6c578e78b9972ee313399137 Mon Sep 17 00:00:00 2001 From: Hackerpilot Date: Thu, 21 May 2015 17:55:20 -0700 Subject: [PATCH] Pull symbol resolution code out into dsymbol folder --- README.md | 2 +- dsymbol/src/dsymbol/builtin/names.d | 144 ++++ dsymbol/src/dsymbol/builtin/symbols.d | 235 ++++++ .../src/dsymbol}/conversion/astconverter.d | 13 +- .../src/dsymbol}/conversion/first.d | 24 +- .../src/dsymbol}/conversion/second.d | 48 +- .../src/dsymbol}/conversion/third.d | 50 +- dsymbol/src/dsymbol/import_.d | 38 + {src => dsymbol/src/dsymbol}/modulecache.d | 41 +- dsymbol/src/dsymbol/scope_.d | 196 +++++ {src => dsymbol/src/dsymbol}/semantic.d | 14 +- .../src/dsymbol}/string_interning.d | 7 +- dsymbol/src/dsymbol/string_interning.d~ | 56 ++ dsymbol/src/dsymbol/symbol.d | 288 +++++++ libdparse | 2 +- makefile | 26 +- src/actypes.d | 766 ------------------ src/{ => client}/client.d | 4 +- src/{ => common}/constants.d | 0 src/{ => common}/dcd_version.d | 0 src/{ => common}/messages.d | 69 -- src/{ => server}/autocomplete.d | 62 +- src/{ => server}/server.d | 53 +- src/stupidlog.d | 103 --- 24 files changed, 1134 insertions(+), 1107 deletions(-) create mode 100644 dsymbol/src/dsymbol/builtin/names.d create mode 100644 dsymbol/src/dsymbol/builtin/symbols.d rename {src => dsymbol/src/dsymbol}/conversion/astconverter.d (93%) rename {src => dsymbol/src/dsymbol}/conversion/first.d (98%) rename {src => dsymbol/src/dsymbol}/conversion/second.d (82%) rename {src => dsymbol/src/dsymbol}/conversion/third.d (88%) create mode 100644 dsymbol/src/dsymbol/import_.d rename {src => dsymbol/src/dsymbol}/modulecache.d (92%) create mode 100644 dsymbol/src/dsymbol/scope_.d rename {src => dsymbol/src/dsymbol}/semantic.d (93%) rename {src => dsymbol/src/dsymbol}/string_interning.d (93%) create mode 100644 dsymbol/src/dsymbol/string_interning.d~ create mode 100644 dsymbol/src/dsymbol/symbol.d delete mode 100644 src/actypes.d rename src/{ => client}/client.d (99%) rename src/{ => common}/constants.d (100%) rename src/{ => common}/dcd_version.d (100%) rename src/{ => common}/messages.d (72%) rename src/{ => server}/autocomplete.d (96%) rename src/{ => server}/server.d (84%) delete mode 100644 src/stupidlog.d diff --git a/README.md b/README.md index 43c2d27..c211217 100644 --- a/README.md +++ b/README.md @@ -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. ##### Example output calltips - ACSymbol findSymbolInCurrentScope(size_t cursorPosition, string name) + Symbol findSymbolInCurrentScope(size_t cursorPosition, string name) ## Doc comment display ```dcd-client --doc -c 4298``` diff --git a/dsymbol/src/dsymbol/builtin/names.d b/dsymbol/src/dsymbol/builtin/names.d new file mode 100644 index 0000000..1f64d5f --- /dev/null +++ b/dsymbol/src/dsymbol/builtin/names.d @@ -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"); +} diff --git a/dsymbol/src/dsymbol/builtin/symbols.d b/dsymbol/src/dsymbol/builtin/symbols.d new file mode 100644 index 0000000..ae87b35 --- /dev/null +++ b/dsymbol/src/dsymbol/builtin/symbols.d @@ -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)); +} diff --git a/src/conversion/astconverter.d b/dsymbol/src/dsymbol/conversion/astconverter.d similarity index 93% rename from src/conversion/astconverter.d rename to dsymbol/src/dsymbol/conversion/astconverter.d index 4efe0b2..e24a56f 100644 --- a/src/conversion/astconverter.d +++ b/dsymbol/src/dsymbol/conversion/astconverter.d @@ -16,19 +16,20 @@ * along with this program. If not, see . */ -module conversion.astconverter; +module dsymbol.conversion.astconverter; -import actypes; -import conversion.first; -import conversion.second; -import conversion.third; +import dsymbol.conversion.first; +import dsymbol.conversion.second; +import dsymbol.conversion.third; +import dsymbol.scope_; +import dsymbol.string_interning; +import dsymbol.symbol; import memory.allocators; import std.allocator; import std.d.ast; import std.d.lexer; import std.d.parser; import std.typecons; -import string_interning; /** * Used by autocompletion. diff --git a/src/conversion/first.d b/dsymbol/src/dsymbol/conversion/first.d similarity index 98% rename from src/conversion/first.d rename to dsymbol/src/dsymbol/conversion/first.d index cd00f48..d9cfa35 100644 --- a/src/conversion/first.d +++ b/dsymbol/src/dsymbol/conversion/first.d @@ -16,21 +16,25 @@ * along with this program. If not, see . */ -module conversion.first; +module dsymbol.conversion.first; -import actypes; -import std.d.formatter; -import std.allocator; +import containers.unrolledlist; +import dsymbol.builtin.names; +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.appender; import messages; -import semantic; +import std.allocator; import std.d.ast; +import std.d.formatter; import std.d.lexer; import std.typecons; -import stupidlog; -import containers.unrolledlist; -import string_interning; /** * First Pass handles the following: @@ -325,7 +329,7 @@ final class FirstPass : ASTVisitor Scope* s = allocate!Scope(semanticAllocator, structBody.startLocation, structBody.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); thisSymbol.location = s.startLocation; thisSymbol.symbolFile = symbolFile; @@ -705,7 +709,7 @@ private: } body { - ACSymbol* acSymbol = allocate!ACSymbol(symbolAllocator, name, kind); + DSymbol* acSymbol = allocate!DSymbol(symbolAllocator, name, kind); acSymbol.location = location; acSymbol.symbolFile = symbolFile; symbolsAllocated++; diff --git a/src/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d similarity index 82% rename from src/conversion/second.d rename to dsymbol/src/dsymbol/conversion/second.d index ef358f6..8d418f8 100644 --- a/src/conversion/second.d +++ b/dsymbol/src/dsymbol/conversion/second.d @@ -16,15 +16,17 @@ * along with this program. If not, see . */ -module conversion.second; +module dsymbol.conversion.second; -import conversion.first; -import actypes; -import semantic; -import messages; +import dsymbol.conversion.first; +import dsymbol.semantic; +import dsymbol.string_interning; +import dsymbol.symbol; +import dsymbol.scope_; +import dsymbol.import_; +import dsymbol.builtin.symbols; +import dsymbol.builtin.names; import std.allocator; -import stupidlog; -import string_interning; /** * Second pass handles the following: @@ -79,7 +81,7 @@ private: /** * Assigns symbols to scopes based on their location. */ - void assignToScopes(ACSymbol* currentSymbol) + void assignToScopes(DSymbol* currentSymbol) { if (currentSymbol.kind != CompletionKind.moduleName) { @@ -102,8 +104,8 @@ private: * Returns: A package symbol that can be used for auto-completing qualified * symbol names. */ - ACSymbol* createImportSymbols(ImportInformation* info, Scope* currentScope, - ACSymbol* moduleSymbol) + DSymbol* createImportSymbols(ImportInformation* info, Scope* currentScope, + DSymbol* moduleSymbol) in { assert (info !is null); @@ -116,14 +118,14 @@ private: immutable istring firstPart = info.importParts[].front; // top-level package symbol - ACSymbol* firstSymbol = void; - ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart); + DSymbol* firstSymbol = void; + DSymbol*[] symbols = currentScope.getSymbolsByName(firstPart); if (symbols.length > 0) firstSymbol = symbols[0]; else - firstSymbol = allocate!ACSymbol(symbolAllocator, firstPart, + firstSymbol = allocate!DSymbol(symbolAllocator, firstPart, CompletionKind.packageName); - ACSymbol* currentSymbol = firstSymbol; + DSymbol* currentSymbol = firstSymbol; size_t i = 0; 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 break; symbols = currentSymbol.getPartsByName(importPart); - ACSymbol* s = null; + DSymbol* s = null; foreach (sy; symbols) { if (sy.kind == CompletionKind.packageName) @@ -143,7 +145,7 @@ private: } } if (s is null) - s = allocate!ACSymbol(symbolAllocator, importPart, CompletionKind.packageName); + s = allocate!DSymbol(symbolAllocator, importPart, CompletionKind.packageName); currentSymbol.parts.insert(s); currentSymbol = s; } @@ -157,25 +159,25 @@ private: */ void resolveImports(Scope* currentScope) { - import modulecache : ModuleCache; + import dsymbol.modulecache : ModuleCache; foreach (importInfo; currentScope.importInformation[]) { // Get symbol for the imported module immutable string moduleAbsPath = ModuleCache.resolveImportLoctation( importInfo.modulePath); - ACSymbol* symbol = moduleAbsPath is null ? null + DSymbol* symbol = moduleAbsPath is null ? null : ModuleCache.getModuleSymbol(moduleAbsPath); if (symbol is null) continue; - ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol); + DSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol); // if this is a selective import if (importInfo.importedSymbols.length == 0) { // if this import is at module scope 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)); else currentScope.symbols.insert(symbol.parts[]); @@ -186,8 +188,8 @@ private: { // Handle selective and renamed imports - ACSymbol needle = ACSymbol(tup[1]); - ACSymbol* sym; + DSymbol needle = DSymbol(tup[1]); + DSymbol* sym; auto r = symbol.parts.equalRange(&needle); if (r.empty) foreach (sy; symbol.parts[]) { @@ -204,7 +206,7 @@ private: continue; if (tup[0] !is null) { - ACSymbol* s = allocate!ACSymbol(symbolAllocator, tup[0], + DSymbol* s = allocate!DSymbol(symbolAllocator, tup[0], sym.kind, sym.type); s.parts.insert(sym.parts[]); s.callTip = sym.callTip; diff --git a/src/conversion/third.d b/dsymbol/src/dsymbol/conversion/third.d similarity index 88% rename from src/conversion/third.d rename to dsymbol/src/dsymbol/conversion/third.d index a64c5bb..c83f37d 100644 --- a/src/conversion/third.d +++ b/dsymbol/src/dsymbol/conversion/third.d @@ -16,17 +16,19 @@ * along with this program. If not, see . */ -module conversion.third; +module dsymbol.conversion.third; -import std.d.ast; -import std.d.lexer; -import conversion.second; -import semantic; -import actypes; +import dsymbol.conversion.second; +import dsymbol.semantic; +import dsymbol.string_interning; +import dsymbol.symbol; +import dsymbol.scope_; +import dsymbol.builtin.names; +import dsymbol.builtin.symbols; import messages; import std.allocator; -import string_interning; -import stupidlog; +import std.d.ast; +import std.d.lexer; /** * Third pass handles the following: @@ -73,13 +75,13 @@ public: Scope* moduleScope; /** - * The Symbol allocator + * The symbol allocator */ CAllocator symbolAllocator; private: - bool shouldFollowtype(const ACSymbol* t, const SemanticSymbol* currentSymbol) + bool shouldFollowtype(const DSymbol* t, const SemanticSymbol* currentSymbol) { if (t is null) return false; @@ -107,7 +109,7 @@ private: case memberVariableName: case functionName: case aliasName: - ACSymbol* t = resolveType(currentSymbol.initializer, + DSymbol* t = resolveType(currentSymbol.initializer, currentSymbol.type, currentSymbol.acSymbol.location); while (shouldFollowtype(t, currentSymbol)) t = t.type; @@ -155,7 +157,7 @@ private: import std.algorithm : filter; outer: foreach (istring[] base; currentSymbol.baseClasses) { - ACSymbol* baseClass; + DSymbol* baseClass; if (base.length == 0) continue; auto symbolScope = moduleScope.getScopeByCursor(currentSymbol.acSymbol.location); @@ -177,7 +179,7 @@ private: a => a.name.ptr != CONSTRUCTOR_SYMBOL_NAME.ptr)); if (baseClass.kind == CompletionKind.className) { - auto s = allocate!ACSymbol(symbolAllocator, + auto s = allocate!DSymbol(symbolAllocator, SUPER_SYMBOL_NAME, CompletionKind.variableName, baseClass); symbolScope.symbols.insert(s); } @@ -191,7 +193,7 @@ private: auto parts = currentSymbol.acSymbol.getPartsByName(aliasThis); if (parts.length == 0 || parts[0].type is null) continue; - ACSymbol* s = allocate!ACSymbol(symbolAllocator, IMPORT_SYMBOL_NAME, + DSymbol* s = allocate!DSymbol(symbolAllocator, IMPORT_SYMBOL_NAME, CompletionKind.importSymbol); s.type = parts[0].type; 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) return null; @@ -256,7 +258,7 @@ private: s = s.type; else { - ACSymbol*[] f = s.getPartsByName(internString("front")); + DSymbol*[] f = s.getPartsByName(internString("front")); if (f.length > 0) s = f[0].type; else @@ -280,13 +282,13 @@ private: 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) return resolveInitializerType(initializer, location); if (t.type2 is null) return null; - ACSymbol* s; + DSymbol* s; if (t.type2.builtinType != tok!"") s = convertBuiltinType(t.type2); 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!"") return symbol; 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[] : assocArraySymbols[]); s.type = symbol; @@ -348,10 +350,10 @@ private: } if (suffix.parameters) { - import conversion.first : formatNode; + import dsymbol.conversion.first : formatNode; import memory.allocators : QuickAllocator; import memory.appender : Appender; - ACSymbol* s = allocate!ACSymbol(symbolAllocator, istring(null)); + DSymbol* s = allocate!DSymbol(symbolAllocator, istring(null)); s.type = symbol; s.qualifier = SymbolQualifier.func; QuickAllocator!1024 q; @@ -364,10 +366,10 @@ private: return null; } - ACSymbol* convertBuiltinType(const Type2 type2) + DSymbol* convertBuiltinType(const Type2 type2) { istring stringRepresentation = getBuiltinTypeName(type2.builtinType); - ACSymbol s = ACSymbol(stringRepresentation); + DSymbol s = DSymbol(stringRepresentation); assert(s.name.ptr == stringRepresentation.ptr); return builtinSymbols.equalRange(&s).front(); } diff --git a/dsymbol/src/dsymbol/import_.d b/dsymbol/src/dsymbol/import_.d new file mode 100644 index 0000000..4346e49 --- /dev/null +++ b/dsymbol/src/dsymbol/import_.d @@ -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 . + */ + +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; +} diff --git a/src/modulecache.d b/dsymbol/src/dsymbol/modulecache.d similarity index 92% rename from src/modulecache.d rename to dsymbol/src/dsymbol/modulecache.d index 125678b..d479322 100644 --- a/src/modulecache.d +++ b/dsymbol/src/dsymbol/modulecache.d @@ -16,8 +16,20 @@ * along with this program. If not, see . */ -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.allocator; import std.conv; @@ -25,27 +37,16 @@ import std.d.ast; import std.datetime; import std.d.lexer; import std.d.parser; +import std.experimental.logger; import std.file; import std.lexer; 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; private struct CacheEntry { - ACSymbol* symbol; + DSymbol* symbol; SysTime modificationTime; string path; @@ -81,7 +82,7 @@ bool existanceCheck(A)(A path) { if (path.exists()) 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; } @@ -105,7 +106,7 @@ struct ModuleCache */ static void addImportPaths(string[] paths) { - import string_interning : internString; + import dsymbol.string_interning : internString; import std.array : array; auto newPaths = paths.filter!(a => existanceCheck(a) && !importPaths[].canFind(a)).map!(internString).array; importPaths.insert(newPaths); @@ -124,7 +125,7 @@ struct ModuleCache /// TODO: Implement 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: * 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.typecons : scoped; @@ -155,7 +156,7 @@ struct ModuleCache recursionGuard.insert(cachedLocation); - ACSymbol* symbol; + DSymbol* symbol; File f = File(cachedLocation); immutable fileSize = cast(size_t) f.size; if (fileSize == 0) diff --git a/dsymbol/src/dsymbol/scope_.d b/dsymbol/src/dsymbol/scope_.d new file mode 100644 index 0000000..f27758d --- /dev/null +++ b/dsymbol/src/dsymbol/scope_.d @@ -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 . + */ + +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; +} diff --git a/src/semantic.d b/dsymbol/src/dsymbol/semantic.d similarity index 93% rename from src/semantic.d rename to dsymbol/src/dsymbol/semantic.d index 181d5c2..2a01fce 100644 --- a/src/semantic.d +++ b/dsymbol/src/dsymbol/semantic.d @@ -16,18 +16,15 @@ * along with this program. If not, see . */ -module semantic; +module dsymbol.semantic; -import messages; -import actypes; +import dsymbol.symbol; import std.d.ast; import std.d.lexer; -import stupidlog; 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. */ struct SemanticSymbol @@ -46,7 +43,7 @@ public: * symbolFile = the file name for 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.type = type; @@ -68,7 +65,7 @@ public: } /// Autocompletion symbol - ACSymbol* acSymbol; + DSymbol* acSymbol; /// Base classes UnrolledList!(istring[]) baseClasses; @@ -107,6 +104,7 @@ Type argumentsType; static this() { + import dsymbol.string_interning : internString; import std.allocator : allocate, Mallocator; // _argptr has type void* argptrType = allocate!Type(Mallocator.it); diff --git a/src/string_interning.d b/dsymbol/src/dsymbol/string_interning.d similarity index 93% rename from src/string_interning.d rename to dsymbol/src/dsymbol/string_interning.d index a39c620..c620fee 100644 --- a/src/string_interning.d +++ b/dsymbol/src/dsymbol/string_interning.d @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -module string_interning; +module dsymbol.string_interning; import std.d.lexer; @@ -38,6 +38,11 @@ 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)) diff --git a/dsymbol/src/dsymbol/string_interning.d~ b/dsymbol/src/dsymbol/string_interning.d~ new file mode 100644 index 0000000..00fbae3 --- /dev/null +++ b/dsymbol/src/dsymbol/string_interning.d~ @@ -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 . + */ + +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; +} diff --git a/dsymbol/src/dsymbol/symbol.d b/dsymbol/src/dsymbol/symbol.d new file mode 100644 index 0000000..ca46e95 --- /dev/null +++ b/dsymbol/src/dsymbol/symbol.d @@ -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 . + */ + +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; +} diff --git a/libdparse b/libdparse index 32f6d63..b490677 160000 --- a/libdparse +++ b/libdparse @@ -1 +1 @@ -Subproject commit 32f6d638e38888e1bb11cf43e93fe2d11132a98f +Subproject commit b490677106450153a6b270a37369a40a40b34689 diff --git a/makefile b/makefile index bbb3cb3..67f229f 100644 --- a/makefile +++ b/makefile @@ -26,10 +26,9 @@ clean: rm -f *.o rm -rf $(OBJ_DIR) -CLIENT_SRC := src/client.d\ - src/messages.d\ - src/stupidlog.d\ - src/dcd_version.d\ +CLIENT_SRC := \ + $(shell find src/common -name "*.d")\ + $(shell find src/client -name "*.d")\ msgpack-d/src/msgpack.d DMD_CLIENT_FLAGS := -Imsgpack-d/src\ @@ -55,20 +54,10 @@ LDC_CLIENT_FLAGS := -Imsgpack-d/src\ -oq\ -of=bin/dcd-client -SERVER_SRC := src/actypes.d\ - src/conversion/astconverter.d\ - src/conversion/first.d\ - src/conversion/second.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\ +SERVER_SRC := \ + $(shell find src/common -name "*.d")\ + $(shell find src/server -name "*.d")\ + $(shell find dsymbol/src -name "*.d")\ libdparse/src/std/d/ast.d\ libdparse/src/std/d/entities.d\ libdparse/src/std/d/lexer.d\ @@ -93,6 +82,7 @@ SERVER_OBJS = $(SERVER_SRC:%.d=$(OBJ_DIR)/%.o) DMD_SERVER_FLAGS := -Icontainers/src\ -Imsgpack-d/src\ -Ilibdparse/src\ + -Idsymbol/src\ -J.\ -wi\ -O\ diff --git a/src/actypes.d b/src/actypes.d deleted file mode 100644 index 410f7cd..0000000 --- a/src/actypes.d +++ /dev/null @@ -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 . - */ - -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)); -} - diff --git a/src/client.d b/src/client/client.d similarity index 99% rename from src/client.d rename to src/client/client.d index 7e4fa47..aea6570 100644 --- a/src/client.d +++ b/src/client/client.d @@ -28,10 +28,10 @@ import std.path; import std.file; import std.conv; import std.string; +import std.experimental.logger; import msgpack; import messages; -import stupidlog; import dcd_version; int main(string[] args) @@ -58,7 +58,7 @@ int main(string[] args) } catch (ConvException e) { - Log.fatal(e.msg); + fatal(e.msg); printHelp(args[0]); return 1; } diff --git a/src/constants.d b/src/common/constants.d similarity index 100% rename from src/constants.d rename to src/common/constants.d diff --git a/src/dcd_version.d b/src/common/dcd_version.d similarity index 100% rename from src/dcd_version.d rename to src/common/dcd_version.d diff --git a/src/messages.d b/src/common/messages.d similarity index 72% rename from src/messages.d rename to src/common/messages.d index 8f1db4d..88c352b 100644 --- a/src/messages.d +++ b/src/common/messages.d @@ -18,75 +18,6 @@ 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 */ diff --git a/src/autocomplete.d b/src/server/autocomplete.d similarity index 96% rename from src/autocomplete.d rename to src/server/autocomplete.d index d0e4941..82c8435 100644 --- a/src/autocomplete.d +++ b/src/server/autocomplete.d @@ -19,28 +19,34 @@ module autocomplete; import std.algorithm; +import std.allocator; import std.array; import std.conv; +import std.experimental.logger; import std.file; import std.path; import std.range; import std.stdio; +import std.string; +import std.typecons; import std.uni; + import std.d.ast; import std.d.lexer; import std.d.parser; -import std.string; -import std.typecons; -import memory.allocators; -import std.allocator; -import messages; -import actypes; +import dsymbol.conversion.astconverter; +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 modulecache; -import conversion.astconverter; -import stupidlog; -import string_interning; +import messages; /** * Gets documentation for the symbol at the cursor @@ -51,14 +57,14 @@ import string_interning; */ public AutocompleteResponse getDoc(const AutocompleteRequest request) { -// Log.trace("Getting doc comments"); +// trace("Getting doc comments"); AutocompleteResponse response; auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))(); auto cache = StringCache(StringCache.defaultBucketCount); - ACSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc, + DSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc, allocator, &cache); if (symbols.length == 0) - Log.error("Could not find symbol"); + warning("Could not find symbol"); else foreach (symbol; symbols.filter!(a => !a.doc.empty)) response.docComments ~= formatComment(symbol.doc); return response; @@ -76,7 +82,7 @@ public AutocompleteResponse findDeclaration(const AutocompleteRequest request) AutocompleteResponse response; auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))(); auto cache = StringCache(StringCache.defaultBucketCount); - ACSymbol*[] symbols = getSymbolsForCompletion(request, + DSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.location, allocator, &cache); if (symbols.length > 0) { @@ -84,7 +90,7 @@ public AutocompleteResponse findDeclaration(const AutocompleteRequest request) response.symbolFilePath = symbols[0].symbolFile.idup; } else - Log.error("Could not find symbol declaration"); + warning("Could not find symbol declaration"); return response; } @@ -143,14 +149,14 @@ public AutocompleteResponse symbolSearch(const AutocompleteRequest request) static struct SearchResults { - void put(ACSymbol* symbol) + void put(DSymbol* symbol) { tree.insert(SearchResult(symbol)); } static struct SearchResult { - ACSymbol* symbol; + DSymbol* symbol; 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 * 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(Token)[] tokenArray; @@ -525,7 +531,7 @@ body string resolvedLocation = ModuleCache.resolveImportLoctation(path); if (resolvedLocation is null) { - Log.error("Could not resolve location of ", path); + warning("Could not resolve location of ", path); return response; } auto symbols = ModuleCache.getModuleSymbol(resolvedLocation); @@ -533,9 +539,9 @@ body import containers.hashset : HashSet; 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) && sy.name != CONSTRUCTOR_SYMBOL_NAME) { @@ -610,17 +616,17 @@ void setImportCompletions(T)(T tokens, ref AutocompleteResponse response) } } 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) { // Find the symbol corresponding to the beginning of the chain - ACSymbol*[] symbols; + DSymbol*[] symbols; if (tokens.length == 0) return []; if (tokens[0] == tok!"." && tokens.length > 1) @@ -633,7 +639,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope, 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); return []; } @@ -759,7 +765,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope, skip(); Parser p = new Parser(); p.setTokens(tokens[h .. i].array()); - ACSymbol*[] overloads; + DSymbol*[] overloads; if (p.isSliceExpression()) overloads = symbols[0].getPartsByName(internString("opSlice")); else @@ -805,7 +811,7 @@ void setCompletions(T)(ref AutocompleteResponse response, if (tokens.length == 0) return; - ACSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens, + DSymbol*[] symbols = getSymbolsByTokenChain(completionScope, tokens, cursorPosition, completionType); 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 { assert (symbol.kind == CompletionKind.structName); diff --git a/src/server.d b/src/server/server.d similarity index 84% rename from src/server.d rename to src/server/server.d index 96ddc02..65251f4 100644 --- a/src/server.d +++ b/src/server/server.d @@ -30,16 +30,18 @@ import std.datetime; import std.conv; import std.allocator; import std.exception : enforce; +import std.experimental.logger; import core.memory; import msgpack; +import dsymbol.string_interning; + import messages; import autocomplete; -import modulecache; -import stupidlog; -import actypes; +import dsymbol.modulecache; +import dsymbol.symbol; import core.memory; import dcd_version; @@ -53,12 +55,9 @@ version(OSX) version = useXDG; int main(string[] args) { - Log.info("Starting up..."); + info("Starting up..."); StopWatch sw = StopWatch(AutoStart.yes); - Log.output = stdout; - Log.level = LogLevel.trace; - ushort port = 9166; bool help; bool printVersion; @@ -71,7 +70,7 @@ int main(string[] args) } catch (ConvException e) { - Log.fatal(e.msg); + fatal(e.msg); printHelp(args[0]); return 1; } @@ -100,21 +99,21 @@ int main(string[] args) socket.listen(0); scope (exit) { - Log.info("Shutting down sockets..."); + info("Shutting down sockets..."); socket.shutdown(SocketShutdown.BOTH); socket.close(); - Log.info("Sockets shut down."); + info("Sockets shut down."); } 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... scope(exit) Mallocator.it.deallocate(buffer); sw.stop(); - Log.info(ModuleCache.symbolsAllocated, " symbols cached."); - Log.info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds."); + info(ModuleCache.symbolsAllocated, " symbols cached."); + info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds."); import core.memory : GC; GC.minimize(); @@ -165,7 +164,7 @@ int main(string[] args) if (bytesReceived == Socket.ERROR) { - Log.error("Socket recieve failed"); + warning("Socket recieve failed"); break; } @@ -173,12 +172,12 @@ int main(string[] args) msgpack.unpack(buffer[size_t.sizeof .. bytesReceived], request); if (request.kind & RequestKind.clearCache) { - Log.info("Clearing cache."); + info("Clearing cache."); ModuleCache.clear(); } else if (request.kind & RequestKind.shutdown) { - Log.info("Shutting down."); + info("Shutting down."); break serverLoop; } else if (request.kind & RequestKind.query) @@ -195,14 +194,14 @@ int main(string[] args) } if (request.kind & RequestKind.autocomplete) { - Log.info("Getting completions"); + info("Getting completions"); AutocompleteResponse response = complete(request); ubyte[] responseBytes = msgpack.pack(response); s.send(responseBytes); } else if (request.kind & RequestKind.doc) { - Log.info("Getting doc comment"); + info("Getting doc comment"); try { AutocompleteResponse response = getDoc(request); @@ -211,7 +210,7 @@ int main(string[] args) } 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) @@ -224,7 +223,7 @@ int main(string[] args) } 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) @@ -233,7 +232,7 @@ int main(string[] args) ubyte[] responseBytes = msgpack.pack(response); 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; } @@ -283,11 +282,11 @@ void warnAboutOldConfigLocation() version (linux) if ("~/.config/dcd".expandTilde().exists() && "~/.config/dcd".expandTilde().isFile()) { - Log.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); - Log.error("!! Upgrade warning:"); - Log.error("!! '~/.config/dcd' should be moved to '$XDG_CONFIG_HOME/dcd/dcd.conf'"); - Log.error("!! or '$HOME/.config/dcd/dcd.conf'"); - Log.error("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); + warning("!! Upgrade warning:"); + warning("!! '~/.config/dcd' should be moved to '$XDG_CONFIG_HOME/dcd/dcd.conf'"); + warning("!! or '$HOME/.config/dcd/dcd.conf'"); + warning("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } } @@ -300,7 +299,7 @@ string[] loadConfiguredImportDirs() immutable string configLocation = getConfigurationLocation(); if (!configLocation.exists()) return []; - Log.info("Loading configuration from ", configLocation); + info("Loading configuration from ", configLocation); File f = File(configLocation, "rt"); return f.byLine(KeepTerminator.no) .filter!(a => a.length > 0 && existanceCheck(a)) diff --git a/src/stupidlog.d b/src/stupidlog.d deleted file mode 100644 index 49de3f6..0000000 --- a/src/stupidlog.d +++ /dev/null @@ -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 . - */ - -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; -}