1 module described; 2 3 import introspection.type; 4 import introspection.callable; 5 import introspection.aggregate; 6 import introspection.module_; 7 import introspection.enum_; 8 9 public import selectors.where; 10 public import selectors.has; 11 12 import std.traits; 13 14 version(unittest) { 15 import fluent.asserts; 16 } 17 18 /// Describe a build in type 19 Type describe(T)() if(isBuiltinType!T) { 20 return describeType!T; 21 } 22 23 /// It should describe an int 24 unittest { 25 enum result = describeType!int; 26 result.name.should.equal("int"); 27 } 28 29 /// Describe a callable 30 Callable describe(alias T)() if(isCallable!T) { 31 return describeCallable!T; 32 } 33 34 /// It should describe a function 35 unittest { 36 void test() { } 37 38 enum result = describe!test; 39 40 result.name.should.equal("test"); 41 result.type.name.should.equal("pure nothrow @nogc @safe void()"); 42 } 43 44 /// It should describe class method 45 unittest { 46 class Test { 47 void test() { } 48 } 49 50 enum result = describe!(Test.test); 51 52 result.name.should.equal("test"); 53 result.type.name.should.equal("@system void()"); 54 } 55 56 /// Describe a build in type 57 Module describe(alias T)() if(__traits(isModule, T)) { 58 return describeModule!T; 59 } 60 61 /// It should describe a function 62 unittest { 63 enum result = describe!(introspection.template_); 64 65 result.name.should.equal("module template_"); 66 } 67 68 /// Describe a build in type 69 Aggregate describe(T)() if(isAggregateType!T) { 70 return describeAggregate!T; 71 } 72 73 /// It should describe a class 74 unittest { 75 class C3 { } 76 77 auto result = describe!C3; 78 79 result.name.should.equal("C3"); 80 } 81 82 /// Describe an enum 83 auto describe(alias T)() if(is(T == enum)) { 84 return describeEnum!T; 85 } 86 87 /// It should describe an enum 88 unittest { 89 enum Something { A, B } 90 91 auto result = describe!Something; 92 93 result.name.should.equal("Something"); 94 } 95 96 /// Describe a type 97 Aggregate describe(Type type)() if(type.isClass || type.isStruct || type.isUnion || type.isInterface) { 98 return describe!(fromType!type); 99 } 100 101 /// It should describe a class by type 102 unittest { 103 enum result = describe!(describe!RandomClass.type); 104 105 result.name.should.equal("RandomClass"); 106 } 107 108 /// Get a symbol from the type definition 109 template fromType(alias type) { 110 mixin(`import ` ~ type.module_ ~ ` : ` ~ type.name ~ `;`); 111 mixin(`alias fromType = ` ~ type.fullyQualifiedName ~ `;`); 112 } 113 114 version(unittest) class RandomClass { } 115 116 /// It should get the symbol from the type definition 117 unittest { 118 alias T = fromType!(describe!RandomClass.type); 119 120 static assert(is(T == RandomClass)); 121 }