1 module introspection.manifestConstant; 2 3 import std.traits; 4 import std.conv; 5 6 import introspection.type; 7 import introspection.location; 8 import introspection.protection; 9 10 version(unittest) { 11 import fluent.asserts; 12 } 13 14 /// Stores information about manifest constants 15 struct ManifestConstant { 16 /// The constant name 17 string name; 18 19 /// 20 string value; 21 22 /// 23 Type type; 24 25 /// 26 Protection protection; 27 28 /// 29 Location location; 30 } 31 32 /// Describe a manifest constant defined in aggregate types 33 ManifestConstant describeManifestConstant(T, string member)() { 34 ManifestConstant manifestConstant; 35 36 manifestConstant.name = member; 37 manifestConstant.value = __traits(getMember, T, member).to!string; 38 manifestConstant.type = describeType!(__traits(getMember, T, member)); 39 40 auto location = __traits(getLocation, T); 41 manifestConstant.location = Location(location[0], location[1], location[2]); 42 43 manifestConstant.protection = __traits(getProtection, __traits(getMember, T, member)).toProtection; 44 45 return manifestConstant; 46 } 47 48 /// ditto 49 ManifestConstant describeManifestConstant(alias T, string member)() { 50 ManifestConstant manifestConstant; 51 52 manifestConstant.name = member; 53 manifestConstant.value = __traits(getMember, T, member).to!string; 54 manifestConstant.type = describeType!(__traits(getMember, T, member)); 55 56 auto location = __traits(getLocation, __traits(getMember, T, member)); 57 manifestConstant.location = Location(location[0], location[1], location[2]); 58 59 manifestConstant.protection = __traits(getProtection, __traits(getMember, T, member)).toProtection; 60 61 return manifestConstant; 62 } 63 64 /// Check if a member is manifest constant 65 bool isManifestConstant(T, string name)() { 66 mixin(`return is(typeof(T.init.` ~ name ~ `)) && !is(typeof(&T.init.` ~ name ~ `));`); 67 } 68 69 /// ditto 70 bool isManifestConstant(alias T)() { 71 return is(typeof(T)) && !is(typeof(&T)); 72 } 73 74 /// it should describe a public manifest constant 75 unittest { 76 struct Test { 77 enum config = 3; 78 } 79 80 auto result = describeManifestConstant!(Test, "config"); 81 82 result.name.should.equal("config"); 83 result.value.should.equal("3"); 84 85 result.type.name.should.equal("int"); 86 result.type.isManifestConstant.should.equal(true); 87 88 result.protection.should.equal(Protection.public_); 89 90 result.location.file.should.equal("source/introspection/manifestConstant.d"); 91 result.location.line.should.be.greaterThan(0); 92 result.location.column.should.equal(3); 93 } 94 95 /// it should describe a private manifest constant 96 unittest { 97 struct Test { 98 private enum config = "test"; 99 } 100 101 auto result = describeManifestConstant!(Test, "config"); 102 103 result.name.should.equal("config"); 104 result.value.should.equal("test"); 105 106 result.type.name.should.equal("string"); 107 result.type.isManifestConstant.should.equal(true); 108 109 result.protection.should.equal(Protection.private_); 110 }