Merge pull request #189 from Hackerpilot/typed-string-interning

Typed string interning
This commit is contained in:
Brian Schott 2015-02-04 07:07:55 +00:00
commit 63cbef8864
11 changed files with 251 additions and 190 deletions

@ -1 +1 @@
Subproject commit 394c27f110a94596c65f31e97207bf1ca3e60aaa Subproject commit d99c858c5a6e09ec1900a7adc125fe10ca682ec8

@ -1 +1 @@
Subproject commit 36e3bcd5d0db2fc6ba6300b168109752961330c1 Subproject commit f73bed9279602a228933b21156d8f1f2ec5e4fdd

View File

@ -31,6 +31,7 @@ import std.d.lexer;
import messages; import messages;
import string_interning; import string_interning;
public import string_interning : istring;
import std.range : isOutputRange; import std.range : isOutputRange;
@ -70,7 +71,13 @@ public:
*/ */
this(string name) nothrow @safe this(string name) nothrow @safe
{ {
this.name = name is null ? name : internString(name); this.name = name is null ? istring(null) : internString(name);
}
/// ditto
this(istring name) nothrow @safe
{
this.name = name;
} }
/** /**
@ -80,7 +87,14 @@ public:
*/ */
this(string name, CompletionKind kind) nothrow @safe @nogc this(string name, CompletionKind kind) nothrow @safe @nogc
{ {
this.name = name is null ? name : internString(name); 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; this.kind = kind;
} }
@ -92,7 +106,15 @@ public:
*/ */
this(string name, CompletionKind kind, ACSymbol* type) this(string name, CompletionKind kind, ACSymbol* type)
{ {
this.name = name is null ? name : internString(name); 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.kind = kind;
this.type = type; this.type = type;
} }
@ -120,7 +142,7 @@ public:
/** /**
* Gets all parts whose name matches the given string. * Gets all parts whose name matches the given string.
*/ */
ACSymbol*[] getPartsByName(string name) const ACSymbol*[] getPartsByName(istring name) const
{ {
import std.range : chain; import std.range : chain;
ACSymbol s = ACSymbol(name); ACSymbol s = ACSymbol(name);
@ -151,7 +173,7 @@ public:
/** /**
* Symbol's name * Symbol's name
*/ */
string name; istring name;
/** /**
* Symbols that compose this symbol, such as enum members, class variables, * Symbols that compose this symbol, such as enum members, class variables,
@ -167,12 +189,12 @@ public:
/** /**
* Module containing the symbol. * Module containing the symbol.
*/ */
string symbolFile; istring symbolFile;
/** /**
* Documentation for the symbol. * Documentation for the symbol.
*/ */
string doc; istring doc;
/** /**
* The symbol that represents the type. * The symbol that represents the type.
@ -276,7 +298,7 @@ struct Scope
* Returns: * Returns:
* all symbols in this scope or parent scopes with the given name * all symbols in this scope or parent scopes with the given name
*/ */
ACSymbol*[] getSymbolsByName(string name) const ACSymbol*[] getSymbolsByName(istring name) const
{ {
ACSymbol s = ACSymbol(name); ACSymbol s = ACSymbol(name);
auto er = symbols.equalRange(&s); auto er = symbols.equalRange(&s);
@ -325,7 +347,7 @@ struct Scope
* all symbols with the given name in the scope containing the cursor * all symbols with the given name in the scope containing the cursor
* and its parent scopes * and its parent scopes
*/ */
ACSymbol*[] getSymbolsByNameAndCursor(string name, size_t cursorPosition) const ACSymbol*[] getSymbolsByNameAndCursor(istring name, size_t cursorPosition) const
{ {
auto s = getScopeByCursor(cursorPosition); auto s = getScopeByCursor(cursorPosition);
if (s is null) if (s is null)
@ -336,7 +358,7 @@ struct Scope
/** /**
* Returns an array of symbols that are present at global scope * Returns an array of symbols that are present at global scope
*/ */
ACSymbol*[] getSymbolsAtGlobalScope(string name) const ACSymbol*[] getSymbolsAtGlobalScope(istring name) const
{ {
if (parent !is null) if (parent !is null)
return parent.getSymbolsAtGlobalScope(name); return parent.getSymbolsAtGlobalScope(name);
@ -368,11 +390,11 @@ struct Scope
struct ImportInformation struct ImportInformation
{ {
/// Import statement parts /// Import statement parts
UnrolledList!string importParts; UnrolledList!istring importParts;
/// module relative path /// module relative path
string modulePath; istring modulePath;
/// symbols to import from this module /// symbols to import from this module
UnrolledList!(Tuple!(string, string), false) importedSymbols; UnrolledList!(Tuple!(istring, istring), false) importedSymbols;
/// true if the import is public /// true if the import is public
bool isPublic; bool isPublic;
} }
@ -403,25 +425,43 @@ TTree!(ACSymbol*, true, "a < b", false) aggregateSymbols;
*/ */
TTree!(ACSymbol*, true, "a < b", false) classSymbols; TTree!(ACSymbol*, true, "a < b", false) classSymbols;
private immutable(string[24]) builtinTypeNames; private immutable(istring[24]) builtinTypeNames;
/** /// Constants for buit-in or dummy symbol names
* Name given to the public import symbol. Its value is "public" because this immutable istring IMPORT_SYMBOL_NAME;
* is not a valid identifier. This is initialized to an interned string during /// ditto
* static construction. immutable istring WITH_SYMBOL_NAME;
*/ /// ditto
immutable string IMPORT_SYMBOL_NAME; immutable istring CONSTRUCTOR_SYMBOL_NAME;
/// ditto
/** immutable istring DESTRUCTOR_SYMBOL_NAME;
* Name given to the symbol in a "with" expression. Initialized during a static /// ditto
* constructor. immutable istring ARGPTR_SYMBOL_NAME;
*/ /// ditto
immutable string WITH_SYMBOL_NAME; immutable istring ARGUMENTS_SYMBOL_NAME;
/// ditto
immutable istring THIS_SYMBOL_NAME;
/// ditto
immutable istring UNITTEST_SYMBOL_NAME;
immutable istring DOUBLE_LITERAL_SYMBOL_NAME;
immutable istring FLOAT_LITERAL_SYMBOL_NAME;
immutable istring IDOUBLE_LITERAL_SYMBOL_NAME;
immutable istring IFLOAT_LITERAL_SYMBOL_NAME;
immutable istring INT_LITERAL_SYMBOL_NAME;
immutable istring LONG_LITERAL_SYMBOL_NAME;
immutable istring REAL_LITERAL_SYMBOL_NAME;
immutable istring IREAL_LITERAL_SYMBOL_NAME;
immutable istring UINT_LITERAL_SYMBOL_NAME;
immutable istring ULONG_LITERAL_SYMBOL_NAME;
immutable istring CHAR_LITERAL_SYMBOL_NAME;
immutable istring DSTRING_LITERAL_SYMBOL_NAME;
immutable istring STRING_LITERAL_SYMBOL_NAME;
immutable istring WSTRING_LITERAL_SYMBOL_NAME;
/** /**
* Translates the IDs for built-in types into an interned string. * Translates the IDs for built-in types into an interned string.
*/ */
string getBuiltinTypeName(IdType id) nothrow pure @nogc @safe istring getBuiltinTypeName(IdType id) nothrow pure @nogc @safe
{ {
switch (id) switch (id)
{ {
@ -486,53 +526,72 @@ static this()
IMPORT_SYMBOL_NAME = internString("public"); IMPORT_SYMBOL_NAME = internString("public");
WITH_SYMBOL_NAME = internString("with"); 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");
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, internString("bool"), CompletionKind.keyword);
auto int_ = allocate!ACSymbol(Mallocator.it, internString("int"), CompletionKind.keyword);
auto long_ = allocate!ACSymbol(Mallocator.it, internString("long"), CompletionKind.keyword);
auto byte_ = allocate!ACSymbol(Mallocator.it, internString("byte"), CompletionKind.keyword);
auto char_ = allocate!ACSymbol(Mallocator.it, internString("char"), CompletionKind.keyword);
auto dchar_ = allocate!ACSymbol(Mallocator.it, internString("dchar"), CompletionKind.keyword);
auto short_ = allocate!ACSymbol(Mallocator.it, internString("short"), CompletionKind.keyword);
auto ubyte_ = allocate!ACSymbol(Mallocator.it, internString("ubyte"), CompletionKind.keyword);
auto uint_ = allocate!ACSymbol(Mallocator.it, internString("uint"), CompletionKind.keyword);
auto ulong_ = allocate!ACSymbol(Mallocator.it, internString("ulong"), CompletionKind.keyword);
auto ushort_ = allocate!ACSymbol(Mallocator.it, internString("ushort"), CompletionKind.keyword);
auto wchar_ = allocate!ACSymbol(Mallocator.it, internString("wchar"), CompletionKind.keyword);
auto bool_ = allocate!ACSymbol(Mallocator.it, "bool", CompletionKind.keyword); auto alignof_ = allocate!ACSymbol(Mallocator.it, internString("alignof"), CompletionKind.keyword);
auto int_ = allocate!ACSymbol(Mallocator.it, "int", CompletionKind.keyword); auto mangleof_ = allocate!ACSymbol(Mallocator.it, internString("mangleof"), CompletionKind.keyword);
auto long_ = allocate!ACSymbol(Mallocator.it, "long", CompletionKind.keyword); auto sizeof_ = allocate!ACSymbol(Mallocator.it, internString("sizeof"), CompletionKind.keyword);
auto byte_ = allocate!ACSymbol(Mallocator.it, "byte", CompletionKind.keyword); auto stringof_ = allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword);
auto char_ = allocate!ACSymbol(Mallocator.it, "char", CompletionKind.keyword); auto init = allocate!ACSymbol(Mallocator.it, internString("stringof"), 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 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);
arraySymbols.insert(alignof_); arraySymbols.insert(alignof_);
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "dup", CompletionKind.keyword)); arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("dup"), CompletionKind.keyword));
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "idup", CompletionKind.keyword)); arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("idup"), CompletionKind.keyword));
arraySymbols.insert(init); arraySymbols.insert(init);
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "length", CompletionKind.keyword, ulong_)); arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("length"), CompletionKind.keyword, ulong_));
arraySymbols.insert(mangleof_); arraySymbols.insert(mangleof_);
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "ptr", CompletionKind.keyword)); arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("ptr"), CompletionKind.keyword));
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "reverse", CompletionKind.keyword)); arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("reverse"), CompletionKind.keyword));
arraySymbols.insert(sizeof_); arraySymbols.insert(sizeof_);
arraySymbols.insert(allocate!ACSymbol(Mallocator.it, "sort", CompletionKind.keyword)); arraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("sort"), CompletionKind.keyword));
arraySymbols.insert(stringof_); arraySymbols.insert(stringof_);
assocArraySymbols.insert(alignof_); assocArraySymbols.insert(alignof_);
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "byKey", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("byKey"), CompletionKind.keyword));
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "byValue", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("byValue"), CompletionKind.keyword));
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "dup", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("dup"), CompletionKind.keyword));
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "get", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("get"), CompletionKind.keyword));
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword));
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "keys", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("keys"), CompletionKind.keyword));
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "length", CompletionKind.keyword, ulong_)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("length"), CompletionKind.keyword, ulong_));
assocArraySymbols.insert(mangleof_); assocArraySymbols.insert(mangleof_);
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "rehash", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("rehash"), CompletionKind.keyword));
assocArraySymbols.insert(sizeof_); assocArraySymbols.insert(sizeof_);
assocArraySymbols.insert(stringof_); assocArraySymbols.insert(stringof_);
assocArraySymbols.insert(init); assocArraySymbols.insert(init);
assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, "values", CompletionKind.keyword)); assocArraySymbols.insert(allocate!ACSymbol(Mallocator.it, internString("values"), CompletionKind.keyword));
ACSymbol*[11] integralTypeArray; ACSymbol*[11] integralTypeArray;
integralTypeArray[0] = bool_; integralTypeArray[0] = bool_;
@ -550,9 +609,9 @@ static this()
foreach (s; integralTypeArray) foreach (s; integralTypeArray)
{ {
s.parts.insert(allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("max"), CompletionKind.keyword, s));
s.parts.insert(alignof_); s.parts.insert(alignof_);
s.parts.insert(sizeof_); s.parts.insert(sizeof_);
s.parts.insert(stringof_); s.parts.insert(stringof_);
@ -560,17 +619,17 @@ static this()
s.parts.insert(init); s.parts.insert(init);
} }
auto cdouble_ = allocate!ACSymbol(Mallocator.it, "cdouble", CompletionKind.keyword); auto cdouble_ = allocate!ACSymbol(Mallocator.it, internString("cdouble"), CompletionKind.keyword);
auto cent_ = allocate!ACSymbol(Mallocator.it, "cent", CompletionKind.keyword); auto cent_ = allocate!ACSymbol(Mallocator.it, internString("cent"), CompletionKind.keyword);
auto cfloat_ = allocate!ACSymbol(Mallocator.it, "cfloat", CompletionKind.keyword); auto cfloat_ = allocate!ACSymbol(Mallocator.it, internString("cfloat"), CompletionKind.keyword);
auto creal_ = allocate!ACSymbol(Mallocator.it, "creal", CompletionKind.keyword); auto creal_ = allocate!ACSymbol(Mallocator.it, internString("creal"), CompletionKind.keyword);
auto double_ = allocate!ACSymbol(Mallocator.it, "double", CompletionKind.keyword); auto double_ = allocate!ACSymbol(Mallocator.it, internString("double"), CompletionKind.keyword);
auto float_ = allocate!ACSymbol(Mallocator.it, "float", CompletionKind.keyword); auto float_ = allocate!ACSymbol(Mallocator.it, internString("float"), CompletionKind.keyword);
auto idouble_ = allocate!ACSymbol(Mallocator.it, "idouble", CompletionKind.keyword); auto idouble_ = allocate!ACSymbol(Mallocator.it, internString("idouble"), CompletionKind.keyword);
auto ifloat_ = allocate!ACSymbol(Mallocator.it, "ifloat", CompletionKind.keyword); auto ifloat_ = allocate!ACSymbol(Mallocator.it, internString("ifloat"), CompletionKind.keyword);
auto ireal_ = allocate!ACSymbol(Mallocator.it, "ireal", CompletionKind.keyword); auto ireal_ = allocate!ACSymbol(Mallocator.it, internString("ireal"), CompletionKind.keyword);
auto real_ = allocate!ACSymbol(Mallocator.it, "real", CompletionKind.keyword); auto real_ = allocate!ACSymbol(Mallocator.it, internString("real"), CompletionKind.keyword);
auto ucent_ = allocate!ACSymbol(Mallocator.it, "ucent", CompletionKind.keyword); auto ucent_ = allocate!ACSymbol(Mallocator.it, internString("ucent"), CompletionKind.keyword);
ACSymbol*[11] floatTypeArray; ACSymbol*[11] floatTypeArray;
floatTypeArray[0] = cdouble_; floatTypeArray[0] = cdouble_;
@ -588,49 +647,49 @@ static this()
foreach (s; floatTypeArray) foreach (s; floatTypeArray)
{ {
s.parts.insert(alignof_); s.parts.insert(alignof_);
s.parts.insert(allocate!ACSymbol(Mallocator.it, "dig", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("dig"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "epsilon", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("epsilon"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "infinity", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("infinity"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "init", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("init"), CompletionKind.keyword, s));
s.parts.insert(mangleof_); s.parts.insert(mangleof_);
s.parts.insert(allocate!ACSymbol(Mallocator.it, "mant_dig", CompletionKind.keyword, int_)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("mant_dig"), CompletionKind.keyword, int_));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("max"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "max_10_exp", CompletionKind.keyword, int_)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("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, internString("max_exp"), CompletionKind.keyword, int_));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("min"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "min_exp", CompletionKind.keyword, int_)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("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, internString("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, internString("min_normal"), CompletionKind.keyword, s));
s.parts.insert(allocate!ACSymbol(Mallocator.it, "nan", CompletionKind.keyword, s)); s.parts.insert(allocate!ACSymbol(Mallocator.it, internString("nan"), CompletionKind.keyword, s));
s.parts.insert(sizeof_); s.parts.insert(sizeof_);
s.parts.insert(stringof_); s.parts.insert(stringof_);
} }
aggregateSymbols.insert(allocate!ACSymbol(Mallocator.it, "tupleof", CompletionKind.keyword)); aggregateSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("tupleof"), CompletionKind.keyword));
aggregateSymbols.insert(mangleof_); aggregateSymbols.insert(mangleof_);
aggregateSymbols.insert(alignof_); aggregateSymbols.insert(alignof_);
aggregateSymbols.insert(sizeof_); aggregateSymbols.insert(sizeof_);
aggregateSymbols.insert(stringof_); aggregateSymbols.insert(stringof_);
aggregateSymbols.insert(init); aggregateSymbols.insert(init);
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "classInfo", CompletionKind.variableName)); classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("classInfo"), CompletionKind.variableName));
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "tupleof", CompletionKind.variableName)); classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("tupleof"), CompletionKind.variableName));
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "__vptr", CompletionKind.variableName)); classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("__vptr"), CompletionKind.variableName));
classSymbols.insert(allocate!ACSymbol(Mallocator.it, "__monitor", CompletionKind.variableName)); classSymbols.insert(allocate!ACSymbol(Mallocator.it, internString("__monitor"), CompletionKind.variableName));
classSymbols.insert(mangleof_); classSymbols.insert(mangleof_);
classSymbols.insert(alignof_); classSymbols.insert(alignof_);
classSymbols.insert(sizeof_); classSymbols.insert(sizeof_);
classSymbols.insert(stringof_); classSymbols.insert(stringof_);
classSymbols.insert(init); classSymbols.insert(init);
ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, "im", CompletionKind.keyword, real_)); ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, real_));
ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, "im", CompletionKind.keyword, float_)); ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, float_));
idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, "im", CompletionKind.keyword, double_)); idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("im"), CompletionKind.keyword, double_));
ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, "re", CompletionKind.keyword, real_)); ireal_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, real_));
ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, "re", CompletionKind.keyword, float_)); ifloat_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, float_));
idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, "re", CompletionKind.keyword, double_)); idouble_.parts.insert(allocate!ACSymbol(Mallocator.it, internString("re"), CompletionKind.keyword, double_));
auto void_ = allocate!ACSymbol(Mallocator.it, "void", CompletionKind.keyword); auto void_ = allocate!ACSymbol(Mallocator.it, internString("void"), CompletionKind.keyword);
builtinSymbols.insert(bool_); builtinSymbols.insert(bool_);
bool_.type = bool_; bool_.type = bool_;

