Skip to content

Commit

Permalink
Merge branch 'master' into public-imports
Browse files Browse the repository at this point in the history
  • Loading branch information
WebFreak001 authored Jun 24, 2020
2 parents 0dfa5ae + 1796664 commit 724716d
Show file tree
Hide file tree
Showing 6 changed files with 164 additions and 5 deletions.
3 changes: 3 additions & 0 deletions src/dsymbol/builtin/names.d
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ package istring[24] builtinTypeNames;
/// Constants for buit-in or dummy symbol names
istring FUNCTION_SYMBOL_NAME;
/// ditto
istring FUNCTION_LITERAL_SYMBOL_NAME;
/// ditto
istring IMPORT_SYMBOL_NAME;
/// ditto
istring ARRAY_SYMBOL_NAME;
Expand Down Expand Up @@ -135,6 +137,7 @@ static this()
builtinTypeNames[23] = internString("creal");

FUNCTION_SYMBOL_NAME = internString("function");
FUNCTION_LITERAL_SYMBOL_NAME = internString("*function-literal*");
IMPORT_SYMBOL_NAME = internString("import");
ARRAY_SYMBOL_NAME = internString("*arr*");
ARRAY_LITERAL_SYMBOL_NAME = internString("*arr-literal*");
Expand Down
2 changes: 1 addition & 1 deletion src/dsymbol/cache_entry.d
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pure nothrow @nogc @safe:

ptrdiff_t opCmp(ref const CacheEntry other) const
{
return path.opCmp(other.path);
return path.opCmpFast(other.path);
}

bool opEquals(ref const CacheEntry other) const
Expand Down
94 changes: 92 additions & 2 deletions src/dsymbol/conversion/first.d
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,28 @@ final class FirstPass : ASTVisitor
}
}

override void visit(const FunctionLiteralExpression exp)
{
assert(exp);

auto fbody = exp.specifiedFunctionBody;
if (fbody is null)
return;
auto block = fbody.blockStatement;
if (block is null)
return;

pushSymbol(FUNCTION_LITERAL_SYMBOL_NAME, CompletionKind.dummy, symbolFile,
block.startLocation, null);
scope(exit) popSymbol();

pushScope(block.startLocation, block.endLocation);
scope (exit) popScope();
processParameters(currentSymbol, exp.returnType,
FUNCTION_LITERAL_SYMBOL_NAME, exp.parameters, null);
block.accept(this);
}

override void visit(const ClassDeclaration dec)
{
visitAggregateDeclaration(dec, CompletionKind.className);
Expand Down Expand Up @@ -582,6 +604,34 @@ final class FirstPass : ASTVisitor
}
}

// Create attribute/protection scope for conditional compilation declaration
// blocks.
override void visit(const ConditionalDeclaration conditionalDecl)
{
if (conditionalDecl.compileCondition !is null)
visit(conditionalDecl.compileCondition);

if (conditionalDecl.trueDeclarations.length)
{
protection.beginScope();
scope (exit) protection.endScope();

foreach (decl; conditionalDecl.trueDeclarations)
if (decl !is null)
visit (decl);
}

if (conditionalDecl.falseDeclarations.length)
{
protection.beginScope();
scope (exit) protection.endScope();

foreach (decl; conditionalDecl.falseDeclarations)
if (decl !is null)
visit (decl);
}
}

override void visit(const TemplateMixinExpression tme)
{
// TODO: support typeof here
Expand Down Expand Up @@ -720,6 +770,12 @@ final class FirstPass : ASTVisitor
withStatement.accept(this);
}

override void visit(const ArgumentList list)
{
auto visitor = scoped!(ArgumentListVisitor)(this);
visitor.visit(list);
}

alias visit = ASTVisitor.visit;

/// Module scope
Expand Down Expand Up @@ -1329,6 +1385,11 @@ class InitializerVisitor : ASTVisitor

alias visit = ASTVisitor.visit;

override void visit(const FunctionLiteralExpression exp)
{
fp.visit(exp);
}

override void visit(const IdentifierOrTemplateInstance ioti)
{
if (on && ioti.identifier != tok!"")
Expand Down Expand Up @@ -1445,8 +1506,7 @@ class InitializerVisitor : ASTVisitor
lookup.breadcrumbs.insert(ARRAY_LITERAL_SYMBOL_NAME);
}

// Skip these
override void visit(const ArgumentList) {}
// Skip it
override void visit(const NewAnonClassExpression) {}

