Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Major change making dsymbol deduce ufcs #724

Merged
merged 9 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion dsymbol/src/dsymbol/conversion/package.d
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import dsymbol.scope_;
import dsymbol.semantic;
import dsymbol.string_interning;
import dsymbol.symbol;
import dsymbol.ufcs;
import std.algorithm;
import std.experimental.allocator;
import containers.hashset;
Expand All @@ -52,9 +53,11 @@ ScopeSymbolPair generateAutocompleteTrees(const(Token)[] tokens,

thirdPass(first.moduleScope, cache, cursorPosition);

auto ufcsSymbols = getUFCSSymbolsForCursor(first.moduleScope, tokens, cursorPosition);

auto r = move(first.rootSymbol.acSymbol);
typeid(SemanticSymbol).destroy(first.rootSymbol);
return ScopeSymbolPair(r, move(first.moduleScope));
return ScopeSymbolPair(r, move(first.moduleScope), ufcsSymbols);
}

struct ScopeSymbolPair
Expand All @@ -63,10 +66,13 @@ struct ScopeSymbolPair
{
typeid(DSymbol).destroy(symbol);
typeid(Scope).destroy(scope_);
// don't destroy ufcsSymbols contents since we don't own the values
// array itself is GC-allocated, so we just let it live
}

DSymbol* symbol;
Scope* scope_;
DSymbol*[] ufcsSymbols;
vushu marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down
93 changes: 78 additions & 15 deletions dsymbol/src/dsymbol/tests.d
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ module dsymbol.tests;
import std.experimental.allocator;
import dparse.ast, dparse.parser, dparse.lexer, dparse.rollback_allocator;
import dsymbol.cache_entry, dsymbol.modulecache, dsymbol.symbol;
import dsymbol.conversion, dsymbol.conversion.first, dsymbol.conversion.second;
import dsymbol.conversion, dsymbol.conversion.first, dsymbol.conversion.second, dsymbol.conversion.third;
import dsymbol.semantic, dsymbol.string_interning, dsymbol.builtin.names;
import std.file, std.path, std.format;
import std.stdio : writeln, stdout;
import dsymbol.ufcs;

/**
* Parses `source`, caches its symbols and compares the the cache content
Expand Down Expand Up @@ -413,7 +414,7 @@ unittest
writeln("Running template type parameters tests...");
{
auto source = q{ struct Foo(T : int){} struct Bar(T : Foo){} };
auto pair = generateAutocompleteTrees(source, "", 0, cache);
auto pair = generateAutocompleteTreesProd(source, "", 0, cache);
DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
DSymbol* T2 = T1.getFirstPartNamed(internString("T"));
assert(T2.type.name == "int");
Expand All @@ -424,7 +425,7 @@ unittest
}
{
auto source = q{ struct Foo(T){ }};
auto pair = generateAutocompleteTrees(source, "", 0, cache);
auto pair = generateAutocompleteTreesProd(source, "", 0, cache);
DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
assert(T1);
DSymbol* T2 = T1.getFirstPartNamed(internString("T"));
Expand All @@ -439,7 +440,7 @@ unittest

writeln("Running template variadic parameters tests...");
auto source = q{ struct Foo(T...){ }};
auto pair = generateAutocompleteTrees(source, "", 0, cache);
auto pair = generateAutocompleteTreesProd(source, "", 0, cache);
DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
assert(T1);
DSymbol* T2 = T1.getFirstPartNamed(internString("T"));
Expand Down Expand Up @@ -528,15 +529,14 @@ unittest

writeln("Testing protection scopes");
auto source = q{version(all) { private: } struct Foo{ }};
auto pair = generateAutocompleteTrees(source, "", 0, cache);
auto pair = generateAutocompleteTreesProd(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
version (linux) unittest
{
import core.memory : GC;
import core.thread : Thread;
Expand Down Expand Up @@ -584,6 +584,7 @@ static this()
{
stringCache = StringCache(StringCache.defaultBucketCount);
}

static ~this()
{
destroy(stringCache);
Expand All @@ -598,6 +599,7 @@ const(Token)[] lex(string source, string filename)
{
import dparse.lexer : getTokensForParser;
import std.string : representation;

LexerConfig config;
config.fileName = filename;
return getTokensForParser(source.dup.representation, config, &stringCache);
Expand Down Expand Up @@ -626,7 +628,7 @@ ScopeSymbolPair generateAutocompleteTrees(string source, ref ModuleCache cache)
return generateAutocompleteTrees(source, randomDFilename, cache);
}

ScopeSymbolPair generateAutocompleteTrees(string source, string filename, ref ModuleCache cache)
ScopeSymbolPair generateAutocompleteTrees(string source, string filename, ref ModuleCache cache, size_t cursorPosition = -1)
{
auto tokens = lex(source);
RollbackAllocator rba;
Expand All @@ -635,21 +637,82 @@ ScopeSymbolPair generateAutocompleteTrees(string source, string filename, ref Mo
scope first = new FirstPass(m, internString(filename), &cache);
first.run();


secondPass(first.rootSymbol, first.moduleScope, cache);
thirdPass(first.moduleScope, cache, cursorPosition);
auto ufcsSymbols = getUFCSSymbolsForCursor(first.moduleScope, tokens, cursorPosition);
auto r = first.rootSymbol.acSymbol;
typeid(SemanticSymbol).destroy(first.rootSymbol);
return ScopeSymbolPair(r, first.moduleScope);
return ScopeSymbolPair(r, first.moduleScope, ufcsSymbols);
}

ScopeSymbolPair generateAutocompleteTrees(string source, size_t cursorPosition, ref ModuleCache cache)
{
return generateAutocompleteTrees(source, null, cache);
}

ScopeSymbolPair generateAutocompleteTrees(string source, string filename, size_t cursorPosition, ref ModuleCache cache)
ScopeSymbolPair generateAutocompleteTreesProd(string source, string filename, size_t cursorPosition, ref ModuleCache cache)
WebFreak001 marked this conversation as resolved.
Show resolved Hide resolved
{
auto tokens = lex(source);
RollbackAllocator rba;
return dsymbol.conversion.generateAutocompleteTrees(
tokens, &rba, cursorPosition, cache);
}



version (linux)
{
enum string ufcsExampleCode =
q{class Incrementer
{
int run(int x)
{
return x++;
}
}
int increment(int x)
{
return x++;
}
void doIncrement()
{
int life = 42;
life.
}};

unittest
{
import dsymbol.ufcs;

writeln("Getting UFCS Symbols For life");
ModuleCache cache;
// position of variable life
size_t cursorPos = 139;
auto pair = generateAutocompleteTreesProd(ufcsExampleCode, randomDFilename, cursorPos, cache);
assert(pair.ufcsSymbols.length > 0);
assert(pair.ufcsSymbols[0].name == "increment");

}

enum string ufcsTemplateExampleCode =
q{int increment(T)(T x)
{
return x++;
}
void doIncrement()
{
int life = 42;
life.
}};

unittest
{
import dsymbol.ufcs;

writeln("Getting Templated UFCS Symbols For life");
ModuleCache cache;
// position of variable life
size_t cursorPos = 82;
auto pair = generateAutocompleteTreesProd(ufcsTemplateExampleCode, randomDFilename, cursorPos, cache);
assert(pair.ufcsSymbols.length > 0);
assert(pair.ufcsSymbols[0].name == "increment");

}

}
Loading