View File

@ -680,7 +680,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
case tok!"ireal": case tok!"ireal":
case tok!"creal": case tok!"creal":
case tok!"this": case tok!"this":
symbols = symbols[0].getPartsByName(str(tokens[i].type)); symbols = symbols[0].getPartsByName(internString(str(tokens[i].type)));
if (symbols.length == 0) if (symbols.length == 0)
break loop; break loop;
break; break;
@ -695,7 +695,7 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
} }
// Log.trace("looking for ", tokens[i].text, " in ", symbols[0].name); // Log.trace("looking for ", tokens[i].text, " in ", symbols[0].name);
symbols = symbols[0].getPartsByName(tokens[i].text); symbols = symbols[0].getPartsByName(internString(tokens[i].text));
if (symbols.length == 0) if (symbols.length == 0)
{ {
// Log.trace("Couldn't find it."); // Log.trace("Couldn't find it.");
@ -751,9 +751,9 @@ ACSymbol*[] getSymbolsByTokenChain(T)(Scope* completionScope,
p.setTokens(tokens[h .. i].array()); p.setTokens(tokens[h .. i].array());
ACSymbol*[] overloads; ACSymbol*[] overloads;
if (p.isSliceExpression()) if (p.isSliceExpression())
overloads = symbols[0].getPartsByName("opSlice"); overloads = symbols[0].getPartsByName(internString("opSlice"));
else else
overloads = symbols[0].getPartsByName("opIndex"); overloads = symbols[0].getPartsByName(internString("opIndex"));
if (overloads.length > 0) if (overloads.length > 0)
{ {
symbols = overloads[0].type is null ? [] : [overloads[0].type]; symbols = overloads[0].type is null ? [] : [overloads[0].type];
@ -866,7 +866,7 @@ void setCompletions(T)(ref AutocompleteResponse response,
if (symbols[0].kind == CompletionKind.structName if (symbols[0].kind == CompletionKind.structName
|| symbols[0].kind == CompletionKind.className) || symbols[0].kind == CompletionKind.className)
{ {
auto constructor = symbols[0].getPartsByName(internString("*constructor*")); auto constructor = symbols[0].getPartsByName(CONSTRUCTOR_SYMBOL_NAME);
if (constructor.length == 0) if (constructor.length == 0)
{ {
// Build a call tip out of the struct fields // Build a call tip out of the struct fields
@ -1120,18 +1120,7 @@ string formatComment(string comment)
.replaceAll(regex("\n"), `\n`).outdent(); .replaceAll(regex("\n"), `\n`).outdent();
} }
string stringToken()(auto ref const Token a) istring stringToken()(auto ref const Token a)
{ {
return a.text is null ? str(a.type) : a.text; return internString(a.text is null ? str(a.type) : a.text);
} }
//unittest
//{
// auto comment1 = "/**\n * This is some text\n */";
// auto result1 = formatComment(comment1);
// assert (result1 == `This is some text\n\n`, result1);
//
// auto comment2 = "///some\n///text";
// auto result2 = formatComment(comment2);
// assert (result2 == `some\ntext\n\n`, result2);
//}

View File

@ -28,14 +28,15 @@ import std.d.ast;
import std.d.lexer; import std.d.lexer;
import std.d.parser; import std.d.parser;
import std.typecons; import std.typecons;
import string_interning;
/** /**
* Used by autocompletion. * Used by autocompletion.
*/ */
Scope* generateAutocompleteTrees(const(Token)[] tokens, CAllocator symbolAllocator) Scope* generateAutocompleteTrees(const(Token)[] tokens, CAllocator symbolAllocator)
{ {
Module m = parseModule(tokens, "stdin", symbolAllocator, &doesNothing); Module m = parseModule(tokens, internString("stdin"), symbolAllocator, &doesNothing);
auto first = scoped!FirstPass(m, "stdin", symbolAllocator, symbolAllocator); auto first = scoped!FirstPass(m, internString("stdin"), symbolAllocator, symbolAllocator);
first.run(); first.run();
SecondPass second = SecondPass(first); SecondPass second = SecondPass(first);

View File

@ -54,7 +54,7 @@ final class FirstPass : ASTVisitor
* symbolAllocator = allocator used for the auto-complete symbols * symbolAllocator = allocator used for the auto-complete symbols
* semanticAllocator = allocator used for semantic symbols * semanticAllocator = allocator used for semantic symbols
*/ */
this(Module mod, string symbolFile, CAllocator symbolAllocator, this(Module mod, istring symbolFile, CAllocator symbolAllocator,
CAllocator semanticAllocator) CAllocator semanticAllocator)
in in
{ {
@ -82,8 +82,8 @@ final class FirstPass : ASTVisitor
{ {
// Create a dummy symbol because we don't want unit test symbols leaking // Create a dummy symbol because we don't want unit test symbols leaking
// into the symbol they're declared in. // into the symbol they're declared in.
SemanticSymbol* s = allocateSemanticSymbol(internString("*unittest*"), SemanticSymbol* s = allocateSemanticSymbol(UNITTEST_SYMBOL_NAME,
CompletionKind.dummy, null, 0); CompletionKind.dummy, istring(null), 0);
s.parent = currentSymbol; s.parent = currentSymbol;
currentSymbol.addChild(s); currentSymbol.addChild(s);
currentSymbol = s; currentSymbol = s;
@ -213,8 +213,8 @@ final class FirstPass : ASTVisitor
foreach (i, identifier; dec.autoDeclaration.identifiers) foreach (i, identifier; dec.autoDeclaration.identifiers)
{ {
SemanticSymbol* symbol = allocateSemanticSymbol( SemanticSymbol* symbol = allocateSemanticSymbol(
identifier.text, CompletionKind.variableName, symbolFile, identifier.text, CompletionKind.variableName,
identifier.index, null); symbolFile, identifier.index, null);
populateInitializer(symbol, dec.autoDeclaration.initializers[i]); populateInitializer(symbol, dec.autoDeclaration.initializers[i]);
symbol.protection = protection; symbol.protection = protection;
symbol.parent = currentSymbol; symbol.parent = currentSymbol;
@ -231,10 +231,7 @@ final class FirstPass : ASTVisitor
foreach (name; aliasDeclaration.identifierList.identifiers) foreach (name; aliasDeclaration.identifierList.identifiers)
{ {
SemanticSymbol* symbol = allocateSemanticSymbol( SemanticSymbol* symbol = allocateSemanticSymbol(
name.text, name.text, CompletionKind.aliasName, symbolFile, name.index,
CompletionKind.aliasName,
symbolFile,
name.index,
aliasDeclaration.type); aliasDeclaration.type);
symbol.protection = protection; symbol.protection = protection;
symbol.parent = currentSymbol; symbol.parent = currentSymbol;
@ -247,11 +244,8 @@ final class FirstPass : ASTVisitor
foreach (initializer; aliasDeclaration.initializers) foreach (initializer; aliasDeclaration.initializers)
{ {
SemanticSymbol* symbol = allocateSemanticSymbol( SemanticSymbol* symbol = allocateSemanticSymbol(
initializer.name.text, initializer.name.text, CompletionKind.aliasName,
CompletionKind.aliasName, symbolFile, initializer.name.index, initializer.type);
symbolFile,
initializer.name.index,
initializer.type);
symbol.protection = protection; symbol.protection = protection;
symbol.parent = currentSymbol; symbol.parent = currentSymbol;
symbol.acSymbol.doc = internString(aliasDeclaration.comment); symbol.acSymbol.doc = internString(aliasDeclaration.comment);
@ -331,8 +325,8 @@ final class FirstPass : ASTVisitor
Scope* s = allocate!Scope(semanticAllocator, structBody.startLocation, structBody.endLocation); Scope* s = allocate!Scope(semanticAllocator, structBody.startLocation, structBody.endLocation);
// Log.trace("Added scope ", s.startLocation, " ", s.endLocation); // Log.trace("Added scope ", s.startLocation, " ", s.endLocation);
ACSymbol* thisSymbol = allocate!ACSymbol(symbolAllocator, "this", ACSymbol* thisSymbol = allocate!ACSymbol(symbolAllocator,
CompletionKind.variableName, currentSymbol.acSymbol); THIS_SYMBOL_NAME, CompletionKind.variableName, currentSymbol.acSymbol);
thisSymbol.location = s.startLocation; thisSymbol.location = s.startLocation;
thisSymbol.symbolFile = symbolFile; thisSymbol.symbolFile = symbolFile;
s.symbols.insert(thisSymbol); s.symbols.insert(thisSymbol);
@ -373,7 +367,7 @@ final class FirstPass : ASTVisitor
} }
foreach (bind; importDeclaration.importBindings.importBinds) foreach (bind; importDeclaration.importBindings.importBinds)
{ {
Tuple!(string, string) bindTuple; Tuple!(istring, istring) bindTuple;
if (bind.right == tok!"") if (bind.right == tok!"")
{ {
bindTuple[1] = internString(bind.left.text); bindTuple[1] = internString(bind.left.text);
@ -514,8 +508,9 @@ private:
override void visit(const T member) override void visit(const T member)
{ {
// Log.trace(__FUNCTION__, " ", typeof(member).stringof); // Log.trace(__FUNCTION__, " ", typeof(member).stringof);
SemanticSymbol* symbol = allocateSemanticSymbol(member.name.text, SemanticSymbol* symbol = allocateSemanticSymbol(
CompletionKind.enumMember, symbolFile, member.name.index, member.type); member.name.text, CompletionKind.enumMember, symbolFile,
member.name.index, member.type);
symbol.parent = currentSymbol; symbol.parent = currentSymbol;
symbol.acSymbol.doc = internString(member.comment); symbol.acSymbol.doc = internString(member.comment);
currentSymbol.addChild(symbol); currentSymbol.addChild(symbol);
@ -561,9 +556,9 @@ private:
const TemplateParameters templateParameters, const TemplateParameters templateParameters,
const FunctionBody functionBody, string doc) const FunctionBody functionBody, string doc)
{ {
SemanticSymbol* symbol = allocateSemanticSymbol("*constructor*", SemanticSymbol* symbol = allocateSemanticSymbol(CONSTRUCTOR_SYMBOL_NAME,
CompletionKind.functionName, symbolFile, location); CompletionKind.functionName, symbolFile, location);
processParameters(symbol, null, "this", parameters, templateParameters); processParameters(symbol, null, THIS_SYMBOL_NAME, parameters, templateParameters);
symbol.protection = protection; symbol.protection = protection;
symbol.parent = currentSymbol; symbol.parent = currentSymbol;
symbol.acSymbol.doc = internString(doc); symbol.acSymbol.doc = internString(doc);
@ -584,7 +579,7 @@ private:
void visitDestructor(size_t location, const FunctionBody functionBody, string doc) void visitDestructor(size_t location, const FunctionBody functionBody, string doc)
{ {
SemanticSymbol* symbol = allocateSemanticSymbol("~this", SemanticSymbol* symbol = allocateSemanticSymbol(DESTRUCTOR_SYMBOL_NAME,
CompletionKind.functionName, symbolFile, location); CompletionKind.functionName, symbolFile, location);
symbol.acSymbol.callTip = "~this()"; symbol.acSymbol.callTip = "~this()";
symbol.protection = protection; symbol.protection = protection;
@ -622,13 +617,15 @@ private:
} }
if (parameters.hasVarargs) if (parameters.hasVarargs)
{ {
SemanticSymbol* argptr = allocateSemanticSymbol("_argptr", SemanticSymbol* argptr = allocateSemanticSymbol(ARGPTR_SYMBOL_NAME,
CompletionKind.variableName, null, size_t.max, argptrType); CompletionKind.variableName, istring(null), size_t.max,
argptrType);
argptr.parent = symbol; argptr.parent = symbol;
symbol.addChild(argptr); symbol.addChild(argptr);
SemanticSymbol* arguments = allocateSemanticSymbol("_arguments", SemanticSymbol* arguments = allocateSemanticSymbol(
CompletionKind.variableName, null, size_t.max, argumentsType); ARGUMENTS_SYMBOL_NAME, CompletionKind.variableName,
istring(null), size_t.max, argumentsType);
arguments.parent = symbol; arguments.parent = symbol;
symbol.addChild(arguments); symbol.addChild(arguments);
} }
@ -668,8 +665,8 @@ private:
} }
else else
continue; continue;
SemanticSymbol* templateParameter = allocateSemanticSymbol(name, kind, SemanticSymbol* templateParameter = allocateSemanticSymbol(name,
symbolFile, index, type); kind, symbolFile, index, type);
symbol.addChild(templateParameter); symbol.addChild(templateParameter);
templateParameter.parent = symbol; templateParameter.parent = symbol;
} }
@ -705,7 +702,7 @@ private:
} }
SemanticSymbol* allocateSemanticSymbol(string name, CompletionKind kind, SemanticSymbol* allocateSemanticSymbol(string name, CompletionKind kind,
string symbolFile, size_t location = 0, const Type type = null) istring symbolFile, size_t location = 0, const Type type = null)
in in
{ {
assert (symbolAllocator !is null); assert (symbolAllocator !is null);
@ -729,7 +726,7 @@ private:
SemanticSymbol* currentSymbol; SemanticSymbol* currentSymbol;
/// Path to the file being converted /// Path to the file being converted
string symbolFile; istring symbolFile;
Module mod; Module mod;
@ -760,9 +757,9 @@ Scope* createFunctionScope(const FunctionBody functionBody, CAllocator semanticA
return allocate!Scope(semanticAllocator, scopeBegin, scopeEnd); return allocate!Scope(semanticAllocator, scopeBegin, scopeEnd);
} }
string[] iotcToStringArray(A)(ref A allocator, const IdentifierOrTemplateChain iotc) istring[] iotcToStringArray(A)(ref A allocator, const IdentifierOrTemplateChain iotc)
{ {
string[] retVal = cast(string[]) allocator.allocate((string[]).sizeof istring[] retVal = cast(istring[]) allocator.allocate((istring[]).sizeof
* iotc.identifiersOrTemplateInstances.length); * iotc.identifiersOrTemplateInstances.length);
foreach (i, ioti; iotc.identifiersOrTemplateInstances) foreach (i, ioti; iotc.identifiersOrTemplateInstances)
{ {
@ -774,7 +771,7 @@ string[] iotcToStringArray(A)(ref A allocator, const IdentifierOrTemplateChain i
return retVal; return retVal;
} }
static string convertChainToImportPath(const IdentifierChain ic) static istring convertChainToImportPath(const IdentifierChain ic)
{ {
import std.path : dirSeparator; import std.path : dirSeparator;
QuickAllocator!1024 q; QuickAllocator!1024 q;
@ -802,7 +799,7 @@ class InitializerVisitor : ASTVisitor
override void visit(const IdentifierOrTemplateInstance ioti) override void visit(const IdentifierOrTemplateInstance ioti)
{ {
if (on && ioti.identifier != tok!"") if (on && ioti.identifier != tok!"")
semanticSymbol.initializer.insert(ioti.identifier.text); semanticSymbol.initializer.insert(internString(ioti.identifier.text));
ioti.accept(this); ioti.accept(this);
} }
@ -812,53 +809,53 @@ class InitializerVisitor : ASTVisitor
// the prefix '*' so that that the third pass can tell the difference // the prefix '*' so that that the third pass can tell the difference
// between "int.abc" and "10.abc". // between "int.abc" and "10.abc".
if (on && primary.basicType != tok!"") if (on && primary.basicType != tok!"")
semanticSymbol.initializer.insert(str(primary.basicType.type)); semanticSymbol.initializer.insert(internString(str(primary.basicType.type)));
if (on) switch (primary.primary.type) if (on) switch (primary.primary.type)
{ {
case tok!"identifier": case tok!"identifier":
semanticSymbol.initializer.insert(primary.primary.text); semanticSymbol.initializer.insert(internString(primary.primary.text));
break; break;
case tok!"doubleLiteral": case tok!"doubleLiteral":
semanticSymbol.initializer.insert("*double"); semanticSymbol.initializer.insert(DOUBLE_LITERAL_SYMBOL_NAME);
break; break;
case tok!"floatLiteral": case tok!"floatLiteral":
semanticSymbol.initializer.insert("*float"); semanticSymbol.initializer.insert(FLOAT_LITERAL_SYMBOL_NAME);
break; break;
case tok!"idoubleLiteral": case tok!"idoubleLiteral":
semanticSymbol.initializer.insert("*idouble"); semanticSymbol.initializer.insert(IDOUBLE_LITERAL_SYMBOL_NAME);
break; break;
case tok!"ifloatLiteral": case tok!"ifloatLiteral":
semanticSymbol.initializer.insert("*ifloat"); semanticSymbol.initializer.insert(IFLOAT_LITERAL_SYMBOL_NAME);
break; break;
case tok!"intLiteral": case tok!"intLiteral":
semanticSymbol.initializer.insert("*int"); semanticSymbol.initializer.insert(INT_LITERAL_SYMBOL_NAME);
break; break;
case tok!"longLiteral": case tok!"longLiteral":
semanticSymbol.initializer.insert("*long"); semanticSymbol.initializer.insert(LONG_LITERAL_SYMBOL_NAME);
break; break;
case tok!"realLiteral": case tok!"realLiteral":
semanticSymbol.initializer.insert("*real"); semanticSymbol.initializer.insert(REAL_LITERAL_SYMBOL_NAME);
break; break;
case tok!"irealLiteral": case tok!"irealLiteral":
semanticSymbol.initializer.insert("*ireal"); semanticSymbol.initializer.insert(IREAL_LITERAL_SYMBOL_NAME);
break; break;
case tok!"uintLiteral": case tok!"uintLiteral":
semanticSymbol.initializer.insert("*uint"); semanticSymbol.initializer.insert(UINT_LITERAL_SYMBOL_NAME);
break; break;
case tok!"ulongLiteral": case tok!"ulongLiteral":
semanticSymbol.initializer.insert("*ulong"); semanticSymbol.initializer.insert(ULONG_LITERAL_SYMBOL_NAME);
break; break;
case tok!"characterLiteral": case tok!"characterLiteral":
semanticSymbol.initializer.insert("*char"); semanticSymbol.initializer.insert(CHAR_LITERAL_SYMBOL_NAME);
break; break;
case tok!"dstringLiteral": case tok!"dstringLiteral":
semanticSymbol.initializer.insert("*dstring"); semanticSymbol.initializer.insert(DSTRING_LITERAL_SYMBOL_NAME);
break; break;
case tok!"stringLiteral": case tok!"stringLiteral":
semanticSymbol.initializer.insert("*string"); semanticSymbol.initializer.insert(STRING_LITERAL_SYMBOL_NAME);
break; break;
case tok!"wstringLiteral": case tok!"wstringLiteral":
semanticSymbol.initializer.insert("*wstring"); semanticSymbol.initializer.insert(WSTRING_LITERAL_SYMBOL_NAME);
break; break;
default: default:
break; break;
@ -870,7 +867,7 @@ class InitializerVisitor : ASTVisitor
{ {
unary.accept(this); unary.accept(this);
if (unary.indexExpression) if (unary.indexExpression)
semanticSymbol.initializer.insert("[]"); semanticSymbol.initializer.insert(internString("[]"));
} }
override void visit(const ArgumentList) {} override void visit(const ArgumentList) {}
@ -880,7 +877,7 @@ class InitializerVisitor : ASTVisitor
on = true; on = true;
initializer.accept(this); initializer.accept(this);
if (appendForeach) if (appendForeach)
semanticSymbol.initializer.insert("foreach"); semanticSymbol.initializer.insert(internString("foreach"));
on = false; on = false;
} }

View File

@ -113,7 +113,7 @@ private:
body body
{ {
// top-level package name // top-level package name
immutable string firstPart = info.importParts[].front; immutable istring firstPart = info.importParts[].front;
// top-level package symbol // top-level package symbol
ACSymbol* firstSymbol = void; ACSymbol* firstSymbol = void;
@ -125,7 +125,7 @@ private:
CompletionKind.packageName); CompletionKind.packageName);
ACSymbol* currentSymbol = firstSymbol; ACSymbol* currentSymbol = firstSymbol;
size_t i = 0; size_t i = 0;
foreach (string importPart; info.importParts[]) foreach (importPart; info.importParts[])
{ {
i++; i++;
if (i == 1) // Skip the top-level package if (i == 1) // Skip the top-level package

View File

@ -152,7 +152,7 @@ private:
void resolveInheritance(SemanticSymbol* currentSymbol) void resolveInheritance(SemanticSymbol* currentSymbol)
{ {
outer: foreach (string[] base; currentSymbol.baseClasses) outer: foreach (istring[] base; currentSymbol.baseClasses)
{ {
ACSymbol* baseClass; ACSymbol* baseClass;
if (base.length == 0) if (base.length == 0)
@ -283,7 +283,7 @@ private:
{ {
// TODO: global scoped symbol handling // TODO: global scoped symbol handling
size_t l = t.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances.length; size_t l = t.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances.length;
string[] symbolParts = (cast(string*) Mallocator.it.allocate(l * string.sizeof))[0 .. l]; istring[] symbolParts = (cast(istring*) Mallocator.it.allocate(l * istring.sizeof))[0 .. l];
scope(exit) Mallocator.it.deallocate(symbolParts); scope(exit) Mallocator.it.deallocate(symbolParts);
expandSymbol(symbolParts, t.type2.symbol.identifierOrTemplateChain); expandSymbol(symbolParts, t.type2.symbol.identifierOrTemplateChain);
auto symbols = moduleScope.getSymbolsByNameAndCursor( auto symbols = moduleScope.getSymbolsByNameAndCursor(
@ -305,14 +305,14 @@ private:
return s; return s;
} }
static void expandSymbol(string[] strings, const IdentifierOrTemplateChain chain) static void expandSymbol(istring[] strings, const IdentifierOrTemplateChain chain)
{ {
for (size_t i = 0; i < chain.identifiersOrTemplateInstances.length; ++i) for (size_t i = 0; i < chain.identifiersOrTemplateInstances.length; ++i)
{ {
auto identOrTemplate = chain.identifiersOrTemplateInstances[i]; auto identOrTemplate = chain.identifiersOrTemplateInstances[i];
if (identOrTemplate is null) if (identOrTemplate is null)
{ {
strings[i] = null; strings[i] = istring(null);
continue; continue;
} }
strings[i] = internString(identOrTemplate.templateInstance is null ? strings[i] = internString(identOrTemplate.templateInstance is null ?
@ -327,7 +327,7 @@ private:
return symbol; return symbol;
if (suffix.array || suffix.type) if (suffix.array || suffix.type)
{ {
ACSymbol* s = allocate!ACSymbol(symbolAllocator, null); ACSymbol* s = allocate!ACSymbol(symbolAllocator, istring(null));
s.parts.insert(suffix.array ? arraySymbols[] s.parts.insert(suffix.array ? arraySymbols[]
: assocArraySymbols[]); : assocArraySymbols[]);
s.type = symbol; s.type = symbol;
@ -339,7 +339,7 @@ private:
import conversion.first : formatNode; import conversion.first : formatNode;
import memory.allocators : QuickAllocator; import memory.allocators : QuickAllocator;
import memory.appender : Appender; import memory.appender : Appender;
ACSymbol* s = allocate!ACSymbol(symbolAllocator, null); ACSymbol* s = allocate!ACSymbol(symbolAllocator, istring(null));
s.type = symbol; s.type = symbol;
s.qualifier = SymbolQualifier.func; s.qualifier = SymbolQualifier.func;
QuickAllocator!1024 q; QuickAllocator!1024 q;
@ -354,7 +354,7 @@ private:
ACSymbol* convertBuiltinType(const Type2 type2) ACSymbol* convertBuiltinType(const Type2 type2)
{ {
string stringRepresentation = getBuiltinTypeName(type2.builtinType); istring stringRepresentation = getBuiltinTypeName(type2.builtinType);
ACSymbol s = ACSymbol(stringRepresentation); ACSymbol s = ACSymbol(stringRepresentation);
assert(s.name.ptr == stringRepresentation.ptr); assert(s.name.ptr == stringRepresentation.ptr);
return builtinSymbols.equalRange(&s).front(); return builtinSymbols.equalRange(&s).front();

View File

@ -141,7 +141,7 @@ struct ModuleCache
assert (location !is null); assert (location !is null);
string cachedLocation = internString(location); istring cachedLocation = internString(location);
if (!needsReparsing(cachedLocation)) if (!needsReparsing(cachedLocation))
{ {

View File

@ -24,6 +24,7 @@ import std.d.ast;
import std.d.lexer; import std.d.lexer;
import stupidlog; import stupidlog;
import containers.unrolledlist; import containers.unrolledlist;
import string_interning;
/** /**
* Intermediate form between ACSymbol and the AST classes. Stores enough * Intermediate form between ACSymbol and the AST classes. Stores enough
@ -70,16 +71,16 @@ public:
ACSymbol* acSymbol; ACSymbol* acSymbol;
/// Base classes /// Base classes
UnrolledList!(string[]) baseClasses; UnrolledList!(istring[]) baseClasses;
/// Variable type or function return type /// Variable type or function return type
const Type type; const Type type;
/// Alias this symbols /// Alias this symbols
UnrolledList!(string) aliasThis; UnrolledList!(istring) aliasThis;
/// MixinTemplates /// MixinTemplates
UnrolledList!(string[]) mixinTemplates; UnrolledList!(istring[]) mixinTemplates;
/// Protection level for this symobol /// Protection level for this symobol
IdType protection; IdType protection;
@ -91,7 +92,7 @@ public:
UnrolledList!(SemanticSymbol*) children; UnrolledList!(SemanticSymbol*) children;
/// Assign expression identifier chain used for auto declarations /// Assign expression identifier chain used for auto declarations
UnrolledList!(string) initializer; UnrolledList!(istring) initializer;
} }
/** /**
@ -122,7 +123,7 @@ static this()
argumentsType.type2.symbol = allocate!Symbol(Mallocator.it); argumentsType.type2.symbol = allocate!Symbol(Mallocator.it);
argumentsType.type2.symbol.identifierOrTemplateChain = allocate!IdentifierOrTemplateChain(Mallocator.it); argumentsType.type2.symbol.identifierOrTemplateChain = allocate!IdentifierOrTemplateChain(Mallocator.it);
IdentifierOrTemplateInstance i = allocate!IdentifierOrTemplateInstance(Mallocator.it); IdentifierOrTemplateInstance i = allocate!IdentifierOrTemplateInstance(Mallocator.it);
i.identifier.text = "TypeInfo"; i.identifier.text = internString("TypeInfo");
i.identifier.type = tok!"identifier"; i.identifier.type = tok!"identifier";
argumentsType.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances = argumentsType.type2.symbol.identifierOrTemplateChain.identifiersOrTemplateInstances =
cast(IdentifierOrTemplateInstance[]) Mallocator.it.allocate(IdentifierOrTemplateInstance.sizeof); cast(IdentifierOrTemplateInstance[]) Mallocator.it.allocate(IdentifierOrTemplateInstance.sizeof);

View File

@ -23,9 +23,9 @@ import std.d.lexer;
/** /**
* Interns the given string and returns the interned version. * Interns the given string and returns the interned version.
*/ */
string internString(string s) nothrow @safe @nogc istring internString(string s) nothrow @safe @nogc
{ {
return stringCache.intern(s); return istring(stringCache.intern(s));
} }
static this() static this()
@ -33,5 +33,19 @@ static this()
stringCache = StringCache(StringCache.defaultBucketCount); stringCache = StringCache(StringCache.defaultBucketCount);
} }
alias istring = InternedString;
//private size_t[string] dupCheck; //private size_t[string] dupCheck;
private StringCache stringCache = void; private StringCache stringCache = void;
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;
}