Switch over to allocators from GC, dropping the memory usage by 70%
This commit is contained in:
parent
9e0ee133b5
commit
970310702d
338
actypes.d
338
actypes.d
|
|
@ -23,19 +23,15 @@ import std.array;
|
|||
import std.container;
|
||||
import std.stdio;
|
||||
import std.typecons;
|
||||
import std.allocator;
|
||||
|
||||
import stdx.d.lexer;
|
||||
import containers.karytree;
|
||||
import containers.unrolledlist;
|
||||
import containers.slist;
|
||||
import std.d.lexer;
|
||||
|
||||
import messages;
|
||||
|
||||
/**
|
||||
* Compares symbols by their name
|
||||
*/
|
||||
bool comparitor(const(ACSymbol)* a, const(ACSymbol)* b) pure nothrow
|
||||
{
|
||||
return a.name < b.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Any special information about a variable declaration symbol.
|
||||
*/
|
||||
|
|
@ -67,7 +63,6 @@ public:
|
|||
this(string name)
|
||||
{
|
||||
this.name = name;
|
||||
this.parts = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -79,7 +74,6 @@ public:
|
|||
{
|
||||
this.name = name;
|
||||
this.kind = kind;
|
||||
this.parts = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -93,7 +87,15 @@ public:
|
|||
this.name = name;
|
||||
this.kind = kind;
|
||||
this.type = type;
|
||||
this.parts = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
}
|
||||
|
||||
int opCmp(ref const ACSymbol other) const
|
||||
{
|
||||
if (name < other.name)
|
||||
return -1;
|
||||
if (name > other.name)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -101,16 +103,15 @@ public:
|
|||
*/
|
||||
ACSymbol*[] getPartsByName(string name)
|
||||
{
|
||||
import std.range;
|
||||
ACSymbol s = ACSymbol(name);
|
||||
return parts.equalRange(&s).array();
|
||||
return array(parts.equalRange(&s));
|
||||
}
|
||||
|
||||
/**
|
||||
* Symbols that compose this symbol, such as enum members, class variables,
|
||||
* methods, etc.
|
||||
*/
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) parts;
|
||||
KAryTree!(ACSymbol*, true, "a < b", false) parts;
|
||||
|
||||
/**
|
||||
* Symbol's name
|
||||
|
|
@ -167,7 +168,14 @@ struct Scope
|
|||
{
|
||||
this.startLocation = begin;
|
||||
this.endLocation = end;
|
||||
this.symbols = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
foreach (info; importInformation[])
|
||||
typeid(ImportInformation).destroy(info);
|
||||
foreach (child; children[])
|
||||
typeid(Scope).destroy(child);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -176,11 +184,11 @@ struct Scope
|
|||
* Returns:
|
||||
* the innermost scope that contains the given cursor position
|
||||
*/
|
||||
Scope* getScopeByCursor(size_t cursorPosition) const
|
||||
Scope* getScopeByCursor(size_t cursorPosition)
|
||||
{
|
||||
if (cursorPosition < startLocation) return null;
|
||||
if (cursorPosition > endLocation) return null;
|
||||
foreach (child; children)
|
||||
foreach (child; children[])
|
||||
{
|
||||
auto childScope = child.getScopeByCursor(cursorPosition);
|
||||
if (childScope !is null)
|
||||
|
|
@ -196,20 +204,20 @@ struct Scope
|
|||
* 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
|
||||
ACSymbol*[] getSymbolsInCursorScope(size_t cursorPosition)
|
||||
{
|
||||
auto s = getScopeByCursor(cursorPosition);
|
||||
if (s is null)
|
||||
return [];
|
||||
auto symbols = s.symbols;
|
||||
UnrolledList!(ACSymbol*) symbols;
|
||||
symbols.insert(s.symbols[]);
|
||||
Scope* sc = s.parent;
|
||||
while (sc !is null)
|
||||
{
|
||||
foreach (sym; sc.symbols)
|
||||
symbols.insert(sym);
|
||||
symbols.insert(sc.symbols[]);
|
||||
sc = sc.parent;
|
||||
}
|
||||
return symbols.array();
|
||||
return array(symbols[]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -218,12 +226,16 @@ struct Scope
|
|||
* Returns:
|
||||
* all symbols in this scope or parent scopes with the given name
|
||||
*/
|
||||
ACSymbol*[] getSymbolsByName(string name) const
|
||||
ACSymbol*[] getSymbolsByName(string name)
|
||||
{
|
||||
import std.range;
|
||||
ACSymbol s = ACSymbol(name);
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) t = cast() symbols;
|
||||
auto r = t.equalRange(&s).array();
|
||||
auto r = array(symbols.equalRange(&s));
|
||||
foreach (i; r)
|
||||
{
|
||||
import std.string;
|
||||
assert (i.name == name, format("%s %s %d", i.name, name, r.length));
|
||||
}
|
||||
if (r.length > 0)
|
||||
return cast(typeof(return)) r;
|
||||
if (parent is null)
|
||||
|
|
@ -239,7 +251,7 @@ struct Scope
|
|||
* all symbols with the given name in the scope containing the cursor
|
||||
* and its parent scopes
|
||||
*/
|
||||
ACSymbol*[] getSymbolsByNameAndCursor(string name, size_t cursorPosition) const
|
||||
ACSymbol*[] getSymbolsByNameAndCursor(string name, size_t cursorPosition)
|
||||
{
|
||||
auto s = getScopeByCursor(cursorPosition);
|
||||
if (s is null)
|
||||
|
|
@ -248,13 +260,13 @@ struct Scope
|
|||
}
|
||||
|
||||
/// Imports contained in this scope
|
||||
ImportInformation[] importInformation;
|
||||
UnrolledList!(ImportInformation*) importInformation;
|
||||
|
||||
/// The scope that contains this one
|
||||
Scope* parent;
|
||||
|
||||
/// Child scopes
|
||||
Scope*[] children;
|
||||
UnrolledList!(Scope*, false) children;
|
||||
|
||||
/// Start location of this scope in bytes
|
||||
size_t startLocation;
|
||||
|
|
@ -263,7 +275,7 @@ struct Scope
|
|||
size_t endLocation;
|
||||
|
||||
/// Symbols contained in this scope
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) symbols;
|
||||
KAryTree!(ACSymbol*, true, "a < b", false) symbols;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -272,11 +284,11 @@ struct Scope
|
|||
struct ImportInformation
|
||||
{
|
||||
/// Import statement parts
|
||||
string[] importParts;
|
||||
UnrolledList!string importParts;
|
||||
/// module relative path
|
||||
string modulePath;
|
||||
/// symbols to import from this module
|
||||
Tuple!(string, string)[] importedSymbols;
|
||||
UnrolledList!(Tuple!(string, string), false) importedSymbols;
|
||||
/// true if the import is public
|
||||
bool isPublic;
|
||||
}
|
||||
|
|
@ -285,91 +297,98 @@ struct ImportInformation
|
|||
/**
|
||||
* Symbols for the built in types
|
||||
*/
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) builtinSymbols;
|
||||
KAryTree!(ACSymbol*, true) builtinSymbols;
|
||||
|
||||
/**
|
||||
* Array properties
|
||||
*/
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) arraySymbols;
|
||||
KAryTree!(ACSymbol*, true) arraySymbols;
|
||||
|
||||
/**
|
||||
* Associative array properties
|
||||
*/
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) assocArraySymbols;
|
||||
KAryTree!(ACSymbol*, true) assocArraySymbols;
|
||||
|
||||
/**
|
||||
* Enum, union, class, and interface properties
|
||||
*/
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) aggregateSymbols;
|
||||
KAryTree!(ACSymbol*, true) aggregateSymbols;
|
||||
|
||||
/**
|
||||
* Class properties
|
||||
*/
|
||||
RedBlackTree!(ACSymbol*, comparitor, true) classSymbols;
|
||||
KAryTree!(ACSymbol*, true) classSymbols;
|
||||
|
||||
/**
|
||||
* Initializes builtin types and the various properties of builtin types
|
||||
*/
|
||||
static this()
|
||||
{
|
||||
auto bSym = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
auto arrSym = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
auto asarrSym = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
auto aggSym = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
auto clSym = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
auto bool_ = allocate!ACSymbol(Mallocator.it, "bool", CompletionKind.keyword);
|
||||
auto int_ = allocate!ACSymbol(Mallocator.it, "int", CompletionKind.keyword);
|
||||
auto long_ = allocate!ACSymbol(Mallocator.it, "long", CompletionKind.keyword);
|
||||
auto byte_ = allocate!ACSymbol(Mallocator.it, "byte", CompletionKind.keyword);
|
||||
auto char_ = allocate!ACSymbol(Mallocator.it, "char", CompletionKind.keyword);
|
||||
auto dchar_ = allocate!ACSymbol(Mallocator.it, "dchar", CompletionKind.keyword);
|
||||
auto short_ = allocate!ACSymbol(Mallocator.it, "short", CompletionKind.keyword);
|
||||
auto ubyte_ = allocate!ACSymbol(Mallocator.it, "ubyte", CompletionKind.keyword);
|
||||
auto uint_ = allocate!ACSymbol(Mallocator.it, "uint", CompletionKind.keyword);
|
||||
auto ulong_ = allocate!ACSymbol(Mallocator.it, "ulong", CompletionKind.keyword);
|
||||
auto ushort_ = allocate!ACSymbol(Mallocator.it, "ushort", CompletionKind.keyword);
|
||||
auto wchar_ = allocate!ACSymbol(Mallocator.it, "wchar", CompletionKind.keyword);
|
||||
|
||||
auto bool_ = new ACSymbol("bool", CompletionKind.keyword);
|
||||
auto int_ = new ACSymbol("int", CompletionKind.keyword);
|
||||
auto long_ = new ACSymbol("long", CompletionKind.keyword);
|
||||
auto byte_ = new ACSymbol("byte", CompletionKind.keyword);
|
||||
auto char_ = new ACSymbol("char", CompletionKind.keyword);
|
||||
auto dchar_ = new ACSymbol("dchar", CompletionKind.keyword);
|
||||
auto short_ = new ACSymbol("short", CompletionKind.keyword);
|
||||
auto ubyte_ = new ACSymbol("ubyte", CompletionKind.keyword);
|
||||
auto uint_ = new ACSymbol("uint", CompletionKind.keyword);
|
||||
auto ulong_ = new ACSymbol("ulong", CompletionKind.keyword);
|
||||
auto ushort_ = new ACSymbol("ushort", CompletionKind.keyword);
|
||||
auto wchar_ = new ACSymbol("wchar", CompletionKind.keyword);
|
||||
auto alignof_ = allocate!ACSymbol(Mallocator.it, "alignof", CompletionKind.keyword);
|
||||
auto mangleof_ = allocate!ACSymbol(Mallocator.it, "mangleof", CompletionKind.keyword);
|
||||
auto sizeof_ = allocate!ACSymbol(Mallocator.it, "sizeof", CompletionKind.keyword);
|
||||
auto stringof_ = allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword);
|
||||
auto init = allocate!ACSymbol(Mallocator.it, "stringof", CompletionKind.keyword);
|
||||
|
||||
auto alignof_ = new ACSymbol("alignof", CompletionKind.keyword, ulong_);
|
||||
auto mangleof_ = new ACSymbol("mangleof", CompletionKind.keyword);
|
||||
auto sizeof_ = new ACSymbol("sizeof", CompletionKind.keyword, ulong_);
|
||||
auto stringof_ = new ACSymbol("init", CompletionKind.keyword);
|
||||
auto init = new ACSymbol("stringof", CompletionKind.keyword);
|
||||
arraySymbols.insert(alignof_);
|
||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "dup", CompletionKind.keyword));
|
||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "idup", CompletionKind.keyword));
|
||||
arraySymbols.insert(init);
|
||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "length", CompletionKind.keyword, ulong_));
|
||||
arraySymbols.insert(mangleof_);
|
||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "ptr", CompletionKind.keyword));
|
||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "reverse", CompletionKind.keyword));
|
||||
arraySymbols.insert(sizeof_);
|
||||
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "sort", CompletionKind.keyword));
|
||||
arraySymbols.insert(stringof_);
|
||||
|
||||
arrSym.insert(alignof_);
|
||||
arrSym.insert(new ACSymbol("dup", CompletionKind.keyword));
|
||||
arrSym.insert(new ACSymbol("idup", CompletionKind.keyword));
|
||||
arrSym.insert(init);
|
||||
arrSym.insert(new ACSymbol("length", CompletionKind.keyword, ulong_));
|
||||
arrSym.insert(mangleof_);
|
||||
arrSym.insert(new ACSymbol("ptr", CompletionKind.keyword));
|
||||
arrSym.insert(new ACSymbol("reverse", CompletionKind.keyword));
|
||||
arrSym.insert(sizeof_);
|
||||
arrSym.insert(new ACSymbol("sort", CompletionKind.keyword));
|
||||
arrSym.insert(stringof_);
|
||||
assocArraySymbols.insert(alignof_);
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "byKey", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "byValue", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "dup", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "get", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "keys", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "length", CompletionKind.keyword, ulong_));
|
||||
assocArraySymbols.insert(mangleof_);
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "rehash", CompletionKind.keyword));
|
||||
assocArraySymbols.insert(sizeof_);
|
||||
assocArraySymbols.insert(stringof_);
|
||||
assocArraySymbols.insert(init);
|
||||
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "values", CompletionKind.keyword));
|
||||
|
||||
asarrSym.insert(alignof_);
|
||||
asarrSym.insert(new ACSymbol("byKey", CompletionKind.keyword));
|
||||
asarrSym.insert(new ACSymbol("byValue", CompletionKind.keyword));
|
||||
asarrSym.insert(new ACSymbol("dup", CompletionKind.keyword));
|
||||
asarrSym.insert(new ACSymbol("get", CompletionKind.keyword));
|
||||
asarrSym.insert(new ACSymbol("init", CompletionKind.keyword));
|
||||
asarrSym.insert(new ACSymbol("keys", CompletionKind.keyword));
|
||||
asarrSym.insert(new ACSymbol("length", CompletionKind.keyword, ulong_));
|
||||
asarrSym.insert(mangleof_);
|
||||
asarrSym.insert(new ACSymbol("rehash", CompletionKind.keyword));
|
||||
asarrSym.insert(sizeof_);
|
||||
asarrSym.insert(stringof_);
|
||||
asarrSym.insert(init);
|
||||
asarrSym.insert(new ACSymbol("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; [bool_, int_, long_, byte_, char_, dchar_, short_, ubyte_, uint_,
|
||||
ulong_, ushort_, wchar_])
|
||||
foreach (s; integralTypeArray)
|
||||
{
|
||||
s.parts.insert(new ACSymbol("init", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("min", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("max", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max", CompletionKind.keyword, s));
|
||||
s.parts.insert(alignof_);
|
||||
s.parts.insert(sizeof_);
|
||||
s.parts.insert(stringof_);
|
||||
|
|
@ -377,74 +396,101 @@ static this()
|
|||
s.parts.insert(init);
|
||||
}
|
||||
|
||||
auto cdouble_ = new ACSymbol("cdouble", CompletionKind.keyword);
|
||||
auto cent_ = new ACSymbol("cent", CompletionKind.keyword);
|
||||
auto cfloat_ = new ACSymbol("cfloat", CompletionKind.keyword);
|
||||
auto creal_ = new ACSymbol("creal", CompletionKind.keyword);
|
||||
auto double_ = new ACSymbol("double", CompletionKind.keyword);
|
||||
auto float_ = new ACSymbol("float", CompletionKind.keyword);
|
||||
auto idouble_ = new ACSymbol("idouble", CompletionKind.keyword);
|
||||
auto ifloat_ = new ACSymbol("ifloat", CompletionKind.keyword);
|
||||
auto ireal_ = new ACSymbol("ireal", CompletionKind.keyword);
|
||||
auto real_ = new ACSymbol("real", CompletionKind.keyword);
|
||||
auto ucent_ = new ACSymbol("ucent", CompletionKind.keyword);
|
||||
auto cdouble_ = allocate!ACSymbol(Mallocator.it, "cdouble", CompletionKind.keyword);
|
||||
auto cent_ = allocate!ACSymbol(Mallocator.it, "cent", CompletionKind.keyword);
|
||||
auto cfloat_ = allocate!ACSymbol(Mallocator.it, "cfloat", CompletionKind.keyword);
|
||||
auto creal_ = allocate!ACSymbol(Mallocator.it, "creal", CompletionKind.keyword);
|
||||
auto double_ = allocate!ACSymbol(Mallocator.it, "double", CompletionKind.keyword);
|
||||
auto float_ = allocate!ACSymbol(Mallocator.it, "float", CompletionKind.keyword);
|
||||
auto idouble_ = allocate!ACSymbol(Mallocator.it, "idouble", CompletionKind.keyword);
|
||||
auto ifloat_ = allocate!ACSymbol(Mallocator.it, "ifloat", CompletionKind.keyword);
|
||||
auto ireal_ = allocate!ACSymbol(Mallocator.it, "ireal", CompletionKind.keyword);
|
||||
auto real_ = allocate!ACSymbol(Mallocator.it, "real", CompletionKind.keyword);
|
||||
auto ucent_ = allocate!ACSymbol(Mallocator.it, "ucent", CompletionKind.keyword);
|
||||
|
||||
foreach (s; [cdouble_, cent_, cfloat_, creal_, double_, float_,
|
||||
idouble_, ifloat_, ireal_, real_, ucent_])
|
||||
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(new ACSymbol("dig", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("epsilon", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("infinity", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("init", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "dig", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "epsilon", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "infinity", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword, s));
|
||||
s.parts.insert(mangleof_);
|
||||
s.parts.insert(new ACSymbol("mant_dig", CompletionKind.keyword, int_));
|
||||
s.parts.insert(new ACSymbol("max", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("max_10_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(new ACSymbol("max_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(new ACSymbol("min", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("min_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(new ACSymbol("min_10_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(new ACSymbol("min_normal", CompletionKind.keyword, s));
|
||||
s.parts.insert(new ACSymbol("nan", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "mant_dig", CompletionKind.keyword, int_));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max_10_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min_10_exp", CompletionKind.keyword, int_));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min_normal", CompletionKind.keyword, s));
|
||||
s.parts.insert(allocate!ACSymbol(Mallocator.it, "nan", CompletionKind.keyword, s));
|
||||
s.parts.insert(sizeof_);
|
||||
s.parts.insert(stringof_);
|
||||
}
|
||||
|
||||
aggSym.insert(new ACSymbol("tupleof", CompletionKind.variableName));
|
||||
aggSym.insert(mangleof_);
|
||||
aggSym.insert(alignof_);
|
||||
aggSym.insert(sizeof_);
|
||||
aggSym.insert(stringof_);
|
||||
aggSym.insert(init);
|
||||
aggregateSymbols.insert(allocate!ACSymbol(Mallocator.it, "tupleof", CompletionKind.variableName));
|
||||
aggregateSymbols.insert(mangleof_);
|
||||
aggregateSymbols.insert(alignof_);
|
||||
aggregateSymbols.insert(sizeof_);
|
||||
aggregateSymbols.insert(stringof_);
|
||||
aggregateSymbols.insert(init);
|
||||
|
||||
clSym.insert(new ACSymbol("classInfo", CompletionKind.variableName));
|
||||
clSym.insert(new ACSymbol("tupleof", CompletionKind.variableName));
|
||||
clSym.insert(new ACSymbol("__vptr", CompletionKind.variableName));
|
||||
clSym.insert(new ACSymbol("__monitor", CompletionKind.variableName));
|
||||
clSym.insert(mangleof_);
|
||||
clSym.insert(alignof_);
|
||||
clSym.insert(sizeof_);
|
||||
clSym.insert(stringof_);
|
||||
clSym.insert(init);
|
||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "classInfo", CompletionKind.variableName));
|
||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "tupleof", CompletionKind.variableName));
|
||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "__vptr", CompletionKind.variableName));
|
||||
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "__monitor", CompletionKind.variableName));
|
||||
classSymbols.insert(mangleof_);
|
||||
classSymbols.insert(alignof_);
|
||||
classSymbols.insert(sizeof_);
|
||||
classSymbols.insert(stringof_);
|
||||
classSymbols.insert(init);
|
||||
|
||||
ireal_.parts.insert(new ACSymbol("im", CompletionKind.keyword, real_));
|
||||
ifloat_.parts.insert(new ACSymbol("im", CompletionKind.keyword, float_));
|
||||
idouble_.parts.insert(new ACSymbol("im", CompletionKind.keyword, double_));
|
||||
ireal_.parts.insert(new ACSymbol("re", CompletionKind.keyword, real_));
|
||||
ifloat_.parts.insert(new ACSymbol("re", CompletionKind.keyword, float_));
|
||||
idouble_.parts.insert(new ACSymbol("re", CompletionKind.keyword, double_));
|
||||
ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, "im", CompletionKind.keyword, real_));
|
||||
ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, "im", CompletionKind.keyword, float_));
|
||||
idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, "im", CompletionKind.keyword, double_));
|
||||
ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, "re", CompletionKind.keyword, real_));
|
||||
ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, "re", CompletionKind.keyword, float_));
|
||||
idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, "re", CompletionKind.keyword, double_));
|
||||
|
||||
auto void_ = new ACSymbol("void", CompletionKind.keyword);
|
||||
auto void_ = allocate!ACSymbol(Mallocator.it, "void", CompletionKind.keyword);
|
||||
|
||||
bSym.insert([bool_, int_, long_, byte_, char_, dchar_, short_, ubyte_, uint_,
|
||||
ulong_, ushort_, wchar_, cdouble_, cent_, cfloat_, creal_, double_,
|
||||
float_, idouble_, ifloat_, ireal_, real_, ucent_, void_]);
|
||||
|
||||
builtinSymbols = bSym;
|
||||
arraySymbols = arrSym;
|
||||
assocArraySymbols = asarrSym;
|
||||
aggregateSymbols = aggSym;
|
||||
classSymbols = clSym;
|
||||
builtinSymbols.insert(bool_);
|
||||
builtinSymbols.insert(int_);
|
||||
builtinSymbols.insert(long_);
|
||||
builtinSymbols.insert(byte_);
|
||||
builtinSymbols.insert(char_);
|
||||
builtinSymbols.insert(dchar_);
|
||||
builtinSymbols.insert(short_);
|
||||
builtinSymbols.insert(ubyte_);
|
||||
builtinSymbols.insert(uint_);
|
||||
builtinSymbols.insert(ulong_);
|
||||
builtinSymbols.insert(ushort_);
|
||||
builtinSymbols.insert(wchar_);
|
||||
builtinSymbols.insert(cdouble_);
|
||||
builtinSymbols.insert(cent_);
|
||||
builtinSymbols.insert(cfloat_);
|
||||
builtinSymbols.insert(creal_);
|
||||
builtinSymbols.insert(double_);
|
||||
builtinSymbols.insert(float_);
|
||||
builtinSymbols.insert(idouble_);
|
||||
builtinSymbols.insert(ifloat_);
|
||||
builtinSymbols.insert(ireal_);
|
||||
builtinSymbols.insert(real_);
|
||||
builtinSymbols.insert(ucent_);
|
||||
builtinSymbols.insert(void_);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -26,10 +26,13 @@ import std.path;
|
|||
import std.range;
|
||||
import std.stdio;
|
||||
import std.uni;
|
||||
import stdx.d.ast;
|
||||
import stdx.d.lexer;
|
||||
import stdx.d.parser;
|
||||
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;
|
||||
|
|
@ -49,7 +52,8 @@ AutocompleteResponse getDoc(const AutocompleteRequest request)
|
|||
{
|
||||
Log.trace("Getting doc comments");
|
||||
AutocompleteResponse response;
|
||||
ACSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc);
|
||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||
ACSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.ddoc, allocator);
|
||||
if (symbols.length == 0)
|
||||
Log.error("Could not find symbol");
|
||||
else foreach (symbol; symbols)
|
||||
|
|
@ -76,7 +80,8 @@ AutocompleteResponse findDeclaration(const AutocompleteRequest request)
|
|||
{
|
||||
Log.trace("Finding declaration");
|
||||
AutocompleteResponse response;
|
||||
ACSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.location);
|
||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||
ACSymbol*[] symbols = getSymbolsForCompletion(request, CompletionType.location, allocator);
|
||||
if (symbols.length > 0)
|
||||
{
|
||||
response.symbolLocation = symbols[0].location;
|
||||
|
|
@ -120,7 +125,7 @@ AutocompleteResponse complete(const AutocompleteRequest request)
|
|||
tokenType = beforeTokens[$ - 2].type;
|
||||
else
|
||||
return response;
|
||||
|
||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||
switch (tokenType)
|
||||
{
|
||||
case tok!"stringLiteral":
|
||||
|
|
@ -160,8 +165,11 @@ AutocompleteResponse complete(const AutocompleteRequest request)
|
|||
case tok!")":
|
||||
case tok!"]":
|
||||
case tok!"this":
|
||||
const(Scope)* completionScope = generateAutocompleteTrees(tokenArray,
|
||||
"stdin");
|
||||
auto semanticAllocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024*16)));
|
||||
shared(StringCache)* cache = new shared StringCache(StringCache.defaultBucketCount);
|
||||
Scope* completionScope = generateAutocompleteTrees(tokenArray,
|
||||
"stdin", allocator, semanticAllocator, cache);
|
||||
scope(exit) typeid(Scope).destroy(completionScope);
|
||||
auto expression = getExpression(beforeTokens);
|
||||
response.setCompletions(completionScope, expression,
|
||||
request.cursorPosition, CompletionType.identifiers, partial);
|
||||
|
|
@ -207,12 +215,16 @@ auto getTokensBeforeCursor(const(ubyte[]) sourceCode, size_t cursorPosition,
|
|||
* the request's source code, cursor position, and completion type.
|
||||
*/
|
||||
ACSymbol*[] getSymbolsForCompletion(const AutocompleteRequest request,
|
||||
const CompletionType type)
|
||||
const CompletionType type, CAllocator allocator)
|
||||
{
|
||||
const(Token)[] tokenArray;
|
||||
auto beforeTokens = getTokensBeforeCursor(request.sourceCode,
|
||||
request.cursorPosition, tokenArray);
|
||||
const(Scope)* completionScope = generateAutocompleteTrees(tokenArray, "stdin");
|
||||
auto semanticAllocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024*16)));
|
||||
shared(StringCache)* cache = new shared StringCache(StringCache.defaultBucketCount);
|
||||
Scope* completionScope = generateAutocompleteTrees(tokenArray,
|
||||
"stdin", allocator, semanticAllocator, cache);
|
||||
scope(exit) typeid(Scope).destroy(completionScope);
|
||||
auto expression = getExpression(beforeTokens);
|
||||
return getSymbolsByTokenChain(completionScope, expression,
|
||||
request.cursorPosition, type);
|
||||
|
|
@ -232,6 +244,7 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
|
|||
{
|
||||
AutocompleteResponse response;
|
||||
immutable(string)[] completions;
|
||||
auto allocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 16)))();
|
||||
switch (beforeTokens[$ - 2].type)
|
||||
{
|
||||
case tok!"__traits":
|
||||
|
|
@ -259,8 +272,11 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
|
|||
case tok!"identifier":
|
||||
case tok!")":
|
||||
case tok!"]":
|
||||
const(Scope)* completionScope = generateAutocompleteTrees(tokenArray,
|
||||
"stdin");
|
||||
auto semanticAllocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024*16)));
|
||||
shared(StringCache)* cache = new shared StringCache(StringCache.defaultBucketCount);
|
||||
Scope* completionScope = generateAutocompleteTrees(tokenArray,
|
||||
"stdin", allocator, semanticAllocator, cache);
|
||||
scope(exit) typeid(Scope).destroy(completionScope);
|
||||
auto expression = getExpression(beforeTokens[0 .. $ - 1]);
|
||||
response.setCompletions(completionScope, expression,
|
||||
cursorPosition, CompletionType.calltips);
|
||||
|
|
@ -274,16 +290,18 @@ AutocompleteResponse parenCompletion(T)(T beforeTokens,
|
|||
/**
|
||||
*
|
||||
*/
|
||||
ACSymbol*[] getSymbolsByTokenChain(T)(const(Scope)* completionScope,
|
||||
ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
|
||||
T tokens, size_t cursorPosition, CompletionType completionType)
|
||||
{
|
||||
Log.trace("Getting symbols from token chain", tokens.map!"a.text");
|
||||
import std.d.lexer;
|
||||
Log.trace("Getting symbols from token chain",
|
||||
tokens.map!stringToken);
|
||||
// Find the symbol corresponding to the beginning of the chain
|
||||
ACSymbol*[] symbols = completionScope.getSymbolsByNameAndCursor(
|
||||
tokens[0].text, cursorPosition);
|
||||
stringToken(tokens[0]), cursorPosition);
|
||||
if (symbols.length == 0)
|
||||
{
|
||||
Log.error("Could not find declaration of ", tokens[0].text,
|
||||
Log.error("Could not find declaration of ", stringToken(tokens[0]),
|
||||
" from position ", cursorPosition);
|
||||
return [];
|
||||
}
|
||||
|
|
@ -437,7 +455,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(const(Scope)* completionScope,
|
|||
*
|
||||
*/
|
||||
void setCompletions(T)(ref AutocompleteResponse response,
|
||||
const(Scope)* completionScope, T tokens, size_t cursorPosition,
|
||||
Scope* completionScope, T tokens, size_t cursorPosition,
|
||||
CompletionType completionType, string partial = null)
|
||||
{
|
||||
// Autocomplete module imports instead of symbols
|
||||
|
|
@ -486,7 +504,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
|
|||
&& (partial is null ? true : a.name.toUpper().startsWith(partial.toUpper()))
|
||||
&& !response.completions.canFind(a.name)))
|
||||
{
|
||||
Log.trace("Adding ", s.name, " to the completion list");
|
||||
// Log.trace("Adding ", s.name, " to the completion list");
|
||||
response.completionKinds ~= s.kind;
|
||||
response.completions ~= s.name;
|
||||
}
|
||||
|
|
@ -733,6 +751,11 @@ string formatComment(string comment)
|
|||
.replaceAll(regex("\n"), `\n`).outdent();
|
||||
}
|
||||
|
||||
string stringToken()(auto ref const Token a)
|
||||
{
|
||||
return a.text is null ? str(a.type) : a.text;
|
||||
}
|
||||
|
||||
//unittest
|
||||
//{
|
||||
// auto comment1 = "/**\n * This is some text\n */";
|
||||
|
|
|
|||
|
|
@ -1,2 +1,3 @@
|
|||
dmd -wi client.d messages.d stupidlog.d msgpack-d/src/msgpack.d -Imsgpack-d/src -release -inline -noboundscheck -O -ofdcd-client.exe
|
||||
dmd actypes.d conversion/astconverter.d conversion/first.d conversion/second.d conversion/third.d autocomplete.d constants.d messages.d modulecache.d semantic.d server.d stupidlog.d dscanner/stdx/d/ast.d dscanner/stdx/d/entities.d dscanner/stdx/d/lexer.d dscanner/stdx/d/parser.d dscanner/stdx/lexer.d dscanner/stdx/allocator.d dscanner/formatter.d msgpack-d/src/msgpack.d -Imsgpack-d/src -Idscanner -wi -g -O -release -noboundscheck -inline -ofdcd-server.exe
|
||||
dmd -wi client.d messages.d stupidlog.d msgpack-d/src/msgpack.d -Imsgpack-d/src -release -inline -O -ofdcd-client
|
||||
|
||||
dmd actypes.d conversion/astconverter.d conversion/first.d conversion/second.d conversion/third.d autocomplete.d constants.d messages.d modulecache.d semantic.d server.d stupidlog.d dscanner/std/d/ast.d dscanner/std/d/entities.d dscanner/std/d/lexer.d dscanner/std/d/parser.d dscanner/std/lexer.d dscanner/std/allocator.d dscanner/formatter.d containers/src/memory/allocators.d msgpack-d/src/msgpack.d -Icontainers/src -Imsgpack-d/src -Idscanner -wi -g -O -release -ofdcd-server
|
||||
|
|
|
|||
33
build.sh
33
build.sh
|
|
@ -1,12 +1,15 @@
|
|||
dmd -wi client.d\
|
||||
rm -f containers/src/std/allocator.d
|
||||
|
||||
dmd\
|
||||
client.d\
|
||||
messages.d\
|
||||
stupidlog.d\
|
||||
msgpack-d/src/msgpack.d\
|
||||
-Imsgpack-d/src\
|
||||
-release -inline -noboundscheck -O\
|
||||
-release -inline -O -wi\
|
||||
-ofdcd-client
|
||||
|
||||
dmd \
|
||||
dmd\
|
||||
actypes.d\
|
||||
conversion/astconverter.d\
|
||||
conversion/first.d\
|
||||
|
|
@ -19,18 +22,26 @@ dmd \
|
|||
semantic.d\
|
||||
server.d\
|
||||
stupidlog.d\
|
||||
dscanner/stdx/d/ast.d\
|
||||
dscanner/stdx/d/entities.d\
|
||||
dscanner/stdx/d/lexer.d\
|
||||
dscanner/stdx/d/parser.d\
|
||||
dscanner/stdx/lexer.d\
|
||||
dscanner/stdx/allocator.d\
|
||||
dscanner/std/d/ast.d\
|
||||
dscanner/std/d/entities.d\
|
||||
dscanner/std/d/lexer.d\
|
||||
dscanner/std/d/parser.d\
|
||||
dscanner/std/lexer.d\
|
||||
dscanner/std/allocator.d\
|
||||
dscanner/formatter.d\
|
||||
containers/src/memory/allocators.d\
|
||||
containers/src/memory/appender.d\
|
||||
containers/src/containers/dynamicarray.d\
|
||||
containers/src/containers/karytree.d\
|
||||
containers/src/containers/unrolledlist.d\
|
||||
containers/src/containers/hashset.d\
|
||||
containers/src/containers/internal/hash.d\
|
||||
containers/src/containers/slist.d\
|
||||
msgpack-d/src/msgpack.d\
|
||||
-Icontainers/src\
|
||||
-Imsgpack-d/src\
|
||||
-Idscanner\
|
||||
-wi -g\
|
||||
-O -release -noboundscheck -inline\
|
||||
-wi -O -release -inline\
|
||||
-ofdcd-server
|
||||
|
||||
#gdc client.d\
|
||||
|
|
|
|||
2
client.d
2
client.d
|
|
@ -185,7 +185,7 @@ Options:
|
|||
Instructs the server to add PATH to its list of paths searced for
|
||||
imported modules.
|
||||
|
||||
--port PORTNUMBER | -pPORTNUMBER
|
||||
--port PORTNUMBER | -p PORTNUMBER
|
||||
Uses PORTNUMBER to communicate with the server instead of the default
|
||||
port 9166.`, programName);
|
||||
}
|
||||
|
|
|
|||
188
constants.d
188
constants.d
|
|
@ -177,113 +177,83 @@ immutable string[] versions = [
|
|||
"X86_64"
|
||||
];
|
||||
|
||||
/**
|
||||
* Properties of class types
|
||||
*/
|
||||
immutable string[] classProperties = [
|
||||
"alignof",
|
||||
"classinfo",
|
||||
"init",
|
||||
"mangleof",
|
||||
"__monitor",
|
||||
"sizeof",
|
||||
"stringof",
|
||||
"tupleof",
|
||||
"__vptr",
|
||||
immutable string[] predefinedVersions = [
|
||||
"AArch64",
|
||||
"AIX",
|
||||
"all",
|
||||
"Alpha",
|
||||
"Alpha_HardFloat",
|
||||
"Alpha_SoftFloat",
|
||||
"Android",
|
||||
"ARM",
|
||||
"ARM_HardFloat",
|
||||
"ARM_SoftFloat",
|
||||
"ARM_SoftFP",
|
||||
"ARM_Thumb",
|
||||
"assert",
|
||||
"BigEndian",
|
||||
"BSD",
|
||||
"Cygwin",
|
||||
"D_Coverage",
|
||||
"D_Ddoc",
|
||||
"D_HardFloat",
|
||||
"DigitalMars",
|
||||
"D_InlineAsm_X86",
|
||||
"D_InlineAsm_X86_64",
|
||||
"D_LP64",
|
||||
"D_NoBoundsChecks",
|
||||
"D_PIC",
|
||||
"DragonFlyBSD",
|
||||
"D_SIMD",
|
||||
"D_SoftFloat",
|
||||
"D_Version2",
|
||||
"D_X32",
|
||||
"FreeBSD",
|
||||
"GNU",
|
||||
"Haiku",
|
||||
"HPPA",
|
||||
"HPPA64",
|
||||
"Hurd",
|
||||
"IA64",
|
||||
"LDC",
|
||||
"linux",
|
||||
"LittleEndian",
|
||||
"MIPS32",
|
||||
"MIPS64",
|
||||
"MIPS_EABI",
|
||||
"MIPS_HardFloat",
|
||||
"MIPS_N32",
|
||||
"MIPS_N64",
|
||||
"MIPS_O32",
|
||||
"MIPS_O64",
|
||||
"MIPS_SoftFloat",
|
||||
"NetBSD",
|
||||
"none",
|
||||
"OpenBSD",
|
||||
"OSX",
|
||||
"Posix",
|
||||
"PPC",
|
||||
"PPC64",
|
||||
"PPC_HardFloat",
|
||||
"PPC_SoftFloat",
|
||||
"S390",
|
||||
"S390X",
|
||||
"SDC",
|
||||
"SH",
|
||||
"SH64",
|
||||
"SkyOS",
|
||||
"Solaris",
|
||||
"SPARC",
|
||||
"SPARC64",
|
||||
"SPARC_HardFloat",
|
||||
"SPARC_SoftFloat",
|
||||
"SPARC_V8Plus",
|
||||
"SysV3",
|
||||
"SysV4",
|
||||
"unittest",
|
||||
"Win32",
|
||||
"Win64",
|
||||
"Windows",
|
||||
"X86",
|
||||
"X86_64",
|
||||
];
|
||||
|
||||
/**
|
||||
* Properties of struct types
|
||||
*/
|
||||
immutable string[] structProperties = [
|
||||
"alignof",
|
||||
"tupleof",
|
||||
"init",
|
||||
"mangleof",
|
||||
"sizeof",
|
||||
"stringof"
|
||||
];
|
||||
|
||||
immutable string[] predefinedVersions;
|
||||
|
||||
static this()
|
||||
{
|
||||
version(AArch64) predefinedVersions ~= "AArch64";
|
||||
version(AIX) predefinedVersions ~= "AIX";
|
||||
version(all) predefinedVersions ~= "all";
|
||||
version(Alpha) predefinedVersions ~= "Alpha";
|
||||
version(Alpha_HardFloat) predefinedVersions ~= "Alpha_HardFloat";
|
||||
version(Alpha_SoftFloat) predefinedVersions ~= "Alpha_SoftFloat";
|
||||
version(Android) predefinedVersions ~= "Android";
|
||||
version(ARM) predefinedVersions ~= "ARM";
|
||||
version(ARM_HardFloat) predefinedVersions ~= "ARM_HardFloat";
|
||||
version(ARM_SoftFloat) predefinedVersions ~= "ARM_SoftFloat";
|
||||
version(ARM_SoftFP) predefinedVersions ~= "ARM_SoftFP";
|
||||
version(ARM_Thumb) predefinedVersions ~= "ARM_Thumb";
|
||||
version(assert) predefinedVersions ~= "assert";
|
||||
version(BigEndian) predefinedVersions ~= "BigEndian";
|
||||
version(BSD) predefinedVersions ~= "BSD";
|
||||
version(Cygwin) predefinedVersions ~= "Cygwin";
|
||||
version(D_Coverage) predefinedVersions ~= "D_Coverage";
|
||||
version(D_Ddoc) predefinedVersions ~= "D_Ddoc";
|
||||
version(D_HardFloat) predefinedVersions ~= "D_HardFloat";
|
||||
version(DigitalMars) predefinedVersions ~= "DigitalMars";
|
||||
version(D_InlineAsm_X86) predefinedVersions ~= "D_InlineAsm_X86";
|
||||
version(D_InlineAsm_X86_64) predefinedVersions ~= "D_InlineAsm_X86_64";
|
||||
version(D_LP64) predefinedVersions ~= "D_LP64";
|
||||
version(D_NoBoundsChecks) predefinedVersions ~= "D_NoBoundsChecks";
|
||||
version(D_PIC) predefinedVersions ~= "D_PIC";
|
||||
version(DragonFlyBSD) predefinedVersions ~= "DragonFlyBSD";
|
||||
version(D_SIMD) predefinedVersions ~= "D_SIMD";
|
||||
version(D_SoftFloat) predefinedVersions ~= "D_SoftFloat";
|
||||
version(D_Version2) predefinedVersions ~= "D_Version2";
|
||||
version(D_X32) predefinedVersions ~= "D_X32";
|
||||
version(FreeBSD) predefinedVersions ~= "FreeBSD";
|
||||
version(GNU) predefinedVersions ~= "GNU";
|
||||
version(Haiku) predefinedVersions ~= "Haiku";
|
||||
version(HPPA) predefinedVersions ~= "HPPA";
|
||||
version(HPPA64) predefinedVersions ~= "HPPA64";
|
||||
version(Hurd) predefinedVersions ~= "Hurd";
|
||||
version(IA64) predefinedVersions ~= "IA64";
|
||||
version(LDC) predefinedVersions ~= "LDC";
|
||||
version(linux) predefinedVersions ~= "linux";
|
||||
version(LittleEndian) predefinedVersions ~= "LittleEndian";
|
||||
version(MIPS32) predefinedVersions ~= "MIPS32";
|
||||
version(MIPS64) predefinedVersions ~= "MIPS64";
|
||||
version(MIPS_EABI) predefinedVersions ~= "MIPS_EABI";
|
||||
version(MIPS_HardFloat) predefinedVersions ~= "MIPS_HardFloat";
|
||||
version(MIPS_N32) predefinedVersions ~= "MIPS_N32";
|
||||
version(MIPS_N64) predefinedVersions ~= "MIPS_N64";
|
||||
version(MIPS_O32) predefinedVersions ~= "MIPS_O32";
|
||||
version(MIPS_O64) predefinedVersions ~= "MIPS_O64";
|
||||
version(MIPS_SoftFloat) predefinedVersions ~= "MIPS_SoftFloat";
|
||||
version(NetBSD) predefinedVersions ~= "NetBSD";
|
||||
version(none) predefinedVersions ~= "none";
|
||||
version(OpenBSD) predefinedVersions ~= "OpenBSD";
|
||||
version(OSX) predefinedVersions ~= "OSX";
|
||||
version(Posix) predefinedVersions ~= "Posix";
|
||||
version(PPC) predefinedVersions ~= "PPC";
|
||||
version(PPC64) predefinedVersions ~= "PPC64";
|
||||
version(PPC_HardFloat) predefinedVersions ~= "PPC_HardFloat";
|
||||
version(PPC_SoftFloat) predefinedVersions ~= "PPC_SoftFloat";
|
||||
version(S390) predefinedVersions ~= "S390";
|
||||
version(S390X) predefinedVersions ~= "S390X";
|
||||
version(SDC) predefinedVersions ~= "SDC";
|
||||
version(SH) predefinedVersions ~= "SH";
|
||||
version(SH64) predefinedVersions ~= "SH64";
|
||||
version(SkyOS) predefinedVersions ~= "SkyOS";
|
||||
version(Solaris) predefinedVersions ~= "Solaris";
|
||||
version(SPARC) predefinedVersions ~= "SPARC";
|
||||
version(SPARC64) predefinedVersions ~= "SPARC64";
|
||||
version(SPARC_HardFloat) predefinedVersions ~= "SPARC_HardFloat";
|
||||
version(SPARC_SoftFloat) predefinedVersions ~= "SPARC_SoftFloat";
|
||||
version(SPARC_V8Plus) predefinedVersions ~= "SPARC_V8Plus";
|
||||
version(SysV3) predefinedVersions ~= "SysV3";
|
||||
version(SysV4) predefinedVersions ~= "SysV4";
|
||||
version(unittest) predefinedVersions ~= "unittest";
|
||||
version(Win32) predefinedVersions ~= "Win32";
|
||||
version(Win64) predefinedVersions ~= "Win64";
|
||||
version(Windows) predefinedVersions ~= "Windows";
|
||||
version(X86) predefinedVersions ~= "X86";
|
||||
version(X86_64) predefinedVersions ~= "X86_64";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,22 +18,24 @@
|
|||
|
||||
module conversion.astconverter;
|
||||
|
||||
import stdx.d.lexer;
|
||||
import stdx.d.ast;
|
||||
import stdx.d.parser;
|
||||
|
||||
import actypes;
|
||||
import conversion.first;
|
||||
import conversion.second;
|
||||
import conversion.third;
|
||||
import actypes;
|
||||
import memory.allocators;
|
||||
import std.allocator;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import std.d.parser;
|
||||
import std.typecons;
|
||||
|
||||
|
||||
const(Scope)* generateAutocompleteTrees(const(Token)[] tokens, string symbolFile)
|
||||
Scope* generateAutocompleteTrees(const(Token)[] tokens, string symbolFile,
|
||||
CAllocator symbolAllocator, CAllocator semanticAllocator,
|
||||
shared(StringCache)* cache)
|
||||
{
|
||||
ParseAllocator p = new ParseAllocator;
|
||||
Module m = parseModule(tokens, "editor buffer", p, &doesNothing);
|
||||
shared(StringCache)* cache = new shared StringCache(StringCache.defaultBucketCount);
|
||||
FirstPass first = new FirstPass(m, symbolFile, cache);
|
||||
Module m = parseModule(tokens, "editor buffer", semanticAllocator, &doesNothing);
|
||||
auto first = scoped!FirstPass(m, symbolFile, cache, symbolAllocator,
|
||||
semanticAllocator);
|
||||
first.run();
|
||||
|
||||
SecondPass second = SecondPass(first);
|
||||
|
|
@ -41,14 +43,13 @@ const(Scope)* generateAutocompleteTrees(const(Token)[] tokens, string symbolFile
|
|||
|
||||
ThirdPass third = ThirdPass(second);
|
||||
third.run();
|
||||
|
||||
p.deallocateAll();
|
||||
return cast(typeof(return)) third.moduleScope;
|
||||
typeid(typeof(third.rootSymbol)).destroy(third.rootSymbol);
|
||||
return third.moduleScope;
|
||||
}
|
||||
|
||||
Module parseModuleSimple(const(Token)[] tokens, string fileName, ParseAllocator p)
|
||||
Module parseModuleSimple(const(Token)[] tokens, string fileName, CAllocator p)
|
||||
{
|
||||
auto parser = new SimpleParser();
|
||||
auto parser = scoped!SimpleParser();
|
||||
parser.fileName = fileName;
|
||||
parser.tokens = tokens;
|
||||
parser.messageFunction = &doesNothing;
|
||||
|
|
|
|||
|
|
@ -18,12 +18,18 @@
|
|||
|
||||
module conversion.first;
|
||||
|
||||
import stdx.d.ast;
|
||||
import stdx.d.lexer;
|
||||
import actypes;
|
||||
import semantic;
|
||||
import formatter;
|
||||
import std.allocator;
|
||||
import memory.allocators;
|
||||
import memory.appender;
|
||||
import messages;
|
||||
import semantic;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import std.typecons;
|
||||
import stupidlog;
|
||||
import containers.unrolledlist;
|
||||
|
||||
/**
|
||||
* First Pass handles the following:
|
||||
|
|
@ -40,24 +46,31 @@ import stupidlog;
|
|||
*/
|
||||
final class FirstPass : ASTVisitor
|
||||
{
|
||||
this(Module mod, string symbolFile, shared(StringCache)* stringCache)
|
||||
this(Module mod, string symbolFile, shared(StringCache)* stringCache,
|
||||
CAllocator symbolAllocator, CAllocator semanticAllocator)
|
||||
in
|
||||
{
|
||||
assert (symbolAllocator);
|
||||
}
|
||||
body
|
||||
{
|
||||
this.symbolFile = symbolFile;
|
||||
this.mod = mod;
|
||||
this.symbolFile = symbolFile;
|
||||
this.stringCache = stringCache;
|
||||
this.symbolAllocator = symbolAllocator;
|
||||
this.semanticAllocator = semanticAllocator;
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
visit(mod);
|
||||
mod = null;
|
||||
}
|
||||
|
||||
override void visit(const Unittest u)
|
||||
{
|
||||
// Create a dummy symbol because we don't want unit test symbols leaking
|
||||
// into the symbol they're declared in.
|
||||
SemanticSymbol* s = new SemanticSymbol("*unittest*",
|
||||
SemanticSymbol* s = allocateSemanticSymbol("*unittest*",
|
||||
CompletionKind.dummy, null, 0);
|
||||
s.parent = currentSymbol;
|
||||
currentSymbol = s;
|
||||
|
|
@ -86,7 +99,7 @@ final class FirstPass : ASTVisitor
|
|||
override void visit(const Destructor des)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(des).stringof);
|
||||
visitDestructor(des.location, des.functionBody, des.comment);
|
||||
visitDestructor(des.index, des.functionBody, des.comment);
|
||||
}
|
||||
|
||||
override void visit(const SharedStaticDestructor des)
|
||||
|
|
@ -103,9 +116,10 @@ final class FirstPass : ASTVisitor
|
|||
|
||||
override void visit(const FunctionDeclaration dec)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(dec).stringof);
|
||||
SemanticSymbol* symbol = new SemanticSymbol(stringCache.intern(dec.name.text),
|
||||
CompletionKind.functionName, symbolFile, dec.name.index, dec.returnType);
|
||||
// Log.trace(__FUNCTION__, " ", typeof(dec).stringof, " ", dec.name.text);
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(dec.name.text,
|
||||
CompletionKind.functionName, symbolFile, dec.name.index,
|
||||
dec.returnType);
|
||||
processParameters(symbol, dec.returnType, symbol.acSymbol.name,
|
||||
dec.parameters, dec.comment);
|
||||
symbol.protection = protection;
|
||||
|
|
@ -153,8 +167,8 @@ final class FirstPass : ASTVisitor
|
|||
override void visit(const BaseClass bc)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(bc).stringof);
|
||||
currentSymbol.baseClasses ~= iotcToStringArray(
|
||||
bc.identifierOrTemplateChain, stringCache);
|
||||
currentSymbol.baseClasses.insert(iotcToStringArray(symbolAllocator,
|
||||
bc.identifierOrTemplateChain, stringCache));
|
||||
}
|
||||
|
||||
override void visit(const VariableDeclaration dec)
|
||||
|
|
@ -164,12 +178,9 @@ final class FirstPass : ASTVisitor
|
|||
const Type t = dec.type;
|
||||
foreach (declarator; dec.declarators)
|
||||
{
|
||||
SemanticSymbol* symbol = new SemanticSymbol(
|
||||
stringCache.intern(declarator.name.text),
|
||||
CompletionKind.variableName,
|
||||
symbolFile,
|
||||
declarator.name.index,
|
||||
t);
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(
|
||||
declarator.name.text, CompletionKind.variableName,
|
||||
symbolFile, declarator.name.index, t);
|
||||
symbol.protection = protection;
|
||||
symbol.parent = currentSymbol;
|
||||
symbol.acSymbol.doc = dec.comment;
|
||||
|
|
@ -179,10 +190,9 @@ final class FirstPass : ASTVisitor
|
|||
{
|
||||
foreach (identifier; dec.autoDeclaration.identifiers)
|
||||
{
|
||||
SemanticSymbol* symbol = new SemanticSymbol(
|
||||
stringCache.intern(identifier.text),
|
||||
CompletionKind.variableName, symbolFile, identifier.index,
|
||||
null);
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(
|
||||
identifier.text, CompletionKind.variableName, symbolFile,
|
||||
identifier.index, null);
|
||||
symbol.protection = protection;
|
||||
symbol.parent = currentSymbol;
|
||||
symbol.acSymbol.doc = dec.comment;
|
||||
|
|
@ -195,8 +205,8 @@ final class FirstPass : ASTVisitor
|
|||
{
|
||||
if (aliasDeclaration.initializers.length == 0)
|
||||
{
|
||||
SemanticSymbol* symbol = new SemanticSymbol(
|
||||
stringCache.intern(aliasDeclaration.name.text),
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(
|
||||
aliasDeclaration.name.text,
|
||||
CompletionKind.aliasName,
|
||||
symbolFile,
|
||||
aliasDeclaration.name.index,
|
||||
|
|
@ -210,8 +220,8 @@ final class FirstPass : ASTVisitor
|
|||
{
|
||||
foreach (initializer; aliasDeclaration.initializers)
|
||||
{
|
||||
SemanticSymbol* symbol = new SemanticSymbol(
|
||||
stringCache.intern(initializer.name.text),
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(
|
||||
initializer.name.text,
|
||||
CompletionKind.aliasName,
|
||||
symbolFile,
|
||||
initializer.name.index,
|
||||
|
|
@ -227,7 +237,7 @@ final class FirstPass : ASTVisitor
|
|||
override void visit(const AliasThisDeclaration dec)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(dec).stringof);
|
||||
currentSymbol.aliasThis ~= stringCache.intern(dec.identifier.text);
|
||||
currentSymbol.aliasThis.insert(stringCache.intern(dec.identifier.text));
|
||||
}
|
||||
|
||||
override void visit(const Declaration dec)
|
||||
|
|
@ -253,23 +263,24 @@ final class FirstPass : ASTVisitor
|
|||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(mod).stringof);
|
||||
//
|
||||
currentSymbol = new SemanticSymbol(null, CompletionKind.moduleName,
|
||||
currentSymbol = allocateSemanticSymbol(null, CompletionKind.moduleName,
|
||||
symbolFile);
|
||||
rootSymbol = currentSymbol;
|
||||
currentScope = new Scope(0, size_t.max);
|
||||
ImportInformation i;
|
||||
currentScope = allocate!Scope(semanticAllocator, 0, size_t.max);
|
||||
auto i = allocate!ImportInformation(semanticAllocator);
|
||||
i.modulePath = "object";
|
||||
i.importParts ~= "object";
|
||||
currentScope.importInformation ~= i;
|
||||
i.importParts.insert("object");
|
||||
currentScope.importInformation.insert(i);
|
||||
moduleScope = currentScope;
|
||||
mod.accept(this);
|
||||
assert (currentSymbol.acSymbol.name is null);
|
||||
}
|
||||
|
||||
override void visit(const EnumDeclaration dec)
|
||||
{
|
||||
assert (currentSymbol);
|
||||
// Log.trace(__FUNCTION__, " ", typeof(dec).stringof);
|
||||
SemanticSymbol* symbol = new SemanticSymbol(stringCache.intern(dec.name.text),
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(dec.name.text,
|
||||
CompletionKind.enumName, symbolFile, dec.name.index, dec.type);
|
||||
symbol.parent = currentSymbol;
|
||||
symbol.acSymbol.doc = dec.comment;
|
||||
|
|
@ -283,7 +294,7 @@ final class FirstPass : ASTVisitor
|
|||
override void visit(const EnumMember member)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(member).stringof);
|
||||
SemanticSymbol* symbol = new SemanticSymbol(stringCache.intern(member.name.text),
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(member.name.text,
|
||||
CompletionKind.enumMember, symbolFile, member.name.index, member.type);
|
||||
symbol.parent = currentSymbol;
|
||||
symbol.acSymbol.doc = member.comment;
|
||||
|
|
@ -295,72 +306,75 @@ final class FirstPass : ASTVisitor
|
|||
// Log.trace(__FUNCTION__, " ", typeof(dec).stringof);
|
||||
foreach (identifier; moduleDeclaration.moduleName.identifiers)
|
||||
{
|
||||
moduleName ~= stringCache.intern(identifier.text);
|
||||
moduleName.insert(stringCache.intern(identifier.text));
|
||||
}
|
||||
}
|
||||
|
||||
// creates scopes for
|
||||
override void visit(const StructBody structBody)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(structBody).stringof);
|
||||
Scope* s = new Scope(structBody.startLocation, structBody.endLocation);
|
||||
Scope* s = allocate!Scope(semanticAllocator, structBody.startLocation, structBody.endLocation);
|
||||
// Log.trace("Added scope ", s.startLocation, " ", s.endLocation);
|
||||
|
||||
ACSymbol* thisSymbol = new ACSymbol("this", CompletionKind.variableName,
|
||||
currentSymbol.acSymbol);
|
||||
ACSymbol* thisSymbol = allocate!ACSymbol(symbolAllocator, "this",
|
||||
CompletionKind.variableName, currentSymbol.acSymbol);
|
||||
thisSymbol.location = s.startLocation;
|
||||
thisSymbol.symbolFile = symbolFile;
|
||||
currentSymbol.acSymbol.parts.insert(thisSymbol);
|
||||
s.symbols.insert(thisSymbol);
|
||||
|
||||
s.parent = currentScope;
|
||||
currentScope = s;
|
||||
foreach (dec; structBody.declarations)
|
||||
visit(dec);
|
||||
currentScope = s.parent;
|
||||
currentScope.children ~= s;
|
||||
currentScope.children.insert(s);
|
||||
}
|
||||
|
||||
override void visit(const ImportDeclaration importDeclaration)
|
||||
{
|
||||
import std.typecons;
|
||||
import std.algorithm;
|
||||
import std.array;
|
||||
// Log.trace(__FUNCTION__, " ImportDeclaration");
|
||||
foreach (single; importDeclaration.singleImports.filter!(
|
||||
a => a !is null && a.identifierChain !is null))
|
||||
{
|
||||
ImportInformation info;
|
||||
info.importParts = single.identifierChain.identifiers.map!(a => stringCache.intern(a.text)).array;
|
||||
info.modulePath = convertChainToImportPath(single.identifierChain);
|
||||
auto info = allocate!ImportInformation(semanticAllocator);
|
||||
foreach (identifier; single.identifierChain.identifiers)
|
||||
info.importParts.insert(stringCache.intern(identifier.text));
|
||||
info.modulePath = convertChainToImportPath(stringCache, single.identifierChain);
|
||||
info.isPublic = protection == tok!"public";
|
||||
currentScope.importInformation ~= info;
|
||||
currentScope.importInformation.insert(info);
|
||||
}
|
||||
if (importDeclaration.importBindings is null) return;
|
||||
if (importDeclaration.importBindings.singleImport.identifierChain is null) return;
|
||||
ImportInformation info;
|
||||
info.modulePath = convertChainToImportPath(
|
||||
auto info = allocate!ImportInformation(semanticAllocator);
|
||||
|
||||
info.modulePath = convertChainToImportPath(stringCache,
|
||||
importDeclaration.importBindings.singleImport.identifierChain);
|
||||
info.importParts = importDeclaration.importBindings.singleImport
|
||||
.identifierChain.identifiers.map!(a => stringCache.intern(a.text)).array;
|
||||
foreach (identifier; importDeclaration.importBindings.singleImport
|
||||
.identifierChain.identifiers)
|
||||
{
|
||||
info.importParts.insert(stringCache.intern(identifier.text));
|
||||
}
|
||||
foreach (bind; importDeclaration.importBindings.importBinds)
|
||||
{
|
||||
Tuple!(string, string) bindTuple;
|
||||
bindTuple[0] = stringCache.intern(bind.left.text);
|
||||
bindTuple[1] = bind.right == tok!"" ? null : stringCache.intern(bind.right.text);
|
||||
info.importedSymbols ~= bindTuple;
|
||||
info.importedSymbols.insert(bindTuple);
|
||||
}
|
||||
info.isPublic = protection == tok!"public";
|
||||
currentScope.importInformation ~= info;
|
||||
currentScope.importInformation.insert(info);
|
||||
}
|
||||
|
||||
// Create scope for block statements
|
||||
override void visit(const BlockStatement blockStatement)
|
||||
{
|
||||
// Log.trace(__FUNCTION__, " ", typeof(blockStatement).stringof);
|
||||
Scope* s = new Scope(blockStatement.startLocation,
|
||||
Scope* s = allocate!Scope(semanticAllocator, blockStatement.startLocation,
|
||||
blockStatement.endLocation);
|
||||
s.parent = currentScope;
|
||||
currentScope.children ~= s;
|
||||
currentScope.children.insert(s);
|
||||
|
||||
if (currentSymbol.acSymbol.kind == CompletionKind.functionName)
|
||||
{
|
||||
|
|
@ -400,12 +414,16 @@ final class FirstPass : ASTVisitor
|
|||
|
||||
shared(StringCache)* stringCache;
|
||||
|
||||
CAllocator symbolAllocator;
|
||||
|
||||
uint symbolsAllocated;
|
||||
|
||||
private:
|
||||
|
||||
void visitAggregateDeclaration(AggType)(AggType dec, CompletionKind kind)
|
||||
{
|
||||
// Log.trace("visiting aggregate declaration ", dec.name.text);
|
||||
SemanticSymbol* symbol = new SemanticSymbol(stringCache.intern(dec.name.text),
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol(dec.name.text,
|
||||
kind, symbolFile, dec.name.index);
|
||||
if (kind == CompletionKind.className)
|
||||
symbol.acSymbol.parts.insert(classSymbols[]);
|
||||
|
|
@ -423,7 +441,7 @@ private:
|
|||
void visitConstructor(size_t location, const Parameters parameters,
|
||||
const FunctionBody functionBody, string doc)
|
||||
{
|
||||
SemanticSymbol* symbol = new SemanticSymbol("*constructor*",
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol("*constructor*",
|
||||
CompletionKind.functionName, symbolFile, location);
|
||||
processParameters(symbol, null, "this", parameters, doc);
|
||||
symbol.protection = protection;
|
||||
|
|
@ -440,7 +458,7 @@ private:
|
|||
|
||||
void visitDestructor(size_t location, const FunctionBody functionBody, string doc)
|
||||
{
|
||||
SemanticSymbol* symbol = new SemanticSymbol("~this",
|
||||
SemanticSymbol* symbol = allocateSemanticSymbol("~this",
|
||||
CompletionKind.functionName, symbolFile, location);
|
||||
symbol.acSymbol.callTip = "~this()";
|
||||
symbol.protection = protection;
|
||||
|
|
@ -462,21 +480,20 @@ private:
|
|||
{
|
||||
foreach (const Parameter p; parameters.parameters)
|
||||
{
|
||||
SemanticSymbol* parameter = new SemanticSymbol(
|
||||
stringCache.intern(p.name.text),
|
||||
CompletionKind.variableName, symbolFile, size_t.max,
|
||||
p.type);
|
||||
SemanticSymbol* parameter = allocateSemanticSymbol(
|
||||
p.name.text, CompletionKind.variableName, symbolFile,
|
||||
size_t.max, p.type);
|
||||
symbol.addChild(parameter);
|
||||
parameter.parent = symbol;
|
||||
}
|
||||
if (parameters.hasVarargs)
|
||||
{
|
||||
SemanticSymbol* argptr = new SemanticSymbol("_argptr",
|
||||
SemanticSymbol* argptr = allocateSemanticSymbol("_argptr",
|
||||
CompletionKind.variableName, null, size_t.max, argptrType);
|
||||
argptr.parent = symbol;
|
||||
symbol.addChild(argptr);
|
||||
|
||||
SemanticSymbol* arguments = new SemanticSymbol("_arguments",
|
||||
SemanticSymbol* arguments = allocateSemanticSymbol("_arguments",
|
||||
CompletionKind.variableName, null, size_t.max, argumentsType);
|
||||
arguments.parent = symbol;
|
||||
symbol.addChild(arguments);
|
||||
|
|
@ -486,22 +503,46 @@ private:
|
|||
parameters, doc);
|
||||
}
|
||||
|
||||
static string formatCallTip(const Type returnType, string name,
|
||||
string formatCallTip(const Type returnType, string name,
|
||||
const Parameters parameters, string doc = null)
|
||||
{
|
||||
import std.string;
|
||||
string parameterString = parameters is null ? "()"
|
||||
: formatNode(parameters);
|
||||
if (returnType is null)
|
||||
return "%s%s".format(name, parameterString);
|
||||
return "%s %s%s".format(formatNode(returnType), name, parameterString);
|
||||
QuickAllocator!1024 q;
|
||||
auto app = Appender!(char, typeof(q), 1024)(q);
|
||||
scope(exit) q.deallocate(app.mem);
|
||||
if (returnType !is null)
|
||||
{
|
||||
app.formatNode(returnType);
|
||||
app.put(' ');
|
||||
}
|
||||
app.put(name);
|
||||
if (parameters is null)
|
||||
app.put("()");
|
||||
else
|
||||
app.formatNode(parameters);
|
||||
return stringCache.intern(cast(ubyte[]) app[]);
|
||||
}
|
||||
|
||||
SemanticSymbol* allocateSemanticSymbol(string name, CompletionKind kind,
|
||||
string symbolFile, size_t location = 0, const Type type = null)
|
||||
in
|
||||
{
|
||||
assert (symbolAllocator !is null);
|
||||
}
|
||||
body
|
||||
{
|
||||
ACSymbol* acSymbol = allocate!ACSymbol(symbolAllocator,
|
||||
name is null ? name : stringCache.intern(name), kind);
|
||||
acSymbol.location = location;
|
||||
acSymbol.symbolFile = symbolFile;
|
||||
symbolsAllocated++;
|
||||
return allocate!SemanticSymbol(semanticAllocator, acSymbol, type);
|
||||
}
|
||||
|
||||
/// Current protection type
|
||||
IdType protection;
|
||||
|
||||
/// Package and module name
|
||||
string[] moduleName;
|
||||
UnrolledList!string moduleName;
|
||||
|
||||
/// Current scope
|
||||
Scope* currentScope;
|
||||
|
|
@ -513,41 +554,47 @@ private:
|
|||
string symbolFile;
|
||||
|
||||
Module mod;
|
||||
|
||||
CAllocator semanticAllocator;
|
||||
}
|
||||
|
||||
string formatNode(T)(const T node)
|
||||
void formatNode(A, T)(ref A appender, const T node)
|
||||
{
|
||||
import formatter;
|
||||
import std.array;
|
||||
import std.conv;
|
||||
if (node is null) return "";
|
||||
auto app = appender!(char[])();
|
||||
auto f = new Formatter!(typeof(app))(app);
|
||||
if (node is null)
|
||||
return;
|
||||
auto f = scoped!(Formatter!(A*))(&appender);
|
||||
f.format(node);
|
||||
return to!string(app.data);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
string[] iotcToStringArray(const IdentifierOrTemplateChain iotc,
|
||||
string[] iotcToStringArray(A)(ref A allocator, const IdentifierOrTemplateChain iotc,
|
||||
shared(StringCache)* stringCache)
|
||||
{
|
||||
string[] parts;
|
||||
foreach (ioti; iotc.identifiersOrTemplateInstances)
|
||||
string[] retVal = cast(string[]) allocator.allocate((string[]).sizeof
|
||||
* iotc.identifiersOrTemplateInstances.length);
|
||||
foreach (i, ioti; iotc.identifiersOrTemplateInstances)
|
||||
{
|
||||
if (ioti.identifier != tok!"")
|
||||
parts ~= stringCache.intern(ioti.identifier.text);
|
||||
retVal[i] = stringCache.intern(ioti.identifier.text);
|
||||
else
|
||||
parts ~= stringCache.intern(ioti.templateInstance.identifier.text);
|
||||
retVal[i] = stringCache.intern(ioti.templateInstance.identifier.text);
|
||||
}
|
||||
return parts;
|
||||
return retVal;
|
||||
}
|
||||
|
||||
private static string convertChainToImportPath(const IdentifierChain ic)
|
||||
static string convertChainToImportPath(shared(StringCache)* stringCache,
|
||||
const IdentifierChain ic)
|
||||
{
|
||||
import std.conv;
|
||||
import std.algorithm;
|
||||
import std.range;
|
||||
import std.path;
|
||||
return to!string(ic.identifiers.map!(a => cast() a.text).join(dirSeparator).array);
|
||||
QuickAllocator!1024 q;
|
||||
auto app = Appender!(char, typeof(q), 1024)(q);
|
||||
scope(exit) q.deallocate(app.mem);
|
||||
foreach (i, ident; ic.identifiers)
|
||||
{
|
||||
app.append(ident.text);
|
||||
if (i + 1 < ic.identifiers.length)
|
||||
app.append(dirSeparator);
|
||||
}
|
||||
return stringCache.intern(cast(string) app[]);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import conversion.first;
|
|||
import actypes;
|
||||
import semantic;
|
||||
import messages;
|
||||
import stdx.lexer : StringCache;
|
||||
import std.lexer : StringCache;
|
||||
import std.allocator;
|
||||
import stupidlog;
|
||||
|
||||
/**
|
||||
* Second pass handles the following:
|
||||
|
|
@ -35,11 +37,12 @@ struct SecondPass
|
|||
{
|
||||
public:
|
||||
|
||||
this(ref FirstPass first)
|
||||
this(FirstPass first)
|
||||
{
|
||||
this.rootSymbol = first.rootSymbol;
|
||||
this.moduleScope = first.moduleScope;
|
||||
this.stringCache = first.stringCache;
|
||||
this.symbolAllocator = first.symbolAllocator;
|
||||
}
|
||||
|
||||
void run()
|
||||
|
|
@ -48,6 +51,7 @@ public:
|
|||
resolveImports(moduleScope);
|
||||
}
|
||||
|
||||
CAllocator symbolAllocator;
|
||||
SemanticSymbol* rootSymbol;
|
||||
Scope* moduleScope;
|
||||
shared(StringCache)* stringCache;
|
||||
|
|
@ -57,45 +61,74 @@ private:
|
|||
void assignToScopes(ACSymbol* currentSymbol)
|
||||
{
|
||||
Scope* s = moduleScope.getScopeByCursor(currentSymbol.location);
|
||||
s.symbols.insert(currentSymbol);
|
||||
if (currentSymbol.kind != CompletionKind.moduleName)
|
||||
s.symbols.insert(currentSymbol);
|
||||
foreach (part; currentSymbol.parts[])
|
||||
{
|
||||
std.utf.validate(part.name);
|
||||
assignToScopes(part);
|
||||
}
|
||||
}
|
||||
|
||||
// This method is really ugly due to the casts...
|
||||
static ACSymbol* createImportSymbols(ImportInformation info,
|
||||
Scope* currentScope, ACSymbol*[] moduleSymbols)
|
||||
ACSymbol* createImportSymbols(ImportInformation* info, Scope* currentScope,
|
||||
ACSymbol*[] moduleSymbols)
|
||||
in
|
||||
{
|
||||
immutable string firstPart = info.importParts[0];
|
||||
assert (info !is null);
|
||||
foreach (s; moduleSymbols)
|
||||
assert (s !is null);
|
||||
}
|
||||
body
|
||||
{
|
||||
immutable string firstPart = info.importParts[].front;
|
||||
// Log.trace("firstPart = ", firstPart);
|
||||
ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
|
||||
immutable bool found = symbols.length > 0;
|
||||
ACSymbol* firstSymbol = found
|
||||
? symbols[0] : new ACSymbol(firstPart, CompletionKind.packageName);
|
||||
? symbols[0] : allocate!ACSymbol(symbolAllocator, firstPart,
|
||||
CompletionKind.packageName);
|
||||
if (!found)
|
||||
{
|
||||
currentScope.symbols.insert(firstSymbol);
|
||||
}
|
||||
ACSymbol* currentSymbol = cast(ACSymbol*) firstSymbol;
|
||||
foreach (size_t i, string importPart; info.importParts[1 .. $])
|
||||
// Log.trace(firstSymbol.name);
|
||||
ACSymbol* currentSymbol = firstSymbol;
|
||||
size_t i = 0;
|
||||
foreach (string importPart; info.importParts[])
|
||||
{
|
||||
if (i++ == 0)
|
||||
continue;
|
||||
symbols = currentSymbol.getPartsByName(importPart);
|
||||
ACSymbol* s = symbols.length > 0
|
||||
? cast(ACSymbol*) symbols[0] : new ACSymbol(importPart, CompletionKind.packageName);
|
||||
? cast(ACSymbol*) symbols[0] : allocate!ACSymbol(symbolAllocator,
|
||||
importPart, CompletionKind.packageName);
|
||||
currentSymbol.parts.insert(s);
|
||||
currentSymbol = s;
|
||||
}
|
||||
currentSymbol.kind = CompletionKind.moduleName;
|
||||
currentSymbol.parts.insert(moduleSymbols);
|
||||
// Log.trace(currentSymbol.name);
|
||||
return currentSymbol;
|
||||
}
|
||||
|
||||
void resolveImports(Scope* currentScope)
|
||||
{
|
||||
import modulecache;
|
||||
foreach (importInfo; currentScope.importInformation)
|
||||
import std.stdio;
|
||||
foreach (importInfo; currentScope.importInformation[])
|
||||
{
|
||||
string location = ModuleCache.resolveImportLoctation(importInfo.modulePath);
|
||||
ACSymbol*[] symbols = location is null ? [] : ModuleCache.getSymbolsInModule(location);
|
||||
//////
|
||||
foreach (s; symbols)
|
||||
{
|
||||
try
|
||||
std.utf.validate(s.name);
|
||||
catch (Exception e)
|
||||
{
|
||||
writeln("Symbols in ", importInfo.modulePath, " are corrupted");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
//////
|
||||
ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbols);
|
||||
currentScope.symbols.insert(moduleSymbol);
|
||||
currentScope.symbols.insert(symbols);
|
||||
|
|
@ -109,16 +142,16 @@ private:
|
|||
}
|
||||
symbolLoop: foreach (symbol; symbols)
|
||||
{
|
||||
foreach (tup; importInfo.importedSymbols)
|
||||
foreach (tup; importInfo.importedSymbols[])
|
||||
{
|
||||
if (tup[0] != symbol.name)
|
||||
continue symbolLoop;
|
||||
if (tup[1] !is null)
|
||||
{
|
||||
ACSymbol* s = new ACSymbol(tup[1],
|
||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, tup[1],
|
||||
symbol.kind, symbol.type);
|
||||
// TODO: Compiler gets confused here, so cast the types.
|
||||
s.parts = cast(typeof(s.parts)) symbol.parts;
|
||||
s.parts.insert(symbol.parts[]);
|
||||
// TODO: Re-format callTip with new name?
|
||||
s.callTip = symbol.callTip;
|
||||
s.doc = symbol.doc;
|
||||
|
|
|
|||
|
|
@ -18,13 +18,13 @@
|
|||
|
||||
module conversion.third;
|
||||
|
||||
import stdx.d.ast;
|
||||
import stdx.d.lexer;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import conversion.second;
|
||||
import semantic;
|
||||
import actypes;
|
||||
import messages;
|
||||
|
||||
import std.allocator;
|
||||
|
||||
/**
|
||||
* Third pass handles the following:
|
||||
|
|
@ -45,6 +45,7 @@ public:
|
|||
this.moduleScope = second.moduleScope;
|
||||
this.stringCache = second.stringCache;
|
||||
this.name = name;
|
||||
this.symbolAllocator = second.symbolAllocator;
|
||||
}
|
||||
|
||||
string name;
|
||||
|
|
@ -56,6 +57,7 @@ public:
|
|||
|
||||
SemanticSymbol* rootSymbol;
|
||||
Scope* moduleScope;
|
||||
CAllocator symbolAllocator;
|
||||
|
||||
private:
|
||||
|
||||
|
|
@ -147,7 +149,11 @@ private:
|
|||
else if (t.type2.symbol !is null)
|
||||
{
|
||||
// TODO: global scoped symbol handling
|
||||
string[] symbolParts = expandSymbol(
|
||||
string[] symbolParts = cast(string[]) Mallocator.it.allocate(
|
||||
t.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances.length
|
||||
* string.sizeof);
|
||||
scope(exit) Mallocator.it.deallocate(symbolParts);
|
||||
expandSymbol(symbolParts,
|
||||
t.type2.symbol.identifierOrTemplateChain, stringCache, name);
|
||||
auto symbols = moduleScope.getSymbolsByNameAndCursor(
|
||||
symbolParts[0], location);
|
||||
|
|
@ -168,12 +174,9 @@ private:
|
|||
return s;
|
||||
}
|
||||
|
||||
static string[] expandSymbol(const IdentifierOrTemplateChain chain,
|
||||
static void expandSymbol(string[] strings, const IdentifierOrTemplateChain chain,
|
||||
shared(StringCache)* stringCache, string n)
|
||||
{
|
||||
if (chain.identifiersOrTemplateInstances.length == 0)
|
||||
return [];
|
||||
string[] strings = new string[chain.identifiersOrTemplateInstances.length];
|
||||
for (size_t i = 0; i < chain.identifiersOrTemplateInstances.length; ++i)
|
||||
{
|
||||
auto identOrTemplate = chain.identifiersOrTemplateInstances[i];
|
||||
|
|
@ -183,21 +186,18 @@ private:
|
|||
identOrTemplate.identifier.text
|
||||
: identOrTemplate.templateInstance.identifier.text);
|
||||
}
|
||||
return strings;
|
||||
}
|
||||
|
||||
static ACSymbol* processSuffix(ACSymbol* symbol, const TypeSuffix suffix)
|
||||
ACSymbol* processSuffix(ACSymbol* symbol, const TypeSuffix suffix)
|
||||
{
|
||||
import std.container;
|
||||
import formatter;
|
||||
if (suffix.star)
|
||||
return symbol;
|
||||
if (suffix.array || suffix.type)
|
||||
{
|
||||
ACSymbol* s = new ACSymbol(null);
|
||||
s.parts = new RedBlackTree!(ACSymbol*, comparitor, true);
|
||||
s.parts.insert(suffix.array ? (cast() arraySymbols)[]
|
||||
: (cast() assocArraySymbols)[]);
|
||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, null);
|
||||
s.parts.insert(suffix.array ? arraySymbols[]
|
||||
: assocArraySymbols[]);
|
||||
s.type = symbol;
|
||||
s.qualifier = suffix.array ? SymbolQualifier.array : SymbolQualifier.assocArray;
|
||||
return s;
|
||||
|
|
@ -205,10 +205,17 @@ private:
|
|||
if (suffix.parameters)
|
||||
{
|
||||
import conversion.first;
|
||||
ACSymbol* s = new ACSymbol(null);
|
||||
import memory.allocators;
|
||||
import memory.appender;
|
||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, null);
|
||||
s.type = symbol;
|
||||
s.qualifier = SymbolQualifier.func;
|
||||
s.callTip = suffix.delegateOrFunction.text ~ formatNode(suffix.parameters);
|
||||
QuickAllocator!1024 q;
|
||||
auto app = Appender!(char, typeof(q), 1024)(q);
|
||||
scope(exit) q.deallocate(app.mem);
|
||||
app.append(suffix.delegateOrFunction.text);
|
||||
app.formatNode(suffix.parameters);
|
||||
s.callTip = stringCache.intern(cast(ubyte[]) app[]);
|
||||
return s;
|
||||
}
|
||||
return null;
|
||||
|
|
@ -219,9 +226,8 @@ private:
|
|||
string stringRepresentation = str(type2.builtinType);
|
||||
if (stringRepresentation is null) return null;
|
||||
// TODO: Make this use binary search instead
|
||||
auto t = cast() builtinSymbols;
|
||||
ACSymbol s = ACSymbol(stringRepresentation);
|
||||
return t.equalRange(&s).front();
|
||||
return builtinSymbols.equalRange(&s).front();
|
||||
}
|
||||
|
||||
shared(StringCache)* stringCache;
|
||||
|
|
|
|||
2
dscanner
2
dscanner
|
|
@ -1 +1 @@
|
|||
Subproject commit 3ddac7885f373c0e5ce7ff1b2670d401d8d482d5
|
||||
Subproject commit 017b90e31f2d8bdc0181fa3ac0d6a0e3be0d480e
|
||||
161
modulecache.d
161
modulecache.d
|
|
@ -18,41 +18,49 @@
|
|||
|
||||
module modulecache;
|
||||
|
||||
import std.file;
|
||||
import std.datetime;
|
||||
import stdx.lexer;
|
||||
import stdx.d.lexer;
|
||||
import stdx.d.parser;
|
||||
import stdx.d.ast;
|
||||
import std.array;
|
||||
import std.path;
|
||||
import std.algorithm;
|
||||
import std.allocator;
|
||||
import std.conv;
|
||||
import std.container;
|
||||
import std.d.ast;
|
||||
import std.datetime;
|
||||
import std.d.lexer;
|
||||
import std.d.parser;
|
||||
import std.file;
|
||||
import std.lexer;
|
||||
import std.path;
|
||||
|
||||
import actypes;
|
||||
import semantic;
|
||||
import memory.allocators;
|
||||
import containers.karytree;
|
||||
import containers.hashset;
|
||||
import containers.unrolledlist;
|
||||
import conversion.astconverter;
|
||||
import conversion.first;
|
||||
import conversion.second;
|
||||
import conversion.third;
|
||||
import containers.dynamicarray;
|
||||
import stupidlog;
|
||||
|
||||
bool cacheComparitor(CacheEntry* a, CacheEntry* b) pure nothrow
|
||||
{
|
||||
return cast(ubyte[]) a.path < cast(ubyte[]) b.path;
|
||||
}
|
||||
import messages;
|
||||
|
||||
private struct CacheEntry
|
||||
{
|
||||
ACSymbol*[] symbols;
|
||||
SysTime modificationTime;
|
||||
string path;
|
||||
|
||||
int opCmp(ref const CacheEntry other) const
|
||||
{
|
||||
if (path < other.path)
|
||||
return -1;
|
||||
if (path > other.path)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void opAssign(ref const CacheEntry other)
|
||||
{
|
||||
this.symbols = cast(typeof(symbols)) other.symbols;
|
||||
this.path = other.path;
|
||||
this.modificationTime = other.modificationTime;
|
||||
assert(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -66,8 +74,8 @@ bool existanceCheck(A)(A path)
|
|||
|
||||
static this()
|
||||
{
|
||||
ModuleCache.cache = new RedBlackTree!(CacheEntry*, cacheComparitor);
|
||||
ModuleCache.stringCache = new shared StringCache(StringCache.defaultBucketCount);
|
||||
ModuleCache.symbolAllocator = new CAllocatorImpl!(BlockAllocator!(1024 * 16));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -77,12 +85,8 @@ struct ModuleCache
|
|||
{
|
||||
@disable this();
|
||||
|
||||
/**
|
||||
* Clears the completion cache
|
||||
*/
|
||||
static void clear()
|
||||
{
|
||||
cache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -91,15 +95,13 @@ struct ModuleCache
|
|||
static void addImportPaths(string[] paths)
|
||||
{
|
||||
import core.memory;
|
||||
string[] addedPaths = paths.filter!(a => existanceCheck(a)).array();
|
||||
importPaths ~= addedPaths;
|
||||
foreach (path; paths.filter!(a => existanceCheck(a)))
|
||||
importPaths.insert(path);
|
||||
|
||||
foreach (path; addedPaths)
|
||||
foreach (path; importPaths[])
|
||||
{
|
||||
foreach (fileName; dirEntries(path, "*.{d,di}", SpanMode.depth))
|
||||
{
|
||||
GC.disable();
|
||||
scope(exit) GC.enable();
|
||||
getSymbolsInModule(fileName);
|
||||
}
|
||||
}
|
||||
|
|
@ -126,29 +128,35 @@ struct ModuleCache
|
|||
|
||||
Log.info("Getting symbols for ", location);
|
||||
|
||||
recursionGuard[location] = true;
|
||||
recursionGuard.insert(location);
|
||||
|
||||
ACSymbol*[] symbols;
|
||||
try
|
||||
{
|
||||
// try
|
||||
// {
|
||||
import core.memory;
|
||||
import std.stdio;
|
||||
import std.typecons;
|
||||
File f = File(location);
|
||||
ubyte[] source = (cast(ubyte*) GC.malloc(cast(size_t) f.size,
|
||||
GC.BlkAttr.NO_SCAN | GC.BlkAttr.NO_MOVE))[0 .. cast(size_t)f.size];
|
||||
ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(cast(size_t)f.size);
|
||||
f.rawRead(source);
|
||||
LexerConfig config;
|
||||
config.fileName = location;
|
||||
shared(StringCache)* cache = new shared StringCache(StringCache.defaultBucketCount);
|
||||
auto tokens = source.byToken(config, cache).array();
|
||||
source[] = 0;
|
||||
GC.free(source.ptr);
|
||||
ParseAllocator p = new ParseAllocator(location);
|
||||
Module m = parseModuleSimple(tokens, location, p);
|
||||
shared parseStringCache = shared StringCache(StringCache.defaultBucketCount);
|
||||
auto semanticAllocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 64)));
|
||||
DynamicArray!(Token, false) tokens;
|
||||
auto tokenRange = byToken(
|
||||
(source.length >= 3 && source[0 .. 3] == "\xef\xbb\xbf"c) ? source[3 .. $] : source,
|
||||
config, &parseStringCache);
|
||||
foreach (t; tokenRange)
|
||||
tokens.insert(t);
|
||||
Mallocator.it.deallocate(source);
|
||||
|
||||
FirstPass first = new FirstPass(m, location, stringCache);
|
||||
Module m = parseModuleSimple(tokens[], location, semanticAllocator);
|
||||
|
||||
assert (symbolAllocator);
|
||||
auto first = scoped!FirstPass(m, location, stringCache,
|
||||
symbolAllocator, semanticAllocator);
|
||||
first.run();
|
||||
cache = null;
|
||||
|
||||
SecondPass second = SecondPass(first);
|
||||
second.run();
|
||||
|
|
@ -156,21 +164,28 @@ struct ModuleCache
|
|||
ThirdPass third = ThirdPass(second, location);
|
||||
third.run();
|
||||
|
||||
p.deallocateAll();
|
||||
p = null;
|
||||
symbols = third.rootSymbol.acSymbol.parts.array();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Log.error("Couln't parse ", location, " due to exception: ", ex.msg);
|
||||
return [];
|
||||
}
|
||||
symbols = cast(ACSymbol*[]) Mallocator.it.allocate(
|
||||
third.rootSymbol.acSymbol.parts.length * (ACSymbol*).sizeof);
|
||||
size_t i = 0;
|
||||
foreach (part; third.rootSymbol.acSymbol.parts[])
|
||||
symbols[i++] = part;
|
||||
|
||||
typeid(Scope).destroy(third.moduleScope);
|
||||
typeid(SemanticSymbol).destroy(third.rootSymbol);
|
||||
symbolsAllocated += first.symbolsAllocated;
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// Log.error("Couln't parse ", location, " due to exception: ", ex.msg);
|
||||
// return [];
|
||||
// }
|
||||
SysTime access;
|
||||
SysTime modification;
|
||||
getTimes(location, access, modification);
|
||||
CacheEntry* c = new CacheEntry(symbols, modification, location);
|
||||
CacheEntry* c = allocate!CacheEntry(Mallocator.it, symbols,
|
||||
modification, stringCache.intern(location));
|
||||
cache.insert(c);
|
||||
recursionGuard[location] = false;
|
||||
recursionGuard.remove(location);
|
||||
return symbols;
|
||||
}
|
||||
|
||||
|
|
@ -188,39 +203,37 @@ struct ModuleCache
|
|||
string[] alternatives;
|
||||
foreach (path; importPaths)
|
||||
{
|
||||
string filePath = buildPath(path, moduleName);
|
||||
if (exists(filePath ~ ".d") && isFile(filePath ~ ".d"))
|
||||
alternatives = (filePath ~ ".d") ~ alternatives;
|
||||
else if (exists(filePath ~ ".di") && isFile(filePath ~ ".di"))
|
||||
alternatives = (filePath ~ ".di") ~ alternatives;
|
||||
else if (exists(filePath) && isDir(filePath))
|
||||
string dotDi = buildPath(path, moduleName) ~ ".di";
|
||||
string dotD = dotDi[0 .. $ - 1];
|
||||
string withoutSuffix = dotDi[0 .. $ - 2];
|
||||
if (exists(dotD) && isFile(dotD))
|
||||
alternatives = (dotD) ~ alternatives;
|
||||
else if (exists(dotDi) && isFile(dotDi))
|
||||
alternatives ~= dotDi;
|
||||
else if (exists(withoutSuffix) && isDir(withoutSuffix))
|
||||
{
|
||||
string packagePath = buildPath(filePath, "package.d");
|
||||
string packagePath = buildPath(withoutSuffix, "package.di");
|
||||
if (exists(packagePath) && isFile(packagePath))
|
||||
{
|
||||
alternatives ~= packagePath;
|
||||
continue;
|
||||
}
|
||||
packagePath ~= "i";
|
||||
if (exists(packagePath) && isFile(packagePath))
|
||||
alternatives ~= packagePath;
|
||||
if (exists(packagePath[0 .. $ - 1]) && isFile(packagePath[0 .. $ - 1]))
|
||||
alternatives ~= packagePath[0 .. $ - 1];
|
||||
}
|
||||
}
|
||||
return alternatives.length > 0 ? alternatives[0] : null;
|
||||
}
|
||||
|
||||
static const(string[]) getImportPaths()
|
||||
static auto getImportPaths()
|
||||
{
|
||||
return cast(const(string[])) importPaths;
|
||||
}
|
||||
|
||||
static string intern(string s)
|
||||
{
|
||||
return s is null || s.length == 0 ? "" : stringCache.intern(s);
|
||||
return importPaths[];
|
||||
}
|
||||
|
||||
static shared(StringCache)* stringCache;
|
||||
|
||||
static uint symbolsAllocated;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
|
|
@ -231,9 +244,7 @@ private:
|
|||
*/
|
||||
static bool needsReparsing(string mod)
|
||||
{
|
||||
if (mod !in recursionGuard)
|
||||
return true;
|
||||
if (recursionGuard[mod])
|
||||
if (recursionGuard.contains(mod))
|
||||
return false;
|
||||
if (!exists(mod))
|
||||
return true;
|
||||
|
|
@ -249,10 +260,12 @@ private:
|
|||
}
|
||||
|
||||
// Mapping of file paths to their cached symbols.
|
||||
static RedBlackTree!(CacheEntry*, cacheComparitor) cache;
|
||||
static KAryTree!(CacheEntry*) cache;
|
||||
|
||||
static bool[string] recursionGuard;
|
||||
static HashSet!string recursionGuard;
|
||||
|
||||
// Listing of paths to check for imports
|
||||
static string[] importPaths;
|
||||
static UnrolledList!string importPaths;
|
||||
|
||||
static CAllocator symbolAllocator;
|
||||
}
|
||||
|
|
|
|||
59
semantic.d
59
semantic.d
|
|
@ -20,9 +20,10 @@ module semantic;
|
|||
|
||||
import messages;
|
||||
import actypes;
|
||||
import stdx.d.ast;
|
||||
import stdx.d.lexer;
|
||||
import std.d.ast;
|
||||
import std.d.lexer;
|
||||
import stupidlog;
|
||||
import containers.unrolledlist;
|
||||
|
||||
/**
|
||||
* Intermediate form between ACSymbol and the AST classes. Stores enough
|
||||
|
|
@ -33,6 +34,7 @@ struct SemanticSymbol
|
|||
public:
|
||||
|
||||
@disable this();
|
||||
@disable this(this);
|
||||
|
||||
/**
|
||||
* Params:
|
||||
|
|
@ -41,21 +43,24 @@ public:
|
|||
* symbolFile = the file name for this symbol
|
||||
* location = the location of this symbol
|
||||
*/
|
||||
this(string name, CompletionKind kind, string symbolFile,
|
||||
size_t location = size_t.max, const Type type = null)
|
||||
this(ACSymbol* acSymbol, const Type type = null)
|
||||
{
|
||||
acSymbol = new ACSymbol(name, kind);
|
||||
acSymbol.location = location;
|
||||
acSymbol.symbolFile = symbolFile;
|
||||
this.acSymbol = acSymbol;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
~this()
|
||||
{
|
||||
foreach (child; children[])
|
||||
typeid(typeof(*child)).destroy(child);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a child to the children field and updates the acSymbol's parts field
|
||||
*/
|
||||
void addChild(SemanticSymbol* child)
|
||||
{
|
||||
children ~= child;
|
||||
children.insert(child);
|
||||
acSymbol.parts.insert(child.acSymbol);
|
||||
}
|
||||
|
||||
|
|
@ -63,16 +68,16 @@ public:
|
|||
ACSymbol* acSymbol;
|
||||
|
||||
/// Base classes
|
||||
string[][] baseClasses;
|
||||
UnrolledList!(string[]) baseClasses;
|
||||
|
||||
/// Variable type or function return type
|
||||
const Type type;
|
||||
|
||||
/// Alias this symbols
|
||||
string[] aliasThis;
|
||||
UnrolledList!(string) aliasThis;
|
||||
|
||||
/// MixinTemplates
|
||||
string[] mixinTemplates;
|
||||
UnrolledList!(string) mixinTemplates;
|
||||
|
||||
/// Protection level for this symobol
|
||||
IdType protection;
|
||||
|
|
@ -81,7 +86,7 @@ public:
|
|||
SemanticSymbol* parent;
|
||||
|
||||
/// Child symbols
|
||||
SemanticSymbol*[] children;
|
||||
UnrolledList!(SemanticSymbol*) children;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -96,25 +101,29 @@ Type argumentsType;
|
|||
|
||||
static this()
|
||||
{
|
||||
import std.allocator;
|
||||
// _argptr has type void*
|
||||
argptrType = new Type;
|
||||
argptrType.type2 = new Type2;
|
||||
argptrType = allocate!Type(Mallocator.it);
|
||||
argptrType.type2 = allocate!Type2(Mallocator.it);
|
||||
argptrType.type2.builtinType = tok!"void";
|
||||
TypeSuffix argptrTypeSuffix = new TypeSuffix;
|
||||
TypeSuffix argptrTypeSuffix = allocate!TypeSuffix(Mallocator.it);
|
||||
argptrTypeSuffix.star = true;
|
||||
argptrType.typeSuffixes ~= argptrTypeSuffix;
|
||||
argptrType.typeSuffixes = cast(TypeSuffix[]) Mallocator.it.allocate(TypeSuffix.sizeof);
|
||||
argptrType.typeSuffixes[0] = argptrTypeSuffix;
|
||||
|
||||
// _arguments has type TypeInfo[]
|
||||
argumentsType = new Type;
|
||||
argumentsType = new Type;
|
||||
argumentsType.type2 = new Type2;
|
||||
argumentsType.type2.symbol = new Symbol;
|
||||
argumentsType.type2.symbol.identifierOrTemplateChain = new IdentifierOrTemplateChain;
|
||||
IdentifierOrTemplateInstance i = new IdentifierOrTemplateInstance;
|
||||
argumentsType = allocate!Type(Mallocator.it);
|
||||
argumentsType.type2 = allocate!Type2(Mallocator.it);
|
||||
argumentsType.type2.symbol = allocate!Symbol(Mallocator.it);
|
||||
argumentsType.type2.symbol.identifierOrTemplateChain = allocate!IdentifierOrTemplateChain(Mallocator.it);
|
||||
IdentifierOrTemplateInstance i = allocate!IdentifierOrTemplateInstance(Mallocator.it);
|
||||
i.identifier.text = "TypeInfo";
|
||||
i.identifier.type = tok!"identifier";
|
||||
argumentsType.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances ~= i;
|
||||
TypeSuffix argumentsTypeSuffix = new TypeSuffix;
|
||||
argumentsType.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances =
|
||||
cast(IdentifierOrTemplateInstance[]) Mallocator.it.allocate(IdentifierOrTemplateInstance.sizeof);
|
||||
argumentsType.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances[0] = i;
|
||||
TypeSuffix argumentsTypeSuffix = allocate!TypeSuffix(Mallocator.it);
|
||||
argumentsTypeSuffix.array = true;
|
||||
argumentsType.typeSuffixes ~= argptrTypeSuffix;
|
||||
argumentsType.typeSuffixes = cast(TypeSuffix[]) Mallocator.it.allocate(TypeSuffix.sizeof);
|
||||
argumentsType.typeSuffixes[0] = argptrTypeSuffix;
|
||||
}
|
||||
|
|
|
|||
25
server.d
25
server.d
|
|
@ -28,6 +28,9 @@ import std.array;
|
|||
import std.process;
|
||||
import std.datetime;
|
||||
import std.conv;
|
||||
import std.allocator;
|
||||
|
||||
import core.memory;
|
||||
|
||||
import msgpack;
|
||||
|
||||
|
|
@ -92,12 +95,16 @@ int main(string[] args)
|
|||
ModuleCache.addImportPaths(importPaths);
|
||||
Log.info("Import directories: ", ModuleCache.getImportPaths());
|
||||
|
||||
ubyte[] buffer = new ubyte[1024 * 1024 * 4]; // 4 megabytes should be enough for anybody...
|
||||
ubyte[] buffer = cast(ubyte[]) Mallocator.it.allocate(1024 * 1024 * 4); // 4 megabytes should be enough for anybody...
|
||||
scope(exit) Mallocator.it.deallocate(buffer);
|
||||
|
||||
sw.stop();
|
||||
Log.info("Startup completed in ", sw.peek().to!("msecs", float), " milliseconds");
|
||||
float internBytes = cast(float) ModuleCache.stringCache.allocated / (1024 * 1024);
|
||||
Log.info("String interning took up ", internBytes, " megabytes");
|
||||
float symbolMegs = (cast(float) (ACSymbol.sizeof * ModuleCache.symbolsAllocated)) / (1024f * 1024f);
|
||||
Log.info(ModuleCache.symbolsAllocated, " symbols allocated, taking up ",
|
||||
symbolMegs, " megabytes");
|
||||
|
||||
// No relative paths
|
||||
version (Posix) chdir("/");
|
||||
|
|
@ -153,17 +160,17 @@ int main(string[] args)
|
|||
Log.info("Shutting down.");
|
||||
break serverLoop;
|
||||
case RequestKind.autocomplete:
|
||||
try
|
||||
{
|
||||
// try
|
||||
// {
|
||||
AutocompleteResponse response = complete(request);
|
||||
ubyte[] responseBytes = msgpack.pack(response);
|
||||
s.send(responseBytes);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Log.error("Could not handle autocomplete request due to an exception:",
|
||||
e.msg);
|
||||
}
|
||||
// }
|
||||
// catch (Exception e)
|
||||
// {
|
||||
// Log.error("Could not handle autocomplete request due to an exception:",
|
||||
// e.msg);
|
||||
// }
|
||||
break;
|
||||
case RequestKind.doc:
|
||||
try
|
||||
|
|
|
|||
Loading…
Reference in New Issue