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 }