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 enum isManifestConstant(T, string name) = isManifestConstant!(__traits(getMember, T, name)); 66 67 /// ditto 68 enum isManifestConstant(alias symbol) = __traits(compiles, { enum e = symbol; }) && 69 !__traits(compiles, { const ptr = &symbol; }); 70 71 /// it should describe a public manifest constant 72 unittest { 73 struct Test { 74 enum config = 3; 75 } 76 77 auto result = describeManifestConstant!(Test, "config"); 78 79 result.name.should.equal("config"); 80 result.value.should.equal("3"); 81 82 result.type.name.should.equal("int"); 83 result.type.isManifestConstant.should.equal(true); 84 85 result.protection.should.equal(Protection.public_); 86 87 result.location.file.should.equal("source/introspection/manifestConstant.d"); 88 result.location.line.should.be.greaterThan(0); 89 result.location.column.should.equal(3); 90 } 91 92 /// it should describe a private manifest constant 93 unittest { 94 struct Test { 95 private enum config = "test"; 96 } 97 98 auto result = describeManifestConstant!(Test, "config"); 99 100 result.name.should.equal("config"); 101 result.value.should.equal("test"); 102 103 result.type.name.should.equal("string"); 104 result.type.isManifestConstant.should.equal(true); 105 106 result.protection.should.equal(Protection.private_); 107 }