Skip to content

Instantly share code, notes, and snippets.

@WebFreak001
Created August 12, 2023 19:11
Show Gist options
  • Save WebFreak001/2c0fd403ca96bb65f9e195b21869b14e to your computer and use it in GitHub Desktop.
Save WebFreak001/2c0fd403ca96bb65f9e195b21869b14e to your computer and use it in GitHub Desktop.
diff --git a/dsymbol/src/dsymbol/conversion/first.d b/dsymbol/src/dsymbol/conversion/first.d
index c9ac1b6..196bd22 100644
--- a/dsymbol/src/dsymbol/conversion/first.d
+++ b/dsymbol/src/dsymbol/conversion/first.d
@@ -237,10 +237,192 @@ final class FirstPass : ASTVisitor
currentSymbol.addChild(symbol, true);
symbol.acSymbol.protection = protection.current;
}
+
+
+ void processIdentifierOrTemplate(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, VariableContext.TypeInstance* current, IdentifierOrTemplateInstance ioti)
+ {
+ if (ioti.identifier != tok!"")
+ current.chain ~= ioti.identifier.text;
+ else if (ioti.templateInstance)
+ processTemplateInstance(symbol, lookup, ctx, current, ioti.templateInstance);
+ }
+
+ void processTypeIdentifierPart(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, VariableContext.TypeInstance* current, TypeIdentifierPart tip)
+ {
+ if (tip.identifierOrTemplateInstance)
+ processIdentifierOrTemplate(symbol, lookup, ctx, current, tip.identifierOrTemplateInstance);
+
+ if (tip.typeIdentifierPart)
+ processTypeIdentifierPart(symbol, lookup, ctx, current, tip.typeIdentifierPart);
+
+ // TODO: handle `tip.dot` and `tip.indexer`
+ }
+
+ void processTemplateArguments(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, VariableContext.TypeInstance* current, TemplateArguments targs)
+ {
+ if (targs.namedTemplateArgumentList)
+ {
+ foreach(i, targ; targs.namedTemplateArgumentList.items)
+ {
+ // TODO: handle targ.assignExpression
+ if (targ.type is null) continue;
+ if (targ.type.type2 is null) continue;
+
+ auto part = targ.type.type2.typeIdentifierPart;
+ if (part is null)
+ {
+ if (targ.type.type2.builtinType == tok!"") continue;
+ auto builtInName = getBuiltinTypeName(targ.type.type2.builtinType);
+ auto newArg = GCAllocator.instance.make!(VariableContext.TypeInstance)();
+ newArg.chain ~= builtInName;
+ current.args ~= newArg;
+ continue;
+ }
+
+ auto newArg = GCAllocator.instance.make!(VariableContext.TypeInstance)();
+ current.args ~= newArg;
+
+ if (part.identifierOrTemplateInstance)
+ {
+ processIdentifierOrTemplate(symbol, lookup, ctx, newArg, part.identifierOrTemplateInstance);
+ }
+ if (part.typeIdentifierPart)
+ {
+ if (part.typeIdentifierPart.identifierOrTemplateInstance)
+ processIdentifierOrTemplate(symbol, lookup, ctx, newArg, part.typeIdentifierPart.identifierOrTemplateInstance);
+ }
+ }
+ }
+ else if (targs.templateSingleArgument)
+ {
+ auto singleArg = targs.templateSingleArgument;
+ auto arg = GCAllocator.instance.make!(VariableContext.TypeInstance)();
+ arg.name = singleArg.token.text;
+ arg.chain ~= arg.name;
+ current.args ~= arg;
+ }
+ }
+
+ void processTemplateInstance(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, VariableContext.TypeInstance* current, TemplateInstance ti)
+ {
+ if (ti.identifier != tok!"")
+ current.chain ~= ti.identifier.text;
+
+ if (ti.templateArguments)
+ processTemplateArguments(symbol, lookup, ctx, current, ti.templateArguments);
+ }
+
+ void buildChain(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, TypeIdentifierPart tip)
+ {
+ if (tip.identifierOrTemplateInstance)
+ buildChainTemplateOrIdentifier(symbol, lookup, ctx, tip.identifierOrTemplateInstance);
+ if (tip.typeIdentifierPart)
+ buildChain(symbol, lookup, ctx, tip.typeIdentifierPart);
+ // TODO: handle `tip.indexer`
+ }
+
+ void buildChainTemplateOrIdentifier(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, IdentifierOrTemplateInstance iot)
+ {
+ auto crumb = iot.identifier;
+ if (crumb != tok!"")
+ lookup.breadcrumbs.insert(istring(crumb.text));
+
+ if (iot.templateInstance)
+ {
+ if (iot.templateInstance.identifier != tok!"")
+ lookup.breadcrumbs.insert(istring(iot.templateInstance.identifier.text));
+
+ // TODO: finish handling `iot.templateInstance.templateArguments`
+ if (iot.templateInstance.templateArguments)
+ {
+ if (iot.templateInstance.templateArguments.templateSingleArgument)
+ {
+ auto tsaTok = iot.templateInstance.templateArguments.templateSingleArgument.token;
+ if (tsaTok.text == "")
+ lookup.breadcrumbs.insert(istring(str(tsaTok.type)));
+ // TODO: investigate why this break everything
+ // else
+ // lookup.breadcrumbs.insert(istring(tsaTok.text));
+ }
+ }
+ }
+ }
+
+ void traverseUnaryExpression(SemanticSymbol* symbol, TypeLookup* lookup, VariableContext* ctx, UnaryExpression ue)
+ {
+ if (PrimaryExpression pe = ue.primaryExpression)
+ {
+ if (pe.identifierOrTemplateInstance)
+ buildChainTemplateOrIdentifier(symbol, lookup, ctx, pe.identifierOrTemplateInstance);
+
+ if (pe.basicType != tok!"")
+ lookup.breadcrumbs.insert(internString(str(pe.basicType.type)));
+ switch (pe.primary.type)
+ {
+ case tok!"identifier":
+ lookup.breadcrumbs.insert(internString(pe.primary.text));
+ break;
+ case tok!"doubleLiteral":
+ lookup.breadcrumbs.insert(DOUBLE_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"floatLiteral":
+ lookup.breadcrumbs.insert(FLOAT_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"idoubleLiteral":
+ lookup.breadcrumbs.insert(IDOUBLE_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"ifloatLiteral":
+ lookup.breadcrumbs.insert(IFLOAT_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"intLiteral":
+ lookup.breadcrumbs.insert(INT_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"longLiteral":
+ lookup.breadcrumbs.insert(LONG_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"realLiteral":
+ lookup.breadcrumbs.insert(REAL_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"irealLiteral":
+ lookup.breadcrumbs.insert(IREAL_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"uintLiteral":
+ lookup.breadcrumbs.insert(UINT_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"ulongLiteral":
+ lookup.breadcrumbs.insert(ULONG_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"characterLiteral":
+ lookup.breadcrumbs.insert(CHAR_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"dstringLiteral":
+ lookup.breadcrumbs.insert(DSTRING_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"stringLiteral":
+ lookup.breadcrumbs.insert(STRING_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"wstringLiteral":
+ lookup.breadcrumbs.insert(WSTRING_LITERAL_SYMBOL_NAME);
+ break;
+ case tok!"false":
+ case tok!"true":
+ lookup.breadcrumbs.insert(BOOL_VALUE_SYMBOL_NAME);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (IdentifierOrTemplateInstance iot = ue.identifierOrTemplateInstance)
+ buildChainTemplateOrIdentifier(symbol, lookup, ctx, iot);
+
+ if(ue.unaryExpression) traverseUnaryExpression(symbol, lookup, ctx, ue.unaryExpression);
+ }
override void visit(const VariableDeclaration dec)
{
assert (currentSymbol);
+
foreach (declarator; dec.declarators)
{
SemanticSymbol* symbol = allocateSemanticSymbol(
@@ -261,6 +443,16 @@ final class FirstPass : ASTVisitor
// TODO: remove this cast. See the note on structFieldTypes
structFieldTypes.insert(cast() dec.type);
}
+
+ auto lookup = symbol.typeLookups.front;
+
+ if (dec.type && dec.type.type2 && dec.type.type2.typeIdentifierPart)
+ {
+ TypeIdentifierPart typeIdentifierPart = cast(TypeIdentifierPart) dec.type.type2.typeIdentifierPart;
+
+ lookup.ctx.root = GCAllocator.instance.make!(VariableContext.TypeInstance)();
+ processTypeIdentifierPart(symbol, lookup, &lookup.ctx, lookup.ctx.root, typeIdentifierPart);
+ }
}
if (dec.autoDeclaration !is null)
{
@@ -283,6 +475,66 @@ final class FirstPass : ASTVisitor
// TODO: remove this cast. See the note on structFieldTypes
structFieldTypes.insert(null);
}
+
+ auto lookup = symbol.typeLookups.front;
+
+ auto initializer = part.initializer.nonVoidInitializer;
+ if (initializer && initializer.assignExpression)
+ {
+ UnaryExpression unary = cast(UnaryExpression) initializer.assignExpression;
+
+ if (unary && (unary.newExpression || unary.indexExpression))
+ continue;
+
+ lookup.breadcrumbs.clear();
+ if (unary)
+ {
+ if (CastExpression castExpression = unary.castExpression)
+ {
+ if (castExpression.type && castExpression.type.type2)
+ {
+ Type2 t2 = castExpression.type.type2;
+ if (t2 && t2.typeIdentifierPart)
+ buildChain(symbol, lookup, &lookup.ctx, t2.typeIdentifierPart);
+ }
+ continue;
+ }
+ else if (FunctionCallExpression fc = unary.functionCallExpression)
+ unary = fc.unaryExpression;
+ // build chain
+ traverseUnaryExpression(symbol, lookup, &lookup.ctx, unary);
+ // needs to be reversed because it got added in order (right->left)
+ auto crumbs = &lookup.breadcrumbs;
+ istring[] result;
+ foreach(c; *crumbs)
+ result ~= c;
+
+ crumbs.clear();
+ foreach_reverse(c; result)
+ lookup.breadcrumbs.insert(c);
+
+ // check template
+ if (IdentifierOrTemplateInstance iot = unary.identifierOrTemplateInstance)
+ {
+ if (iot.templateInstance)
+ {
+ lookup.ctx.root = GCAllocator.instance.make!(VariableContext.TypeInstance)();
+ processTemplateInstance(symbol, lookup, &lookup.ctx, lookup.ctx.root, iot.templateInstance);
+ }
+ }
+ else if (PrimaryExpression pe = unary.primaryExpression)
+ {
+ if (pe.identifierOrTemplateInstance)
+ {
+ if (pe.identifierOrTemplateInstance.templateInstance)
+ {
+ lookup.ctx.root = GCAllocator.instance.make!(VariableContext.TypeInstance)();
+ processTemplateInstance(symbol, lookup, &lookup.ctx, lookup.ctx.root, pe.identifierOrTemplateInstance.templateInstance);
+ }
+ }
+ }
+ }
+ }
}
}
}
diff --git a/dsymbol/src/dsymbol/conversion/second.d b/dsymbol/src/dsymbol/conversion/second.d
index a7b3580..394faa8 100644
--- a/dsymbol/src/dsymbol/conversion/second.d
+++ b/dsymbol/src/dsymbol/conversion/second.d
@@ -57,6 +57,22 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac
resolveType(currentSymbol.acSymbol, currentSymbol.typeLookups,
moduleScope, cache);
}
+
+ if (currentSymbol.acSymbol.type && currentSymbol.typeLookups.length > 0)
+ {
+ TypeLookup* lookup = currentSymbol.typeLookups.front;
+ if (lookup.ctx.root)
+ {
+ auto type = currentSymbol.acSymbol.type;
+ if (type.kind == structName || type.kind == className || type.kind == functionName)
+ if (lookup.ctx.root.args.length > 0)
+ {
+ DSymbol*[string] mapping;
+ int depth;
+ resolveTemplate(currentSymbol.acSymbol, type, lookup, lookup.ctx.root, moduleScope, cache, depth, mapping);
+ }
+ }
+ }
break;
case importSymbol:
if (currentSymbol.acSymbol.type is null)
@@ -81,8 +97,22 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac
break;
}
+ // let's be methodic about the way we traverse symbols
+ // so that childs have access to resolved symbols
+ // functions should be last, because inside, there might be symbols that references
+ // code from the parent not yet resolved (templates)
+ foreach (child; currentSymbol.children)
+ if (child.acSymbol.kind != CompletionKind.variableName && child.acSymbol.kind != CompletionKind.functionName)
+ secondPass(child, moduleScope, cache);
+
foreach (child; currentSymbol.children)
- secondPass(child, moduleScope, cache);
+ if (child.acSymbol.kind == CompletionKind.variableName)
+ secondPass(child, moduleScope, cache);
+
+ foreach (child; currentSymbol.children)
+ if (child.acSymbol.kind == CompletionKind.functionName)
+ secondPass(child, moduleScope, cache);
+
// Alias this and mixin templates are resolved after child nodes are
// resolved so that the correct symbol information will be available.
@@ -100,6 +130,214 @@ void secondPass(SemanticSymbol* currentSymbol, Scope* moduleScope, ref ModuleCac
break;
}
}
+/**
+ * Extract the return type from the callTip of a function symbol
+ */
+string extractReturnType(string callTip)
+{
+ import std.string: indexOf;
+
+ auto spaceIndex = callTip.indexOf(" ");
+ if (spaceIndex <= 0) return "";
+
+ auto retPart = callTip[0 .. spaceIndex];
+ auto returnTypeConst = retPart.length > 6 ? retPart[0 .. 6] == "const(" : false;
+ auto returnTypeInout = retPart.length > 6 ? retPart[0 .. 6] == "inout(" : false;
+ if (returnTypeConst || returnTypeInout)
+ {
+ retPart = retPart[retPart.indexOf("(") + 1 .. $];
+ retPart = retPart[0 .. retPart.indexOf(")")];
+ }
+ auto returnTypePtr = retPart[$-1] == '*';
+ auto returnTypeArr = retPart[$-1] == ']';
+ if (returnTypePtr)
+ {
+ retPart = retPart[0 .. $-1];
+ }
+ return retPart;
+}
+
+/**
+ * Copy a Type symbol with templates arguments
+ * Returns: Copy of Type symbol
+ */
+DSymbol* createTypeWithTemplateArgs(DSymbol* type, TypeLookup* lookup, VariableContext.TypeInstance* ti, ref ModuleCache cache, Scope* moduleScope, ref int depth, DSymbol*[string] m)
+{
+ assert(type);
+ DSymbol* newType = GCAllocator.instance.make!DSymbol("dummy", CompletionKind.dummy, null);
+ newType.name = type.name;
+ newType.kind = type.kind;
+ newType.qualifier = type.qualifier;
+ newType.protection = type.protection;
+ newType.symbolFile = type.symbolFile;
+ newType.doc = type.doc;
+ newType.callTip = type.callTip;
+ newType.type = type.type;
+ DSymbol*[string] mapping;
+
+ int count = 0;
+ if (ti.args.length > 0)
+ {
+ foreach(part; type.opSlice())
+ {
+ if (part.kind == CompletionKind.typeTmpParam)
+ {
+ scope(exit) count++;
+ if (count >= ti.args.length)
+ {
+ // warning("too many T for args available, investigate");
+ continue;
+ }
+ auto key = part.name;
+
+ DSymbol* first;
+ bool isBuiltin;
+ foreach(i, crumb; ti.args[count].chain)
+ {
+ auto argName = crumb;
+ if (i == 0)
+ {
+ if (m && key in m)
+ {
+ argName = m[key].name;
+ }
+
+ // check if that's a built in type
+ // if it is, then use it and skip the type creation step
+ foreach(builtin; builtinSymbols)
+ {
+ if (builtin.name == crumb)
+ {
+ first = builtin;
+ isBuiltin = true;
+ break;
+ }
+ }
+ auto result = moduleScope.getSymbolsAtGlobalScope(istring(argName));
+ if (result.length == 0)
+ {
+ break;
+ }
+ first = result[0];
+ }
+ else
+ first = first.getFirstPartNamed(istring(argName));
+ }
+
+ if (first is null)
+ continue;
+
+ auto ca = ti.args[count];
+ if (ca.chain.length > 0)
+ mapping[key] = isBuiltin ? first : createTypeWithTemplateArgs(first, lookup, ca, cache, moduleScope, depth, null);
+ }
+ }
+ }
+
+
+ // HACK: to support functions with template arguments that return a generic type
+ // first.d in processParameters only store the function's return type in the callTip
+ // maybe it's time to properly handle it by creating a proper symbol, so we can have
+ // proper support for functions that return complex types such as templates
+ if (type.kind == CompletionKind.functionName)
+ {
+ auto callTip = type.callTip;
+ if (callTip && callTip.length > 1)
+ {
+ auto retType = extractReturnType(callTip);
+ if (retType in mapping)
+ {
+ auto result = mapping[retType];
+ newType.ownType = result.kind == CompletionKind.keyword ? false : true;
+ newType.type = result;
+ }
+ }
+ }
+
+ assert(newType);
+ string[] T_names;
+ foreach(part; type.opSlice())
+ {
+ if (part.kind == CompletionKind.typeTmpParam)
+ {
+ T_names ~= part.name;
+ }
+ else if (part.type && part.type.kind == CompletionKind.typeTmpParam)
+ {
+ DSymbol* newPart = GCAllocator.instance.make!DSymbol(part.name, part.kind, null);
+ newPart.qualifier = part.qualifier;
+ newPart.protection = part.protection;
+ newPart.symbolFile = part.symbolFile;
+ newPart.doc = part.doc;
+ newPart.callTip = part.callTip;
+
+ if (part.type.name in mapping)
+ {
+ auto result = mapping[part.type.name];
+ newPart.ownType = result.kind == CompletionKind.keyword ? false : true;
+ newPart.type = result;
+ }
+ else if (m && part.type.name in m)
+ {
+ auto result = m[part.type.name];
+ newPart.ownType = result.kind == CompletionKind.keyword ? false : true;
+ newPart.type = result;
+ }
+
+ newType.addChild(newPart, true);
+ }
+ else
+ {
+ // BUG: doing it recursively messes with the mapping
+ // i need to debug this and figure out perhaps a better way to do this stuff
+ // maybe move the VariableContext to the symbol directly
+ // i'll need to experiemnt with it
+
+ //DSymbol* part_T;
+ //if (depth < 50)
+ //if (part.type && part.kind == CompletionKind.variableName)
+ //foreach(partPart; part.type.opSlice())
+ //{
+ // if (partPart.kind == CompletionKind.typeTmpParam)
+ // {
+ // part_T = part;
+ // foreach(arg; ti.args)
+ // {
+ // warning(" > ", arg.chain);
+ // foreach(aa; arg.args)
+ // warning(" > ", aa.chain);
+ // }
+ // warning("go agane ".blue, part.name, " ", part.type.name, " with arg: ", ti.chain," Ts: ", T_names);
+ // resolveTemplate(part, part.type, lookup, ti, moduleScope, cache, depth, mapping);
+ // break;
+ // }
+ // //else if (partPart.type && partPart.type.kind == CompletionKind.typeTmpParam)
+ // //{
+ // // warning("here!".red," ", partPart.name," ", partPart.type.name);
+ // //}
+ //}
+ newType.addChild(part, false);
+ }
+ }
+ return newType;
+}
+
+/**
+ * Resolve template arguments
+ */
+void resolveTemplate(DSymbol* variableSym, DSymbol* type, TypeLookup* lookup, VariableContext.TypeInstance* current, Scope* moduleScope, ref ModuleCache cache, ref int depth, DSymbol*[string] mapping = null)
+{
+ depth += 1;
+
+ if (variableSym is null || type is null) return;
+
+ if (current.chain.length == 0) return; // TODO: should not be empty, happens for simple stuff Inner inner;
+
+ DSymbol* newType = createTypeWithTemplateArgs(type, lookup, current, cache, moduleScope, depth, mapping);
+
+ variableSym.type = newType;
+ variableSym.ownType = true;
+}
void resolveImport(DSymbol* acSymbol, ref TypeLookups typeLookups,
ref ModuleCache cache)
@@ -281,6 +519,7 @@ do
if (lastSuffix !is null)
{
assert(suffix !is null);
+ typeSwap(currentSymbol);
suffix.type = currentSymbol;
suffix.ownType = false;
symbol.type = lastSuffix;
diff --git a/dsymbol/src/dsymbol/type_lookup.d b/dsymbol/src/dsymbol/type_lookup.d
index 2260e57..c417c53 100644
--- a/dsymbol/src/dsymbol/type_lookup.d
+++ b/dsymbol/src/dsymbol/type_lookup.d
@@ -37,4 +37,17 @@ struct TypeLookup
UnrolledList!istring breadcrumbs;
/// The kind of type lookup
TypeLookupKind kind;
+ /// To store information about template instances
+ VariableContext ctx;
}
+
+struct VariableContext
+{
+ struct TypeInstance
+ {
+ string[] chain;
+ TypeInstance*[] args;
+ string name;
+ }
+ TypeInstance* root;
+}
\ No newline at end of file
diff --git a/dub.json b/dub.json
index f5bade8..7571586 100644
--- a/dub.json
+++ b/dub.json
@@ -8,7 +8,7 @@
"license": "GPL-3.0",
"dependencies": {
":dsymbol": "*",
- "libdparse": ">=0.23.0 <0.24.0",
+ "libdparse": ">=0.23.2 <0.24.0",
":common": "*",
"emsi_containers": "~>0.9.0"
},
diff --git a/dub.selections.json b/dub.selections.json
index 6513ec2..6c91206 100644
--- a/dub.selections.json
+++ b/dub.selections.json
@@ -3,7 +3,7 @@
"versions": {
"dsymbol": "0.14.1",
"emsi_containers": "0.9.0",
- "libdparse": "0.23.0",
+ "libdparse": "0.23.2",
"msgpack-d": "1.0.4",
"stdx-allocator": "2.77.5"
}
diff --git a/msgpack-d b/msgpack-d
index 26ef07e..480f3bf 160000
--- a/msgpack-d
+++ b/msgpack-d
@@ -1 +1 @@
-Subproject commit 26ef07e16023483ad93e3f86374b19d0e541c924
+Subproject commit 480f3bf9ee80ccf6695ed900cfcc1850ba8da991
diff --git a/tests/tc027/expected1.txt b/tests/tc027/expected1.txt
index 3ce878f..d338689 100644
--- a/tests/tc027/expected1.txt
+++ b/tests/tc027/expected1.txt
@@ -1,9 +1,8 @@
identifiers
-C h
-alignof k
-i v
-init k
-mangleof k
-sizeof k
-stringof k
-tupleof k
+alignof k
+i v int i stdin 21 int
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
diff --git a/tests/tc027/run.sh b/tests/tc027/run.sh
index 2f0f9e4..876777b 100755
--- a/tests/tc027/run.sh
+++ b/tests/tc027/run.sh
@@ -1,5 +1,5 @@
set -e
set -u
-../../bin/dcd-client $1 file.d -c66 > actual1.txt
+../../bin/dcd-client $1 file.d --extended -c66 > actual1.txt
diff actual1.txt expected1.txt --strip-trailing-cr
diff --git a/tests/tc_extended_types/expected1.txt b/tests/tc_extended_types/expected1.txt
index fd102a5..0b5ff23 100644
--- a/tests/tc_extended_types/expected1.txt
+++ b/tests/tc_extended_types/expected1.txt
@@ -1,2 +1,2 @@
identifiers
-bar v foo bar stdin 92
+bar v stdin 92
diff --git a/tests/tc_templates_resolve/complex.d b/tests/tc_templates_resolve/complex.d
new file mode 100644
index 0000000..9f1cb03
--- /dev/null
+++ b/tests/tc_templates_resolve/complex.d
@@ -0,0 +1,94 @@
+struct Data
+{
+ int inside_data;
+ Inner inner;
+}
+
+struct Inner
+{
+ int inside_inner;
+}
+
+struct AganeOne(T)
+{
+ int inside_aganeone;
+ T yo;
+}
+
+struct AganeTwo(T, U)
+{
+ int inside_aganetwo;
+ T yo_T;
+ U yo_U;
+}
+
+struct Other(T)
+{
+ int inside_other;
+ T what;
+ AganeOne!(T) agane_T;
+ AganeOne!(Inner) agane_inner;
+}
+
+struct One(T){ T inside_one; }
+
+struct Outter {
+ struct Two(T, U){ int inside_two; T agane_one; U agane_two; One!(T) one_agane_one; T get_T(T)(){return T.init;} U get_U(){return U.init;} }
+}
+
+struct A{ int inside_a;}
+struct B{ int inside_b;}
+struct C{ int inside_c;}
+
+struct What
+{
+ int inside_what;
+ const(V) get_it(T, U, V)() { return T.init; }
+}
+
+void main()
+{
+ auto from_auto = Outter.Two!(
+ AganeOne!(Other!(Data)),
+ AganeTwo!(A, B)
+ )();
+
+ Outter.Two!(
+ AganeOne!(Other!(Data)),
+ AganeTwo!(A, Other!(B))
+ ) from_normal;
+
+ auto u = from_auto.get_U();
+ auto uuu = from_normal.agane_two;
+
+ auto v = from_normal.get_U();
+
+ What what;
+ auto it = what.get_it!(A, B, C)();
+
+ {
+ from_auto.agane_one.
+ }
+ {
+ from_auto.agane_two.
+ }
+ {
+ from_normal.agane_two.
+ }
+ {
+ from_normal.agane_two.
+ }
+ {
+ u.
+ }
+ {
+ uuu.
+ }
+ {
+ uuu.
+ }
+ {
+ it.
+ }
+
+}
\ No newline at end of file
diff --git a/tests/tc_templates_resolve/expected_1_1.txt b/tests/tc_templates_resolve/expected_1_1.txt
new file mode 100644
index 0000000..7a7b156
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_1_1.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+one_t v One one_t stdin 103 One
+sizeof k
+stringof k
+tupleof k
+value_t v A value_t stdin 0 A
diff --git a/tests/tc_templates_resolve/expected_1_2.txt b/tests/tc_templates_resolve/expected_1_2.txt
new file mode 100644
index 0000000..7485291
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_1_2.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
+value_t v A value_t stdin 0 A
+value_u v B value_u stdin 0 B
diff --git a/tests/tc_templates_resolve/expected_2_1.txt b/tests/tc_templates_resolve/expected_2_1.txt
new file mode 100644
index 0000000..7a7b156
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_2_1.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+one_t v One one_t stdin 103 One
+sizeof k
+stringof k
+tupleof k
+value_t v A value_t stdin 0 A
diff --git a/tests/tc_templates_resolve/expected_2_2.txt b/tests/tc_templates_resolve/expected_2_2.txt
new file mode 100644
index 0000000..7485291
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_2_2.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
+value_t v A value_t stdin 0 A
+value_u v B value_u stdin 0 B
diff --git a/tests/tc_templates_resolve/expected_3_1.txt b/tests/tc_templates_resolve/expected_3_1.txt
new file mode 100644
index 0000000..3172011
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_3_1.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
+value_key v int value_key stdin 0 int
+value_value v int value_value stdin 0 int
diff --git a/tests/tc_templates_resolve/expected_3_2.txt b/tests/tc_templates_resolve/expected_3_2.txt
new file mode 100644
index 0000000..3172011
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_3_2.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
+value_key v int value_key stdin 0 int
+value_value v int value_value stdin 0 int
diff --git a/tests/tc_templates_resolve/expected_3_3.txt b/tests/tc_templates_resolve/expected_3_3.txt
new file mode 100644
index 0000000..3172011
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_3_3.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
+value_key v int value_key stdin 0 int
+value_value v int value_value stdin 0 int
diff --git a/tests/tc_templates_resolve/expected_3_4.txt b/tests/tc_templates_resolve/expected_3_4.txt
new file mode 100644
index 0000000..3172011
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_3_4.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+mangleof k
+sizeof k
+stringof k
+tupleof k
+value_key v int value_key stdin 0 int
+value_value v int value_value stdin 0 int
diff --git a/tests/tc_templates_resolve/expected_3_5.txt b/tests/tc_templates_resolve/expected_3_5.txt
new file mode 100644
index 0000000..9e9e562
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_3_5.txt
@@ -0,0 +1,8 @@
+identifiers
+alignof k
+init k int
+mangleof k
+max k int
+min k int
+sizeof k
+stringof k
diff --git a/tests/tc_templates_resolve/expected_complex_1.txt b/tests/tc_templates_resolve/expected_complex_1.txt
new file mode 100644
index 0000000..e2285c4
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_1.txt
@@ -0,0 +1,9 @@
+identifiers
+alignof k
+init k
+inside_aganeone v int inside_aganeone stdin 124 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo v Other yo stdin 0 Other
diff --git a/tests/tc_templates_resolve/expected_complex_2.txt b/tests/tc_templates_resolve/expected_complex_2.txt
new file mode 100644
index 0000000..4e6e8b6
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_2.txt
@@ -0,0 +1,10 @@
+identifiers
+alignof k
+init k
+inside_aganetwo v int inside_aganetwo stdin 186 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo_T v A yo_T stdin 0 A
+yo_U v B yo_U stdin 0 B
diff --git a/tests/tc_templates_resolve/expected_complex_3.txt b/tests/tc_templates_resolve/expected_complex_3.txt
new file mode 100644
index 0000000..cafd0e5
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_3.txt
@@ -0,0 +1,10 @@
+identifiers
+alignof k
+init k
+inside_aganetwo v int inside_aganetwo stdin 186 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo_T v A yo_T stdin 0 A
+yo_U v Other yo_U stdin 0 Other
diff --git a/tests/tc_templates_resolve/expected_complex_4.txt b/tests/tc_templates_resolve/expected_complex_4.txt
new file mode 100644
index 0000000..cafd0e5
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_4.txt
@@ -0,0 +1,10 @@
+identifiers
+alignof k
+init k
+inside_aganetwo v int inside_aganetwo stdin 186 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo_T v A yo_T stdin 0 A
+yo_U v Other yo_U stdin 0 Other
diff --git a/tests/tc_templates_resolve/expected_complex_5.txt b/tests/tc_templates_resolve/expected_complex_5.txt
new file mode 100644
index 0000000..4e6e8b6
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_5.txt
@@ -0,0 +1,10 @@
+identifiers
+alignof k
+init k
+inside_aganetwo v int inside_aganetwo stdin 186 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo_T v A yo_T stdin 0 A
+yo_U v B yo_U stdin 0 B
diff --git a/tests/tc_templates_resolve/expected_complex_6.txt b/tests/tc_templates_resolve/expected_complex_6.txt
new file mode 100644
index 0000000..cafd0e5
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_6.txt
@@ -0,0 +1,10 @@
+identifiers
+alignof k
+init k
+inside_aganetwo v int inside_aganetwo stdin 186 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo_T v A yo_T stdin 0 A
+yo_U v Other yo_U stdin 0 Other
diff --git a/tests/tc_templates_resolve/expected_complex_7.txt b/tests/tc_templates_resolve/expected_complex_7.txt
new file mode 100644
index 0000000..cafd0e5
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_7.txt
@@ -0,0 +1,10 @@
+identifiers
+alignof k
+init k
+inside_aganetwo v int inside_aganetwo stdin 186 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
+yo_T v A yo_T stdin 0 A
+yo_U v Other yo_U stdin 0 Other
diff --git a/tests/tc_templates_resolve/expected_complex_8.txt b/tests/tc_templates_resolve/expected_complex_8.txt
new file mode 100644
index 0000000..eda0ac9
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_complex_8.txt
@@ -0,0 +1,8 @@
+identifiers
+alignof k
+init k
+inside_c v int inside_c stdin 605 int
+mangleof k
+sizeof k
+stringof k
+tupleof k
diff --git a/tests/tc_templates_resolve/expected_extra_1.txt b/tests/tc_templates_resolve/expected_extra_1.txt
new file mode 100644
index 0000000..3a23887
--- /dev/null
+++ b/tests/tc_templates_resolve/expected_extra_1.txt
@@ -0,0 +1,2 @@
+identifiers
+read_test f void read_test() stdin 38 void
diff --git a/tests/tc_templates_resolve/file1.d b/tests/tc_templates_resolve/file1.d
new file mode 100644
index 0000000..16fa8cf
--- /dev/null
+++ b/tests/tc_templates_resolve/file1.d
@@ -0,0 +1,31 @@
+struct A
+{
+ int inside_a;
+}
+struct B
+{
+ int inside_b;
+}
+struct One(T)
+{
+ T value_t;
+ One!T one_t;
+}
+
+struct Two(T, U)
+{
+ T value_t;
+ U value_u;
+}
+
+void main()
+{
+ auto from_auto_one = One!A();
+ auto from_auto_two = Two!(A, B)();
+ {
+ from_auto_one.
+ }
+ {
+ from_auto_two.
+ }
+}
diff --git a/tests/tc_templates_resolve/file2.d b/tests/tc_templates_resolve/file2.d
new file mode 100644
index 0000000..25e561b
--- /dev/null
+++ b/tests/tc_templates_resolve/file2.d
@@ -0,0 +1,31 @@
+struct A
+{
+ int inside_a;
+}
+struct B
+{
+ int inside_b;
+}
+struct One(T)
+{
+ T value_t;
+ One!T one_t;
+}
+
+struct Two(T, U)
+{
+ T value_t;
+ U value_u;
+}
+
+void main()
+{
+ One!A from_normal_one;
+ Two!(A, B) from_normal_two;
+ {
+ from_normal_one.
+ }
+ {
+ from_normal_two.
+ }
+}
diff --git a/tests/tc_templates_resolve/file3.d b/tests/tc_templates_resolve/file3.d
new file mode 100644
index 0000000..946c176
--- /dev/null
+++ b/tests/tc_templates_resolve/file3.d
@@ -0,0 +1,49 @@
+struct TopHashMap(Key, Value)
+{
+ Key value_key;
+ Value value_value;
+}
+
+void main()
+{
+ auto top = TopHashMap!(int, int)();
+ auto bottom = BottomHashMap!(int, int)();
+ {
+ top.
+ }
+ {
+ auto copy = top;
+ copy.
+ }
+ {
+ bottom.
+ }
+ {
+ auto copy = bottom;
+ copy.
+ }
+ {
+ auto wf = WithFunction!(int, int)();
+ auto gkey = wf.get_key();
+ gkey.
+ }
+}
+
+struct BottomHashMap(Key, Value)
+{
+ Key value_key;
+ Value value_value;
+}
+
+struct WithFunction(Key, Value)
+{
+ Key get_key()
+ {
+ return Key.init;
+ }
+
+ Value get_value()
+ {
+ return Value.init;
+ }
+}
diff --git a/tests/tc_templates_resolve/file4.d b/tests/tc_templates_resolve/file4.d
new file mode 100644
index 0000000..2a9ab33
--- /dev/null
+++ b/tests/tc_templates_resolve/file4.d
@@ -0,0 +1,12 @@
+struct ReaderTest(bool LE)
+{
+ void read_test(){}
+}
+alias ReaderTestBE = ReaderTest!true;
+struct Test
+{
+ void read(ReaderTestBE* reader)
+ {
+ reader.re
+ }
+}
diff --git a/tests/tc_templates_resolve/run.sh b/tests/tc_templates_resolve/run.sh
new file mode 100755
index 0000000..afb5f9f
--- /dev/null
+++ b/tests/tc_templates_resolve/run.sh
@@ -0,0 +1,63 @@
+#!/bin/bash
+
+set -e
+set -u
+
+MODE=$1
+
+function check () {
+ echo "$1 $2"
+ ../../bin/dcd-client $MODE $1.d --extended -c $2 > $3.txt
+ diff $3.txt $4.txt --strip-trailing-cr
+}
+
+
+#echo "extra"
+check file4 165 actual_extra_1 expected_extra_1
+
+
+#echo "test1"
+check file1 280 actual_1_1 expected_1_1
+
+
+#echo "test2"
+check file1 315 actual_1_2 expected_1_2
+
+
+#echo "test3"
+check file2 268 actual_2_1 expected_2_1
+
+
+#echo "test4"
+check file2 305 actual_2_2 expected_2_2
+
+
+#echo "test5"
+check file3 195 actual_3_1 expected_3_1
+
+
+#echo "test6"
+check file3 246 actual_3_2 expected_3_2
+
+
+#echo "test7"
+check file3 274 actual_3_3 expected_3_3
+
+
+#echo "test8"
+check file3 328 actual_3_4 expected_3_4
+
+
+#echo "test9"
+check file3 433 actual_3_5 expected_3_5
+
+
+#echo "test complex"
+check complex 1121 actual_complex_1 expected_complex_1
+check complex 1162 actual_complex_2 expected_complex_2
+check complex 1205 actual_complex_3 expected_complex_3
+check complex 1248 actual_complex_4 expected_complex_4
+check complex 1271 actual_complex_5 expected_complex_5
+check complex 1296 actual_complex_6 expected_complex_6
+check complex 1321 actual_complex_7 expected_complex_7
+check complex 1345 actual_complex_8 expected_complex_8
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment