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 }