expectSymbolsAndTypes

Parses source, caches its symbols and compares the the cache content with the results.

version(unittest)
void
expectSymbolsAndTypes
(
const string source
,
const string[][] results
,
string file = __FILE_FULL_PATH__
,
size_t line = __LINE__
)

Parameters

source string

The source code to test.

results string[][]

An array of string array. Each slot represents the variable name followed by the type strings.

Examples

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

writeln("Running type deduction tests...");
q{bool b; int i;}.expectSymbolsAndTypes([["b", "bool"],["i", "int"]]);
q{auto b = false;}.expectSymbolsAndTypes([["b", "bool"]]);
q{auto b = true;}.expectSymbolsAndTypes([["b", "bool"]]);
q{auto b = [0];}.expectSymbolsAndTypes([["b", "*arr-literal*", "int"]]);
q{auto b = [[0]];}.expectSymbolsAndTypes([["b", "*arr-literal*", "*arr-literal*", "int"]]);
q{auto b = [[[0]]];}.expectSymbolsAndTypes([["b", "*arr-literal*", "*arr-literal*", "*arr-literal*", "int"]]);
q{auto b = [];}.expectSymbolsAndTypes([["b", "*arr-literal*", "void"]]);
q{auto b = [[]];}.expectSymbolsAndTypes([["b", "*arr-literal*", "*arr-literal*", "void"]]);
//q{int* b;}.expectSymbolsAndTypes([["b", "*", "int"]]);
//q{int*[] b;}.expectSymbolsAndTypes([["b", "*arr*", "*", "int"]]);

q{auto b = new class {int i;};}.expectSymbolsAndTypes([["b", "__anonclass1"]]);