override void visit(const NewExpression ne)
Expand Down Expand Up @@ -1485,6 +1545,12 @@ class InitializerVisitor : ASTVisitor
ne.arguments = nace.constructorArguments;
}

override void visit(const ArgumentList list)
{
auto visitor = scoped!(ArgumentListVisitor)(fp);
visitor.visit(list);
}

override void visit(const Expression expression)
{
on = true;
Expand All @@ -1508,3 +1574,27 @@ class InitializerVisitor : ASTVisitor
const bool appendForeach;
FirstPass fp;
}

class ArgumentListVisitor : ASTVisitor
{
this(FirstPass fp)
{
assert(fp);
this.fp = fp;
}

alias visit = ASTVisitor.visit;

override void visit(const FunctionLiteralExpression exp)
{
fp.visit(exp);
}

override void visit(const NewAnonClassExpression exp)
{
fp.visit(exp);
}

private:
FirstPass fp;
}
2 changes: 1 addition & 1 deletion src/dsymbol/string_interning.d
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ pure:
return _data.length > 0;
}

ptrdiff_t opCmp(const istring another) const @trusted
ptrdiff_t opCmpFast(const istring another) const @trusted
{
// Interned strings can be compared by the pointers.
// Identical strings MUST have the same address
Expand Down
2 changes: 1 addition & 1 deletion src/dsymbol/symbol.d
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ struct DSymbol

ptrdiff_t opCmp(ref const DSymbol other) const pure nothrow @nogc @safe
{
return name.opCmp(other.name);
return name.opCmpFast(other.name);
}

bool opEquals(ref const DSymbol other) const pure nothrow @nogc @safe
Expand Down
66 changes: 66 additions & 0 deletions src/dsymbol/tests.d
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,31 @@ unittest
auto pair = generateAutocompleteTrees(source, cache);
}

unittest
{
ModuleCache cache = ModuleCache(theAllocator);

writeln("Running function literal tests...");
const sources = [
q{ int a; auto dg = { }; },
q{ void f() { int a; auto dg = { }; } },
q{ auto f = (int a) { }; },
q{ auto f() { return (int a) { }; } },
q{ auto f() { return g((int a) { }); } },
q{ void f() { g((int a) { }); } },
q{ void f() { auto x = (int a) { }; } },
q{ void f() { auto x = g((int a) { }); } },
];
foreach (src; sources)
{
auto pair = generateAutocompleteTrees(src, cache);
auto a = pair.scope_.getFirstSymbolByNameAndCursor(istring("a"), 35);
assert(a, src);
assert(a.type, src);
assert(a.type.name == "int", src);
}
}

unittest
{
ModuleCache cache = ModuleCache(theAllocator);
Expand Down Expand Up @@ -174,6 +199,35 @@ unittest
assert(Aa);
}

unittest
{
ModuleCache cache = ModuleCache(theAllocator);

writeln("Running anon class tests...");
const sources = [
q{ auto a = new class Object { int i; }; },
q{ auto a = new class Object { int i; void m() { } }; },
q{ auto a = g(new class Object { int i; }); },
q{ auto a = g(new class Object { int i; void m() { } }); },
q{ void f() { new class Object { int i; }; } },
q{ void f() { new class Object { int i; void m() { } }; } },
q{ void f() { g(new class Object { int i; }); } },
q{ void f() { g(new class Object { int i; void m() { } }); } },
q{ void f() { auto a = new class Object { int i; }; } },
q{ void f() { auto a = new class Object { int i; void m() { } }; } },
q{ void f() { auto a = g(new class Object { int i; }); } },
q{ void f() { auto a = g(new class Object { int i; void m() { } }); } },
];
foreach (src; sources)
{
auto pair = generateAutocompleteTrees(src, cache);
auto a = pair.scope_.getFirstSymbolByNameAndCursor(istring("i"), 60);
assert(a, src);
assert(a.type, src);
assert(a.type.name == "int", src);
}
}

unittest
{
ModuleCache cache = ModuleCache(theAllocator);
Expand Down Expand Up @@ -373,6 +427,18 @@ unittest
assert(dz is cz);
}

unittest
{
ModuleCache cache = ModuleCache(theAllocator);

writeln("Testing protection scopes");
auto source = q{version(all) { private: } struct Foo{ }};
auto pair = generateAutocompleteTrees(source, "", 0, cache);
DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
assert(T1);
assert(T1.protection != tok!"private");
}

// check for memory leaks on thread termination (in static constructors)
version (linux)
unittest
Expand Down

0 comments on commit 724716d

Please sign in to comment.