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