module meta.search; public import std.meta; public import std.traits; public import meta.seq; public import std.algorithm; private import net.test; @TestUDA struct Y { int y; } template MapMemberStringToSymbol(alias Unit, alias Member) { alias MapMemberStringToSymbol = Alias!(__traits(getMember, Unit, Member)); } template AllMemberSymbols (alias Unit) { alias AllMemberSymbols = staticMap!(ApplyLeft!(MapMemberStringToSymbol, Unit), AliasSeq!(__traits(allMembers, Unit))); } bool isPackage(alias Member)() { static if (__traits(isStaticFunction, Member)) return false; else return startsWith(Member.stringof, "package "); } bool isModule(alias Member)() { static if (__traits(isStaticFunction, Member)) return false; else return startsWith(Member.stringof, "module "); } template SubPackages(alias Unit) { alias SubPackages = Filter!(isPackage, AllMemberSymbols!(Unit)); } template SubModules(alias Unit) { alias SubModules = Filter!(isModule, AllMemberSymbols!(Unit)); } template SubSymbols(alias Unit) { alias SubSymbols = Difference!(AllMemberSymbols!Unit).To!(SubPackages!Unit, SubModules!Unit); } template RecurseTransitiveSearchUDA (alias UDA, Ignored...) { template Call (alias Unit) { pragma (msg, "Searching in: " ~ Unit.stringof); alias OwnSymbols = Filter!(ApplyRight!(hasUDA, UDA), SubSymbols!Unit); pragma (msg, "Symbols: "); pragma (msg, staticMap!(fullyQualifiedName, SubSymbols!Unit)); pragma (msg, "UDA Symbols: "); pragma (msg, staticMap!(fullyQualifiedName, OwnSymbols)); alias NewPackages = Difference!(SubPackages!(Unit)).To!(Ignored); alias NewModules = Difference!(SubModules!(Unit)).To!(Ignored); alias NewModulesAndPackages = AliasSeq!(NewPackages,NewModules); alias NewIgnored = NoDuplicates!(Ignored, NewModulesAndPackages); pragma (msg, "Modules and Packages: "); pragma (msg, staticMap!(fullyQualifiedName, NewModulesAndPackages)); alias Recursor = RecurseTransitiveSearchUDA!(UDA, NewIgnored).Call; alias SubModuleSymbols = staticMap!(Recursor, NewModulesAndPackages); alias Call = AliasSeq!(OwnSymbols, SubModuleSymbols); } } template TransitiveSearchUDA (alias UDA, alias Unit) { alias TransitiveSearchUDA = RecurseTransitiveSearchUDA!(UDA, AliasSeq!(object, std)).Call!(Unit); }