1 module glued.annotations.common_impl; 2 3 import std.traits; 4 5 import glued.utils; 6 7 enum TargetType { 8 MODULE = 1 << 31, //non-target ; 31 is max value when using << 9 FUNCTION = 1<<0, 10 VARIABLE = 1<<1, 11 INTERFACE = 1<<2, 12 CLASS = 1<<3, 13 STRUCT = 1<<4, 14 ENUM = 1<<5, 15 //todo consider making annotations, templates, unittests targets as well; introduce RAW_STRUCT and friends, TEMPLATE, and then STRUCT = RAW_STRUCT | TEMPLATE 16 17 CODE = (FUNCTION | VARIABLE), 18 19 DATA = (STRUCT | ENUM), 20 POINTER = (INTERFACE | CLASS), 21 TYPE = (DATA | POINTER), 22 23 ANY = (CODE | TYPE) 24 } 25 26 bool TargetChecker(alias target, alias annotation, alias constraint)(){ 27 return constraint.canAnnotate(TargetTypeOf!(target)); 28 } 29 30 bool TargetOwnerChecker(alias target, alias annotation, alias constraint)(){ 31 return constraint.canAnnotate(TargetTypeOf!(__traits(parent, target))); 32 } 33 34 template TargetTypeOf(T...) if (T.length == 1) { 35 static if (is(T[0])) { 36 static if (is(T[0] == class)){ 37 enum TargetTypeOf = TargetType.CLASS; 38 } 39 else 40 static if (is(T[0] == interface)){ 41 enum TargetTypeOf = TargetType.INTERFACE; 42 } 43 else 44 static if (is(T[0] == struct)){ 45 enum TargetTypeOf = TargetType.STRUCT; 46 } 47 static if (is(T[0] == enum)){ 48 enum TargetTypeOf = TargetType.ENUM; 49 } 50 } else { 51 static if (isFunction!(T[0])) 52 { 53 enum TargetTypeOf = TargetType.FUNCTION; 54 } 55 else 56 { 57 static if (__traits(compiles, typeof(T[0]))) 58 { 59 enum TargetTypeOf = TargetType.VARIABLE; 60 } 61 else 62 { 63 enum TargetTypeOf = TargetType.MODULE; 64 } 65 } 66 } 67 } 68 69 bool RepeatableChecker(alias target, alias annotation, alias constraint)(){ 70 import glued.annotations.core_impl: getUncheckedAnnotations; 71 import std.meta: Filter; 72 73 immutable occurences = Filter!(ofType!(toType!(annotation)), getUncheckedAnnotations!(target)).length; 74 return constraint.boundaries.check(occurences); 75 }