1 /** 2 * These are core annotations for the whole framework. To avoid recursive checks, 3 * they are not annotated with constraints, but supported usage is documented 4 * with annotations in doc comments. 5 */ 6 module glued.annotations.core_annotations; 7 8 import std.meta: Alias; 9 import std.traits: hasUDA; 10 11 import glued.annotations.common_annotations; 12 import glued.annotations.common_impl; 13 14 ///UDA for "magic annotations" like OnParameter, that should be filtered out 15 /// when retrieving target annotations 16 enum GluedMagic; 17 18 ///Strictly documentational UDA; totally ignored by a framework, but defines 19 /// how the "magic" annotation would be used. 20 @GluedMagic 21 enum MagicUsage(T...) = "And this is how we do it"; 22 23 @GluedMagic 24 @MagicUsage!(OnAnnotation, Repeatable, NonImplicable) 25 struct CheckedBy(alias Checker) 26 { 27 ///bool foo(alias target, alias annotation, alias constraint)() 28 ///where target is a symbol and annotation and constraint are values (struct 29 ///instances) 30 alias Check = Checker; 31 32 static bool check(T...)() 33 { 34 return Checker!(T)(); 35 } 36 } 37 38 /** 39 * If this annotation is present on another annotation, the annotated one cannot 40 * be subject of Implies!(...). 41 */ 42 @GluedMagic 43 struct NonImplicable {} 44 45 @GluedMagic 46 struct Implies(S) 47 if (is(S == struct)) 48 { 49 static assert(!hasUDA!(S, NonImplicable), "Annotation "~fullyQualifiedName!S~" is not implicable and as such cannot be used in Implies!(...)"); 50 ///Annotation "brought" by the one annotated with Implies 51 const S implicated = S.init; 52 53 template getImplicated() 54 { 55 alias getImplicated = Alias!(S.init); 56 } 57 } 58 59 @GluedMagic 60 struct Implies(alias S) 61 if (is(typeof(S) == struct)) 62 { 63 static assert(!hasUDA!(typeof(S), NonImplicable), "Annotation "~fullyQualifiedName!(typeof(S))~" is not implicable and as such cannot be used in Implies!(...)"); 64 65 ///ditto 66 const typeof(S) implicated = S; 67 68 template getImplicated() 69 { 70 alias getImplicated = Alias!(S); 71 } 72 } 73 74 //todo actually figure out parameter annotations instead of using this weird 'pointers' 75 @GluedMagic 76 @MagicUsage!(Repeatable, Target(TargetType.FUNCTION)) 77 struct OnParameter(size_t _paramIdx, alias _annotation) 78 { 79 enum paramIdx = _paramIdx; 80 alias annotation = _annotation; 81 82 enum describesParam(string name, size_t idx) = (idx == paramIdx); 83 } 84 85 @GluedMagic 86 @MagicUsage!(Repeatable, Target(TargetType.FUNCTION)) 87 struct OnParameter(string _paramName, alias _annotation) 88 { 89 enum paramName = _paramName; 90 alias annotation = _annotation; 91 92 enum describesParam(string name, size_t idx) = (name == paramName); 93 }