// got a crash before but solving is not yet working ("foo" instead of  "__anonclass1");
q{class Bar{} auto foo(){return new class Bar{};} auto b = foo();}.expectSymbolsAndTypes([["b", "foo"]]);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);
auto source = q{ auto a = true ? [42] : []; };
auto pair = generateAutocompleteTrees(source, cache);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);
auto source = q{ void test() { foo(new class A {});}  };
auto pair = generateAutocompleteTrees(source, cache);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);
auto source = q{ void b() { c = } alias b this;  };
auto pair = generateAutocompleteTrees(source, cache);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

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

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running struct constructor tests...");
auto source = q{ struct A {int a; struct B {bool b;} int c;} };
auto pair = generateAutocompleteTrees(source, cache);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
auto B = A.getFirstPartNamed(internString("B"));
auto ACtor = A.getFirstPartNamed(CONSTRUCTOR_SYMBOL_NAME);
auto BCtor = B.getFirstPartNamed(CONSTRUCTOR_SYMBOL_NAME);
assert(ACtor.callTip == "this(int a, int c)");
assert(BCtor.callTip == "this(bool b)");

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running union constructor tests...");
auto source = q{ union A {int a; bool b;} };
auto pair = generateAutocompleteTrees(source, cache);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
auto ACtor = A.getFirstPartNamed(CONSTRUCTOR_SYMBOL_NAME);
assert(ACtor.callTip == "this(int a, bool b)");

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);
writeln("Running non-importable symbols tests...");
auto source = q{
	class A { this(int a){} }
	class B : A {}
	class C { A f; alias f this; }
};
auto pair = generateAutocompleteTrees(source, cache);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
auto B = pair.symbol.getFirstPartNamed(internString("B"));
auto C = pair.symbol.getFirstPartNamed(internString("C"));
assert(A.getFirstPartNamed(CONSTRUCTOR_SYMBOL_NAME) !is null);
assert(B.getFirstPartNamed(CONSTRUCTOR_SYMBOL_NAME) is null);
assert(C.getFirstPartNamed(CONSTRUCTOR_SYMBOL_NAME) is null);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running alias this tests...");
auto source = q{ struct A {int f;} struct B { A a; alias a this; void fun() { auto var = f; };} };
auto pair = generateAutocompleteTrees(source, cache);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
auto B = pair.symbol.getFirstPartNamed(internString("B"));
auto Af = A.getFirstPartNamed(internString("f"));
auto fun = B.getFirstPartNamed(internString("fun"));
auto var = fun.getFirstPartNamed(internString("var"));
assert(Af is pair.scope_.getFirstSymbolByNameAndCursor(internString("f"), var.location));

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running anon struct tests...");
auto source = q{ struct A { struct {int a;}} };
auto pair = generateAutocompleteTrees(source, cache);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
assert(A);
auto Aa = A.getFirstPartNamed(internString("a"));
assert(Aa);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

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

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running the deduction from index expr tests...");
{
	auto source = q{struct S{} S[] s; auto b = s[i];};
	auto pair = generateAutocompleteTrees(source, cache);
	DSymbol* S = pair.symbol.getFirstPartNamed(internString("S"));
	DSymbol* b = pair.symbol.getFirstPartNamed(internString("b"));
	assert(S);
	assert(b.type is S);
}
{
	auto source = q{struct S{} S[1] s; auto b = s[i];};
	auto pair = generateAutocompleteTrees(source, cache);
	DSymbol* S = pair.symbol.getFirstPartNamed(internString("S"));
	DSymbol* b = pair.symbol.getFirstPartNamed(internString("b"));
	assert(S);
	assert(b.type is S);
}
{
	auto source = q{struct S{} S[][] s; auto b = s[0];};
	auto pair = generateAutocompleteTrees(source, cache);
	DSymbol* S = pair.symbol.getFirstPartNamed(internString("S"));
	DSymbol* b = pair.symbol.getFirstPartNamed(internString("b"));
	assert(S);
	assert(b.type.type is S);
}
{
	auto source = q{struct S{} S[][][] s; auto b = s[0][0];};
	auto pair = generateAutocompleteTrees(source, cache);
	DSymbol* S = pair.symbol.getFirstPartNamed(internString("S"));
	DSymbol* b = pair.symbol.getFirstPartNamed(internString("b"));
	assert(S);
	assert(b.type.name == ARRAY_SYMBOL_NAME);
	assert(b.type.type is S);
}
{
	auto source = q{struct S{} S s; auto b = [s][0];};
	auto pair = generateAutocompleteTrees(source, cache);
	DSymbol* S = pair.symbol.getFirstPartNamed(internString("S"));
	DSymbol* b = pair.symbol.getFirstPartNamed(internString("b"));
	assert(S);
	assert(b.type is S);
}

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running `super` tests...");
auto source = q{ class A {} class B : A {} };
auto pair = generateAutocompleteTrees(source, cache);
assert(pair.symbol);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
auto B = pair.symbol.getFirstPartNamed(internString("B"));
auto scopeA = (pair.scope_.getScopeByCursor(A.location + A.name.length));
auto scopeB = (pair.scope_.getScopeByCursor(B.location + B.name.length));
assert(scopeA !is scopeB);

assert(!scopeA.getSymbolsByName(SUPER_SYMBOL_NAME).length);
assert(scopeB.getSymbolsByName(SUPER_SYMBOL_NAME)[0].type is A);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running the \"access chain with inherited type\" tests...");
auto source = q{ class A {} class B : A {} };
auto pair = generateAutocompleteTrees(source, cache);
assert(pair.symbol);
auto A = pair.symbol.getFirstPartNamed(internString("A"));
assert(A);
auto B = pair.symbol.getFirstPartNamed(internString("B"));
assert(B);
auto AfromB = B.getFirstPartNamed(internString("A"));
assert(AfromB.kind == CompletionKind.aliasName);
assert(AfromB.type is A);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running template type parameters tests...");
{
	auto source = q{ struct Foo(T : int){} struct Bar(T : Foo){} };
	auto pair = generateAutocompleteTrees(source, "", 0, cache);
	DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
	DSymbol* T2 = T1.getFirstPartNamed(internString("T"));
	assert(T2.type.name == "int");
	DSymbol* T3 = pair.symbol.getFirstPartNamed(internString("Bar"));
	DSymbol* T4 = T3.getFirstPartNamed(internString("T"));
	assert(T4.type);
	assert(T4.type == T1);
}
{
	auto source = q{ struct Foo(T){ }};
	auto pair = generateAutocompleteTrees(source, "", 0, cache);
	DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
	assert(T1);
	DSymbol* T2 = T1.getFirstPartNamed(internString("T"));
	assert(T2);
	assert(T2.kind == CompletionKind.typeTmpParam);
}

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

