Code cleanup

This commit is contained in:
Hackerpilot 2014-12-31 00:38:46 -08:00
parent 3763c4a47c
commit 19c84685a5
11 changed files with 136 additions and 73 deletions

View File

@ -278,13 +278,12 @@ struct Scope
*/ */
ACSymbol*[] getSymbolsByName(string name) ACSymbol*[] getSymbolsByName(string name)
{ {
import std.range;
ACSymbol s = ACSymbol(name); ACSymbol s = ACSymbol(name);
auto er = symbols.equalRange(&s); auto er = symbols.equalRange(&s);
if (!er.empty) if (!er.empty)
return array(er); return array(er);
// Check symbols from "with" statement // Check symbols from "with" statement
ACSymbol ir2 = ACSymbol(WITH_SYMBOL_NAME); ACSymbol ir2 = ACSymbol(WITH_SYMBOL_NAME);
auto r2 = symbols.equalRange(&ir2); auto r2 = symbols.equalRange(&ir2);
if (!r2.empty) if (!r2.empty)
@ -412,6 +411,11 @@ private immutable(string[24]) builtinTypeNames;
* static construction. * static construction.
*/ */
immutable string IMPORT_SYMBOL_NAME; immutable string IMPORT_SYMBOL_NAME;
/**
* Name given to the symbol in a "with" expression. Initialized during a static
* constructor.
*/
immutable string WITH_SYMBOL_NAME; immutable string WITH_SYMBOL_NAME;
/** /**
@ -676,10 +680,5 @@ static this()
ucent_.type = ucent_; ucent_.type = ucent_;
builtinSymbols.insert(void_); builtinSymbols.insert(void_);
void_.type = void_; void_.type = void_;
// writeln(">>Builtin symbols");
// foreach (symbol; builtinSymbols[])
// writeln(symbol.name, " ", symbol.name.ptr);
// writeln("<<Builtin symbols");
} }

View File

@ -125,7 +125,7 @@ public AutocompleteResponse complete(const AutocompleteRequest request)
*/ */
public AutocompleteResponse symbolSearch(const AutocompleteRequest request) public AutocompleteResponse symbolSearch(const AutocompleteRequest request)
{ {
import containers.ttree; import containers.ttree : TTree;
LexerConfig config; LexerConfig config;
config.fileName = ""; config.fileName = "";

View File

@ -177,6 +177,9 @@ immutable string[] versions = [
"X86_64" "X86_64"
]; ];
/**
* Compiler-defined values for version() conditions.
*/
immutable string[] predefinedVersions = [ immutable string[] predefinedVersions = [
"AArch64", "AArch64",
"AIX", "AIX",

View File

@ -47,11 +47,20 @@ import string_interning;
*/ */
final class FirstPass : ASTVisitor 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, this(Module mod, string symbolFile, CAllocator symbolAllocator,
CAllocator semanticAllocator) CAllocator semanticAllocator)
in in
{ {
assert (mod);
assert (symbolAllocator); assert (symbolAllocator);
assert (semanticAllocator);
} }
body body
{ {
@ -61,6 +70,9 @@ final class FirstPass : ASTVisitor
this.semanticAllocator = semanticAllocator; this.semanticAllocator = semanticAllocator;
} }
/**
* Runs the against the AST and produces symbols.
*/
void run() void run()
{ {
visit(mod); visit(mod);
@ -340,8 +352,8 @@ final class FirstPass : ASTVisitor
override void visit(const ImportDeclaration importDeclaration) override void visit(const ImportDeclaration importDeclaration)
{ {
import std.typecons; import std.typecons : Tuple;
import std.algorithm; import std.algorithm : filter;
// Log.trace(__FUNCTION__, " ImportDeclaration"); // Log.trace(__FUNCTION__, " ImportDeclaration");
foreach (single; importDeclaration.singleImports.filter!( foreach (single; importDeclaration.singleImports.filter!(
a => a !is null && a.identifierChain !is null)) a => a !is null && a.identifierChain !is null))
@ -401,8 +413,8 @@ final class FirstPass : ASTVisitor
override void visit(const VersionCondition versionCondition) override void visit(const VersionCondition versionCondition)
{ {
import std.algorithm; import std.algorithm : canFind;
import constants; import constants : predefinedVersions;
// TODO: This is a bit of a hack // TODO: This is a bit of a hack
if (predefinedVersions.canFind(versionCondition.token.text)) if (predefinedVersions.canFind(versionCondition.token.text))
versionCondition.accept(this); versionCondition.accept(this);
@ -491,8 +503,10 @@ final class FirstPass : ASTVisitor
/// The module /// The module
SemanticSymbol* rootSymbol; SemanticSymbol* rootSymbol;
/// Allocator used for symbol allocation
CAllocator symbolAllocator; CAllocator symbolAllocator;
/// Number of symbols allocated
uint symbolsAllocated; uint symbolsAllocated;
private: private:
@ -515,12 +529,11 @@ private:
symbol.protection = protection; symbol.protection = protection;
symbol.acSymbol.doc = internString(dec.comment); symbol.acSymbol.doc = internString(dec.comment);
size_t scopeBegin = dec.name.index + dec.name.text.length; immutable size_t scopeBegin = dec.name.index + dec.name.text.length;
size_t scopeEnd = void;
static if (is (AggType == const(TemplateDeclaration))) static if (is (AggType == const(TemplateDeclaration)))
scopeEnd = dec.endLocation; immutable size_t scopeEnd = dec.endLocation;
else 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); Scope* s = allocate!Scope(semanticAllocator, scopeBegin, scopeEnd);
s.parent = currentScope; s.parent = currentScope;
currentScope.children.insert(s); currentScope.children.insert(s);
@ -752,7 +765,7 @@ string[] iotcToStringArray(A)(ref A allocator, const IdentifierOrTemplateChain i
static string convertChainToImportPath(const IdentifierChain ic) static string convertChainToImportPath(const IdentifierChain ic)
{ {
import std.path; import std.path : dirSeparator;
QuickAllocator!1024 q; QuickAllocator!1024 q;
auto app = Appender!(char, typeof(q), 1024)(q); auto app = Appender!(char, typeof(q), 1024)(q);
scope(exit) q.deallocate(app.mem); scope(exit) q.deallocate(app.mem);

View File

@ -112,9 +112,12 @@ private:
} }
body body
{ {
// top-level package name
immutable string firstPart = info.importParts[].front; immutable string firstPart = info.importParts[].front;
ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
// top-level package symbol
ACSymbol* firstSymbol = void; ACSymbol* firstSymbol = void;
ACSymbol*[] symbols = currentScope.getSymbolsByName(firstPart);
if (symbols.length > 0) if (symbols.length > 0)
firstSymbol = symbols[0]; firstSymbol = symbols[0];
else else
@ -124,13 +127,14 @@ private:
size_t i = 0; size_t i = 0;
foreach (string importPart; info.importParts[]) foreach (string importPart; info.importParts[])
{ {
if (i++ == 0) i++;
if (i == 1) // Skip the top-level package
continue; continue;
if (i + 2 >= info.importParts.length) // Skip the last item as it's the module name if (i + 2 >= info.importParts.length) // Skip the last item as it's the module name
break; break;
symbols = currentSymbol.getPartsByName(importPart); symbols = currentSymbol.getPartsByName(importPart);
ACSymbol* s = null; ACSymbol* s = null;
if (symbols.length > 0) foreach (sy; symbols) foreach (sy; symbols)
{ {
if (sy.kind == CompletionKind.packageName) if (sy.kind == CompletionKind.packageName)
{ {
@ -147,19 +151,29 @@ private:
return currentSymbol; return currentSymbol;
} }
/**
* Creates or adds symbols to the given scope based off of the import
* statements contained therein.
*/
void resolveImports(Scope* currentScope) void resolveImports(Scope* currentScope)
{ {
import modulecache; import modulecache : ModuleCache;
import std.stdio;
foreach (importInfo; currentScope.importInformation[]) foreach (importInfo; currentScope.importInformation[])
{ {
string location = ModuleCache.resolveImportLoctation(importInfo.modulePath); // Get symbol for the imported module
ACSymbol* symbol = location is null ? null : ModuleCache.getModuleSymbol(location); immutable string moduleAbsPath = ModuleCache.resolveImportLoctation(
importInfo.modulePath);
ACSymbol* symbol = moduleAbsPath is null ? null
: ModuleCache.getModuleSymbol(moduleAbsPath);
if (symbol is null) if (symbol is null)
continue; continue;
ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol); ACSymbol* moduleSymbol = createImportSymbols(importInfo, currentScope, symbol);
// if this is a selective import
if (importInfo.importedSymbols.length == 0) if (importInfo.importedSymbols.length == 0)
{ {
// if this import is at module scope
if (importInfo.isPublic && currentScope.parent is null) if (importInfo.isPublic && currentScope.parent is null)
rootSymbol.acSymbol.parts.insert(allocate!ACSymbol(symbolAllocator, rootSymbol.acSymbol.parts.insert(allocate!ACSymbol(symbolAllocator,
IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, symbol)); IMPORT_SYMBOL_NAME, CompletionKind.importSymbol, symbol));
@ -168,9 +182,10 @@ private:
currentScope.symbols.insert(moduleSymbol); currentScope.symbols.insert(moduleSymbol);
continue; continue;
} }
else foreach (tup; importInfo.importedSymbols[])
foreach (tup; importInfo.importedSymbols[])
{ {
// Handle selective and renamed imports
ACSymbol needle = ACSymbol(tup[1]); ACSymbol needle = ACSymbol(tup[1]);
ACSymbol* sym; ACSymbol* sym;
auto r = symbol.parts.equalRange(&needle); auto r = symbol.parts.equalRange(&needle);
@ -205,6 +220,8 @@ private:
rootSymbol.acSymbol.parts.insert(sym); rootSymbol.acSymbol.parts.insert(sym);
} }
} }
// Recurse to child scopes
foreach (childScope; currentScope.children) foreach (childScope; currentScope.children)
resolveImports(childScope); resolveImports(childScope);
} }

View File

@ -40,23 +40,40 @@ import string_interning;
struct ThirdPass struct ThirdPass
{ {
public: 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.rootSymbol = second.rootSymbol;
this.moduleScope = second.moduleScope; this.moduleScope = second.moduleScope;
this.name = name;
this.symbolAllocator = second.symbolAllocator; this.symbolAllocator = second.symbolAllocator;
} }
string name; /**
* Runs the third pass.
*/
void run() void run()
{ {
thirdPass(rootSymbol); thirdPass(rootSymbol);
} }
/**
* The module-level symbol
*/
SemanticSymbol* rootSymbol; SemanticSymbol* rootSymbol;
/**
* The module-level scope
*/
Scope* moduleScope; Scope* moduleScope;
/**
* The Symbol allocator
*/
CAllocator symbolAllocator; CAllocator symbolAllocator;
private: private:
@ -106,6 +123,8 @@ private:
thirdPass(child); 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) with (CompletionKind) switch (currentSymbol.acSymbol.kind)
{ {
case className: case className:
@ -162,7 +181,6 @@ private:
{ {
foreach (mix; currentSymbol.mixinTemplates[]) foreach (mix; currentSymbol.mixinTemplates[])
{ {
import stupidlog;
auto symbols = moduleScope.getSymbolsByNameAndCursor(mix[0], auto symbols = moduleScope.getSymbolsByNameAndCursor(mix[0],
currentSymbol.acSymbol.location); currentSymbol.acSymbol.location);
if (symbols.length == 0) if (symbols.length == 0)
@ -187,31 +205,28 @@ private:
{ {
if (initializer.empty) if (initializer.empty)
return null; return null;
// import stupidlog;
// Log.trace("resolveInitializerType: ", __LINE__, ":", initializer[]);
auto slice = initializer[]; auto slice = initializer[];
bool literal = slice.front[0] == '*'; bool literal = slice.front[0] == '*';
if (literal && initializer.length > 1) if (literal && initializer.length > 1)
{ {
// Log.trace("Popping ", slice.front, " from slice");
slice.popFront(); slice.popFront();
literal = false; literal = false;
} }
auto symbols = moduleScope.getSymbolsByNameAndCursor(internString( auto symbols = moduleScope.getSymbolsByNameAndCursor(internString(
literal ? slice.front[1 .. $] : slice.front), location); literal ? slice.front[1 .. $] : slice.front), location);
if (symbols.length == 0) if (symbols.length == 0)
{
// Log.trace("Could not find ", literal ? slice.front[1 .. $] : slice.front);
return null; return null;
}
if (literal) if (literal)
return symbols[0]; return symbols[0];
slice.popFront(); slice.popFront();
auto s = symbols[0]; auto s = symbols[0];
while (s !is null && s.type !is null && !slice.empty) while (s !is null && s.type !is null && !slice.empty)
{ {
s = s.type; s = s.type;
// Log.trace("resolveInitializerType: ", __LINE__, ":", slice.front);
if (slice.front == "foreach") if (slice.front == "foreach")
{ {
if (s.qualifier == SymbolQualifier.array) if (s.qualifier == SymbolQualifier.array)
@ -293,7 +308,6 @@ private:
ACSymbol* processSuffix(ACSymbol* symbol, const TypeSuffix suffix, const Type t) ACSymbol* processSuffix(ACSymbol* symbol, const TypeSuffix suffix, const Type t)
{ {
import std.d.formatter;
if (suffix.star) if (suffix.star)
return symbol; return symbol;
if (suffix.array || suffix.type) if (suffix.array || suffix.type)
@ -307,9 +321,9 @@ private:
} }
if (suffix.parameters) if (suffix.parameters)
{ {
import conversion.first; import conversion.first : formatNode;
import memory.allocators; import memory.allocators : QuickAllocator;
import memory.appender; import memory.appender : Appender;
ACSymbol* s = allocate!ACSymbol(symbolAllocator, null); ACSymbol* s = allocate!ACSymbol(symbolAllocator, null);
s.type = symbol; s.type = symbol;
s.qualifier = SymbolQualifier.func; s.qualifier = SymbolQualifier.func;
@ -325,12 +339,9 @@ private:
ACSymbol* convertBuiltinType(const Type2 type2) ACSymbol* convertBuiltinType(const Type2 type2)
{ {
import std.stdio;
string stringRepresentation = getBuiltinTypeName(type2.builtinType); string stringRepresentation = getBuiltinTypeName(type2.builtinType);
// writefln(">> %s %016X", stringRepresentation, stringRepresentation.ptr);
ACSymbol s = ACSymbol(stringRepresentation); ACSymbol s = ACSymbol(stringRepresentation);
assert(s.name.ptr == stringRepresentation.ptr); assert(s.name.ptr == stringRepresentation.ptr);
// writefln(">> %s %016X", s.name, s.name.ptr);
return builtinSymbols.equalRange(&s).front(); return builtinSymbols.equalRange(&s).front();
} }
} }

View File

@ -18,5 +18,16 @@
module dcd_version; 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");
}

View File

@ -103,7 +103,6 @@ struct ModuleCache
*/ */
static void addImportPaths(string[] paths) static void addImportPaths(string[] paths)
{ {
import core.memory;
foreach (path; paths.filter!(a => existanceCheck(a))) foreach (path; paths.filter!(a => existanceCheck(a)))
importPaths.insert(path); importPaths.insert(path);
@ -129,9 +128,9 @@ struct ModuleCache
*/ */
static ACSymbol* getModuleSymbol(string location) static ACSymbol* getModuleSymbol(string location)
{ {
import string_interning; import string_interning : internString;
import std.stdio; import std.stdio : File;
import std.typecons; import std.typecons : scoped;
assert (location !is null); assert (location !is null);
@ -156,17 +155,25 @@ struct ModuleCache
immutable fileSize = cast(size_t) f.size; immutable fileSize = cast(size_t) f.size;
if (fileSize == 0) if (fileSize == 0)
return null; return null;
const(Token)[] tokens;
{
ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(fileSize); ubyte[] source = cast(ubyte[]) Mallocator.it.allocate(fileSize);
scope (exit) Mallocator.it.deallocate(source);
f.rawRead(source); f.rawRead(source);
LexerConfig config; LexerConfig config;
config.fileName = cachedLocation; config.fileName = cachedLocation;
auto parseStringCache = StringCache(StringCache.defaultBucketCount); 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);
// 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); Module m = parseModuleSimple(tokens[], cachedLocation, semanticAllocator);
assert (symbolAllocator); assert (symbolAllocator);
@ -177,7 +184,7 @@ struct ModuleCache
SecondPass second = SecondPass(first); SecondPass second = SecondPass(first);
second.run(); second.run();
ThirdPass third = ThirdPass(second, cachedLocation); ThirdPass third = ThirdPass(second);
third.run(); third.run();
symbol = third.rootSymbol.acSymbol; symbol = third.rootSymbol.acSymbol;

View File

@ -33,7 +33,9 @@ struct SemanticSymbol
{ {
public: public:
/// Disable default construction.
@disable this(); @disable this();
/// Disable copy construction
@disable this(this); @disable this(this);
/** /**
@ -104,7 +106,7 @@ Type argumentsType;
static this() static this()
{ {
import std.allocator; import std.allocator : allocate;
// _argptr has type void* // _argptr has type void*
argptrType = allocate!Type(Mallocator.it); argptrType = allocate!Type(Mallocator.it);
argptrType.type2 = allocate!Type2(Mallocator.it); argptrType.type2 = allocate!Type2(Mallocator.it);

View File

@ -42,6 +42,7 @@ import actypes;
import core.memory; import core.memory;
import dcd_version; import dcd_version;
/// Name of the server configuration file
enum CONFIG_FILE_NAME = "dcd.conf"; enum CONFIG_FILE_NAME = "dcd.conf";
version(linux) version = useXDG; 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() void warnAboutOldConfigLocation()
{ {
version (linux) if ("~/.config/dcd".expandTilde().exists() version (linux) if ("~/.config/dcd".expandTilde().exists()
@ -282,6 +286,9 @@ string[] loadConfiguredImportDirs()
.array(); .array();
} }
/**
* Implements the --help switch.
*/
void printHelp(string programName) void printHelp(string programName)
{ {
writefln( writefln(

View File

@ -20,19 +20,12 @@ module string_interning;
import std.d.lexer; import std.d.lexer;
/**
* Interns the given string and returns the interned version.
*/
string internString(string s) 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); 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() static this()