Code cleanup
This commit is contained in:
parent
3763c4a47c
commit
19c84685a5
|
@ -278,13 +278,12 @@ struct Scope
|
|||
*/
|
||||
ACSymbol*[] getSymbolsByName(string name)
|
||||
{
|
||||
import std.range;
|
||||
ACSymbol s = ACSymbol(name);
|
||||
auto er = symbols.equalRange(&s);
|
||||
if (!er.empty)
|
||||
return array(er);
|
||||
|
||||
// Check symbols from "with" statement
|
||||
// Check symbols from "with" statement
|
||||
ACSymbol ir2 = ACSymbol(WITH_SYMBOL_NAME);
|
||||
auto r2 = symbols.equalRange(&ir2);
|
||||
if (!r2.empty)
|
||||
|
@ -412,6 +411,11 @@ private immutable(string[24]) builtinTypeNames;
|
|||
* static construction.
|
||||
*/
|
||||
immutable string IMPORT_SYMBOL_NAME;
|
||||
|
||||
/**
|
||||
* Name given to the symbol in a "with" expression. Initialized during a static
|
||||
* constructor.
|
||||
*/
|
||||
immutable string WITH_SYMBOL_NAME;
|
||||
|
||||
/**
|
||||
|
@ -676,10 +680,5 @@ static this()
|
|||
ucent_.type = ucent_;
|
||||
builtinSymbols.insert(void_);
|
||||
void_.type = void_;
|
||||
|
||||
// writeln(">>Builtin symbols");
|
||||
// foreach (symbol; builtinSymbols[])
|
||||
// writeln(symbol.name, " ", symbol.name.ptr);
|
||||
// writeln("<<Builtin symbols");
|
||||
}
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ public AutocompleteResponse complete(const AutocompleteRequest request)
|
|||
*/
|
||||
public AutocompleteResponse symbolSearch(const AutocompleteRequest request)
|
||||
{
|
||||
import containers.ttree;
|
||||
import containers.ttree : TTree;
|
||||
|
||||
LexerConfig config;
|
||||
config.fileName = "";
|
||||
|
|
|
@ -177,6 +177,9 @@ immutable string[] versions = [
|
|||
"X86_64"
|
||||
];
|
||||
|
||||
/**
|
||||
* Compiler-defined values for version() conditions.
|
||||
*/
|
||||
immutable string[] predefinedVersions = [
|
||||
"AArch64",
|
||||
"AIX",
|
||||
|
|
|
@ -47,11 +47,20 @@ import string_interning;
|
|||
*/
|
||||
final class FirstPass : ASTVisitor
|
||||
{
|
||||
/**
|
||||
* Params:
|
||||
* mod = the module to visit
|
||||
* symbolFile = path to the file being converted
|
||||
* symbolAllocator = allocator used for the auto-complete symbols
|
||||
* semanticAllocator = allocator used for semantic symbols
|
||||
*/
|
||||
this(Module mod, string symbolFile, CAllocator symbolAllocator,
|
||||
CAllocator semanticAllocator)
|
||||
in
|
||||
{
|
||||
assert (mod);
|
||||
assert (symbolAllocator);
|
||||
assert (semanticAllocator);
|
||||
}
|
||||
body
|
||||
{
|
||||
|
@ -61,6 +70,9 @@ final class FirstPass : ASTVisitor
|
|||
this.semanticAllocator = semanticAllocator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs the against the AST and produces symbols.
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
visit(mod);
|
||||
|
@ -340,8 +352,8 @@ final class FirstPass : ASTVisitor
|
|||
|
||||
override void visit(const ImportDeclaration importDeclaration)
|
||||
{
|
||||
import std.typecons;
|
||||
import std.algorithm;
|
||||
import std.typecons : Tuple;
|
||||
import std.algorithm : filter;
|
||||
// Log.trace(__FUNCTION__, " ImportDeclaration");
|
||||
foreach (single; importDeclaration.singleImports.filter!(
|
||||
a => a !is null && a.identifierChain !is null))
|
||||
|
@ -401,8 +413,8 @@ final class FirstPass : ASTVisitor
|
|||
|
||||
override void visit(const VersionCondition versionCondition)
|
||||
{
|
||||
import std.algorithm;
|
||||
import constants;
|
||||
import std.algorithm : canFind;
|
||||
import constants : predefinedVersions;
|
||||
// TODO: This is a bit of a hack
|
||||
if (predefinedVersions.canFind(versionCondition.token.text))
|
||||
versionCondition.accept(this);
|
||||
|
@ -491,8 +503,10 @@ final class FirstPass : ASTVisitor
|
|||
/// The module
|
||||
SemanticSymbol* rootSymbol;
|
||||
|
||||
/// Allocator used for symbol allocation
|
||||
CAllocator symbolAllocator;
|
||||
|
||||
/// Number of symbols allocated
|
||||
uint symbolsAllocated;
|
||||
|
||||
private:
|
||||
|
@ -515,12 +529,11 @@ private:
|
|||
symbol.protection = protection;
|
||||
symbol.acSymbol.doc = internString(dec.comment);
|
||||
|
||||
size_t scopeBegin = dec.name.index + dec.name.text.length;
|
||||
size_t scopeEnd = void;
|
||||
immutable size_t scopeBegin = dec.name.index + dec.name.text.length;
|
||||
static if (is (AggType == const(TemplateDeclaration)))
|
||||
scopeEnd = dec.endLocation;
|
||||
immutable size_t scopeEnd = dec.endLocation;
|
||||
else
|
||||
scopeEnd = dec.structBody is null ? scopeBegin : dec.structBody.endLocation;
|
||||
immutable size_t scopeEnd = dec.structBody is null ? scopeBegin : dec.structBody.endLocation;
|
||||
Scope* s = allocate!Scope(semanticAllocator, scopeBegin, scopeEnd);
|
||||
s.parent = currentScope;
|
||||
currentScope.children.insert(s);
|
||||
|
@ -752,7 +765,7 @@ string[] iotcToStringArray(A)(ref A allocator, const IdentifierOrTemplateChain i
|
|||
|
||||
static string convertChainToImportPath(const IdentifierChain ic)
|
||||
{
|
||||
import std.path;
|
||||
import std.path : dirSeparator;
|
||||
QuickAllocator!1024 q;
|
||||
auto app = Appender!(char, typeof(q), 1024)(q);
|
||||
scope(exit) q.deallocate(app.mem);
|
||||
|
|
|
@ -112,9 +112,12 @@ private:
|
|||
}
|
||||
body
|
||||
{
|
||||
// top-level package name
|
||||
immutable string firstPart = info.importParts[].front;
|
||||
ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
|
||||
|
||||
// top-level package symbol
|
||||
ACSymbol* firstSymbol = void;
|
||||
ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
|
||||
if (symbols.length > 0)
|
||||
firstSymbol = symbols[0];
|
||||
else
|
||||
|
@ -124,13 +127,14 @@ private:
|
|||
size_t i = 0;
|
||||
foreach (string importPart; info.importParts[])
|
||||
{
|
||||
if (i++ == 0)
|
||||
i++;
|
||||
if (i == 1) // Skip the top-level package
|
||||
continue;
|
||||
if (i + 2 >= info.importParts.length) // Skip the last item as it's the module name
|
||||
break;
|
||||
symbols = currentSymbol.getPartsByName(importPart);
|
||||
ACSymbol* s = null;
|
||||
if (symbols.length > 0) foreach (sy; symbols)
|
||||
foreach (sy; symbols)
|
||||
{
|
||||
if (sy.kind == CompletionKind.packageName)
|
||||
{
|
||||
|
@ -147,19 +151,29 @@ private:
|
|||
return currentSymbol;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates or adds symbols to the given scope based off of the import
|
||||
* statements contained therein.
|
||||
*/
|
||||
void resolveImports(Scope* currentScope)
|
||||
{
|
||||
import modulecache;
|
||||
import std.stdio;
|
||||
import modulecache : ModuleCache;
|
||||
foreach (importInfo; currentScope.importInformation[])
|
||||
{
|
||||
string location = ModuleCache.resolveImportLoctation(importInfo.modulePath);
|
||||
ACSymbol* symbol = location is null ? null : ModuleCache.getModuleSymbol(location);
|
||||
// Get symbol for the imported module
|
||||
immutable string moduleAbsPath = ModuleCache.resolveImportLoctation(
|
||||
importInfo.modulePath);
|
||||
ACSymbol* symbol = moduleAbsPath is null ? null
|
||||
: ModuleCache.getModuleSymbol(moduleAbsPath);
|
||||
if (symbol is null)
|
||||
continue;
|
||||
|
||||
ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol);
|
||||
|
||||
// if this is a selective import
|
||||
if (importInfo.importedSymbols.length == 0)
|
||||
{
|
||||
// if this import is at module scope
|
||||
if (importInfo.isPublic && currentScope.parent is null)
|
||||
rootSymbol.acSymbol.parts.insert(allocate!ACSymbol(symbolAllocator,
|
||||
IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, symbol));
|
||||
|
@ -168,9 +182,10 @@ private:
|
|||
currentScope.symbols.insert(moduleSymbol);
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (tup; importInfo.importedSymbols[])
|
||||
else foreach (tup; importInfo.importedSymbols[])
|
||||
{
|
||||
// Handle selective and renamed imports
|
||||
|
||||
ACSymbol needle = ACSymbol(tup[1]);
|
||||
ACSymbol* sym;
|
||||
auto r = symbol.parts.equalRange(&needle);
|
||||
|
@ -205,6 +220,8 @@ private:
|
|||
rootSymbol.acSymbol.parts.insert(sym);
|
||||
}
|
||||
}
|
||||
|
||||
// Recurse to child scopes
|
||||
foreach (childScope; currentScope.children)
|
||||
resolveImports(childScope);
|
||||
}
|
||||
|
|
|
@ -40,23 +40,40 @@ import string_interning;
|
|||
struct ThirdPass
|
||||
{
|
||||
public:
|
||||
this(ref SecondPass second, string name = "none") pure
|
||||
|
||||
/**
|
||||
* Params:
|
||||
* second = The second conversion pass. Results are taken from this to
|
||||
* run the third pass.
|
||||
*/
|
||||
this(ref SecondPass second) pure
|
||||
{
|
||||
this.rootSymbol = second.rootSymbol;
|
||||
this.moduleScope = second.moduleScope;
|
||||
this.name = name;
|
||||
this.symbolAllocator = second.symbolAllocator;
|
||||
}
|
||||
|
||||
string name;
|
||||
|
||||
/**
|
||||
* Runs the third pass.
|
||||
*/
|
||||
void run()
|
||||
{
|
||||
thirdPass(rootSymbol);
|
||||
}
|
||||
|
||||
/**
|
||||
* The module-level symbol
|
||||
*/
|
||||
SemanticSymbol* rootSymbol;
|
||||
|
||||
/**
|
||||
* The module-level scope
|
||||
*/
|
||||
Scope* moduleScope;
|
||||
|
||||
/**
|
||||
* The Symbol allocator
|
||||
*/
|
||||
CAllocator symbolAllocator;
|
||||
|
||||
private:
|
||||
|
@ -106,6 +123,8 @@ private:
|
|||
thirdPass(child);
|
||||
}
|
||||
|
||||
// Alias this and mixin templates are resolved after child nodes are
|
||||
// resolved so that the correct symbol information will be available.
|
||||
with (CompletionKind) switch (currentSymbol.acSymbol.kind)
|
||||
{
|
||||
case className:
|
||||
|
@ -162,7 +181,6 @@ private:
|
|||
{
|
||||
foreach (mix; currentSymbol.mixinTemplates[])
|
||||
{
|
||||
import stupidlog;
|
||||
auto symbols = moduleScope.getSymbolsByNameAndCursor(mix[0],
|
||||
currentSymbol.acSymbol.location);
|
||||
if (symbols.length == 0)
|
||||
|
@ -187,31 +205,28 @@ private:
|
|||
{
|
||||
if (initializer.empty)
|
||||
return null;
|
||||
// import stupidlog;
|
||||
// Log.trace("resolveInitializerType: ", __LINE__, ":", initializer[]);
|
||||
auto slice = initializer[];
|
||||
bool literal = slice.front[0] == '*';
|
||||
if (literal && initializer.length > 1)
|
||||
{
|
||||
// Log.trace("Popping ", slice.front, " from slice");
|
||||
slice.popFront();
|
||||
literal = false;
|
||||
}
|
||||
auto symbols = moduleScope.getSymbolsByNameAndCursor(internString(
|
||||
literal ? slice.front[1 .. $] : slice.front), location);
|
||||
|
||||
if (symbols.length == 0)
|
||||
{
|
||||
// Log.trace("Could not find ", literal ? slice.front[1 .. $] : slice.front);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (literal)
|
||||
return symbols[0];
|
||||
|
||||
slice.popFront();
|
||||
auto s = symbols[0];
|
||||
|
||||
while (s !is null && s.type !is null && !slice.empty)
|
||||
{
|
||||
s = s.type;
|
||||
// Log.trace("resolveInitializerType: ", __LINE__, ":", slice.front);
|
||||
if (slice.front == "foreach")
|
||||
{
|
||||
if (s.qualifier == SymbolQualifier.array)
|
||||
|
@ -293,7 +308,6 @@ private:
|
|||
|
||||
ACSymbol* processSuffix(ACSymbol* symbol, const TypeSuffix suffix, const Type t)
|
||||
{
|
||||
import std.d.formatter;
|
||||
if (suffix.star)
|
||||
return symbol;
|
||||
if (suffix.array || suffix.type)
|
||||
|
@ -307,9 +321,9 @@ private:
|
|||
}
|
||||
if (suffix.parameters)
|
||||
{
|
||||
import conversion.first;
|
||||
import memory.allocators;
|
||||
import memory.appender;
|
||||
import conversion.first : formatNode;
|
||||
import memory.allocators : QuickAllocator;
|
||||
import memory.appender : Appender;
|
||||
ACSymbol* s = allocate!ACSymbol(symbolAllocator, null);
|
||||
s.type = symbol;
|
||||
s.qualifier = SymbolQualifier.func;
|
||||
|
@ -325,12 +339,9 @@ private:
|
|||
|
||||
ACSymbol* convertBuiltinType(const Type2 type2)
|
||||
{
|
||||
import std.stdio;
|
||||
string stringRepresentation = getBuiltinTypeName(type2.builtinType);
|
||||
// writefln(">> %s %016X", stringRepresentation, stringRepresentation.ptr);
|
||||
ACSymbol s = ACSymbol(stringRepresentation);
|
||||
assert(s.name.ptr == stringRepresentation.ptr);
|
||||
// writefln(">> %s %016X", s.name, s.name.ptr);
|
||||
return builtinSymbols.equalRange(&s).front();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,5 +18,16 @@
|
|||
|
||||
module dcd_version;
|
||||
|
||||
enum DCD_VERSION = "v0.4.0";
|
||||
version (Windows) {} else enum GIT_HASH = import("githash.txt");
|
||||
/**
|
||||
* Human-readable version number
|
||||
*/
|
||||
enum DCD_VERSION = "v0.4.1-dev";
|
||||
|
||||
version (Windows) {}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Current build's Git commit hash
|
||||
*/
|
||||
enum GIT_HASH = import("githash.txt");
|
||||
}
|
||||
|
|
|
@ -103,7 +103,6 @@ struct ModuleCache
|
|||
*/
|
||||
static void addImportPaths(string[] paths)
|
||||
{
|
||||
import core.memory;
|
||||
foreach (path; paths.filter!(a => existanceCheck(a)))
|
||||
importPaths.insert(path);
|
||||
|
||||
|
@ -129,9 +128,9 @@ struct ModuleCache
|
|||
*/
|
||||
static ACSymbol* getModuleSymbol(string location)
|
||||
{
|
||||
import string_interning;
|
||||
import std.stdio;
|
||||
import std.typecons;
|
||||
import string_interning : internString;
|
||||
import std.stdio : File;
|
||||
import std.typecons : scoped;
|
||||
|
||||
assert (location !is null);
|
||||
|
||||
|
@ -156,17 +155,25 @@ struct ModuleCache
|
|||
immutable fileSize = cast(size_t) f.size;
|
||||
if (fileSize == 0)
|
||||
return null;
|
||||
ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(fileSize);
|
||||
f.rawRead(source);
|
||||
LexerConfig config;
|
||||
config.fileName = cachedLocation;
|
||||
auto parseStringCache = StringCache(StringCache.defaultBucketCount);
|
||||
auto semanticAllocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 64)));
|
||||
const(Token)[] tokens = getTokensForParser(
|
||||
(source.length >= 3 && source[0 .. 3] == "\xef\xbb\xbf"c) ? source[3 .. $] : source,
|
||||
config, &parseStringCache);
|
||||
Mallocator.it.deallocate(source);
|
||||
|
||||
const(Token)[] tokens;
|
||||
{
|
||||
ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(fileSize);
|
||||
scope (exit) Mallocator.it.deallocate(source);
|
||||
f.rawRead(source);
|
||||
LexerConfig config;
|
||||
config.fileName = cachedLocation;
|
||||
auto parseStringCache = StringCache(StringCache.defaultBucketCount);
|
||||
|
||||
// The first three bytes are sliced off here if the file starts with a
|
||||
// Unicode byte order mark. The lexer/parser don't handle them.
|
||||
tokens = getTokensForParser(
|
||||
(source.length >= 3 && source[0 .. 3] == "\xef\xbb\xbf"c)
|
||||
? source[3 .. $] : source,
|
||||
config, &parseStringCache);
|
||||
}
|
||||
|
||||
auto semanticAllocator = scoped!(CAllocatorImpl!(BlockAllocator!(1024 * 64)));
|
||||
Module m = parseModuleSimple(tokens[], cachedLocation, semanticAllocator);
|
||||
|
||||
assert (symbolAllocator);
|
||||
|
@ -177,7 +184,7 @@ struct ModuleCache
|
|||
SecondPass second = SecondPass(first);
|
||||
second.run();
|
||||
|
||||
ThirdPass third = ThirdPass(second, cachedLocation);
|
||||
ThirdPass third = ThirdPass(second);
|
||||
third.run();
|
||||
|
||||
symbol = third.rootSymbol.acSymbol;
|
||||
|
|
|
@ -33,7 +33,9 @@ struct SemanticSymbol
|
|||
{
|
||||
public:
|
||||
|
||||
/// Disable default construction.
|
||||
@disable this();
|
||||
/// Disable copy construction
|
||||
@disable this(this);
|
||||
|
||||
/**
|
||||
|
@ -104,7 +106,7 @@ Type argumentsType;
|
|||
|
||||
static this()
|
||||
{
|
||||
import std.allocator;
|
||||
import std.allocator : allocate;
|
||||
// _argptr has type void*
|
||||
argptrType = allocate!Type(Mallocator.it);
|
||||
argptrType.type2 = allocate!Type2(Mallocator.it);
|
||||
|
|
|
@ -42,6 +42,7 @@ import actypes;
|
|||
import core.memory;
|
||||
import dcd_version;
|
||||
|
||||
/// Name of the server configuration file
|
||||
enum CONFIG_FILE_NAME = "dcd.conf";
|
||||
|
||||
version(linux) version = useXDG;
|
||||
|
@ -252,6 +253,9 @@ string getConfigurationLocation()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints a warning message to the user when an old config file is detected.
|
||||
*/
|
||||
void warnAboutOldConfigLocation()
|
||||
{
|
||||
version (linux) if ("~/.config/dcd".expandTilde().exists()
|
||||
|
@ -282,6 +286,9 @@ string[] loadConfiguredImportDirs()
|
|||
.array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements the --help switch.
|
||||
*/
|
||||
void printHelp(string programName)
|
||||
{
|
||||
writefln(
|
||||
|
|
|
@ -20,19 +20,12 @@ module string_interning;
|
|||
|
||||
import std.d.lexer;
|
||||
|
||||
/**
|
||||
* Interns the given string and returns the interned version.
|
||||
*/
|
||||
string internString(string s)
|
||||
{
|
||||
// import std.stdio;
|
||||
// import std.string;
|
||||
// size_t* p = s in dupCheck;
|
||||
// auto r = stringCache.intern(s);
|
||||
return stringCache.intern(s);
|
||||
// if (p !is null)
|
||||
// assert (*p == cast(size_t) r.ptr, format("%s, %016x, %016x", s, *p, r.ptr));
|
||||
// else
|
||||
// dupCheck[s] = cast(size_t) r.ptr;
|
||||
// stderr.writefln("%s\t%016x", r, r.ptr);
|
||||
// return r;
|
||||
}
|
||||
|
||||
static this()
|
||||
|
|
Loading…
Reference in New Issue