ModuleCache cache = ModuleCache(theAllocator);

writeln("Running template variadic parameters tests...");
auto source = q{ struct Foo(T...){ }};
auto pair = generateAutocompleteTrees(source, "", 0, cache);
DSymbol* T1 = pair.symbol.getFirstPartNamed(internString("Foo"));
assert(T1);
DSymbol* T2 = T1.getFirstPartNamed(internString("T"));
assert(T2);
assert(T2.kind == CompletionKind.variadicTmpParam);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

1 writeln("Running public import tests...");
2 
3 const dir = buildPath(tempDir(), "dsymbol");
4 const fnameA = buildPath(dir, "a.d");
5 const fnameB = buildPath(dir, "b.d");
6 const fnameC = buildPath(dir, "c.d");
7 const fnameD = buildPath(dir, "d.d");
8 const srcA = q{ int x; int w; };
9 const srcB = q{ float y; private float z; };
10 const srcC = q{ public { import a : x; import b; } import a : w; long t; };
11 const srcD = q{ public import c; };
12 // A simpler diagram:
13 // a = x w
14 // b = y [z]
15 // c = t + (x y) [w]
16 // d = (t x y)
17 
18 mkdir(dir);
19 write(fnameA, srcA);
20 write(fnameB, srcB);
21 write(fnameC, srcC);
22 write(fnameD, srcD);
23 scope (exit)
24 {
25 	remove(fnameA);
26 	remove(fnameB);
27 	remove(fnameC);
28 	remove(fnameD);
29 	rmdir(dir);
30 }
31 
32 ModuleCache cache = ModuleCache(theAllocator);
33 cache.addImportPaths([dir]);
34 
35 const a = cache.getModuleSymbol(istring(fnameA));
36 const b = cache.getModuleSymbol(istring(fnameB));
37 const c = cache.getModuleSymbol(istring(fnameC));
38 const d = cache.getModuleSymbol(istring(fnameD));
39 const ax = a.getFirstPartNamed(istring("x"));
40 const aw = a.getFirstPartNamed(istring("w"));
41 assert(ax);
42 assert(aw);
43 assert(ax.type && ax.type.name == "int");
44 assert(aw.type && aw.type.name == "int");
45 const by = b.getFirstPartNamed(istring("y"));
46 const bz = b.getFirstPartNamed(istring("z"));
47 assert(by);
48 assert(bz);
49 assert(by.type && by.type.name == "float");
50 assert(bz.type && bz.type.name == "float");
51 const ct = c.getFirstPartNamed(istring("t"));
52 const cw = c.getFirstPartNamed(istring("w"));
53 const cx = c.getFirstPartNamed(istring("x"));
54 const cy = c.getFirstPartNamed(istring("y"));
55 const cz = c.getFirstPartNamed(istring("z"));
56 assert(ct);
57 assert(ct.type && ct.type.name == "long");
58 assert(cw is null); // skipOver is true
59 assert(cx is ax);
60 assert(cy is by);
61 assert(cz is bz); // should not be there, but it is handled by DCD
62 const dt = d.getFirstPartNamed(istring("t"));
63 const dw = d.getFirstPartNamed(istring("w"));
64 const dx = d.getFirstPartNamed(istring("x"));
65 const dy = d.getFirstPartNamed(istring("y"));
66 const dz = d.getFirstPartNamed(istring("z"));
67 assert(dt is ct);
68 assert(dw is null);
69 assert(dx is cx);
70 assert(dy is cy);
71 assert(dz is cz);

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

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

Parses source, caches its symbols and compares the the cache content with the results.

Params: source = The source code to test. results = An array of string array. Each slot represents the variable name followed by the type strings.

istring a = internString("foo_bar_baz".idup);
istring b = internString("foo_bar_baz".idup);
assert(a.data.ptr == b.data.ptr);

Meta