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)
{
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");
}

View File

@ -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 = "";

View File

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

View File

@ -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);

View File

@ -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);
}

View File

@ -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();
}
}

View File

@ -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");
}

View File

@ -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;

View File

@ -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);

View File

@ -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(

View File

@ -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()