1 module mage.target; 2 3 import pathlib; 4 5 public __gshared ITarget[] targets; 6 7 interface ITarget 8 { 9 string toString() const; 10 Path[] getSourceFiles(); 11 } 12 13 14 mixin template TargetCommonMixin() 15 { 16 string name; 17 Path[] sourceFiles; 18 19 this() { 20 } 21 22 override string toString() const { 23 return name; 24 } 25 26 override Path[] getSourceFiles() { 27 return sourceFiles; 28 } 29 } 30 31 32 // UDA 33 struct Target 34 { 35 } 36 37 38 class Executable : ITarget 39 { 40 mixin TargetCommonMixin; 41 } 42 43 44 enum LibraryType 45 { 46 Static, 47 Shared 48 } 49 50 class Library : ITarget 51 { 52 mixin TargetCommonMixin; 53 54 LibraryType libType = LibraryType.Static; 55 56 this(LibraryType libType) { 57 this.libType = libType; 58 } 59 } 60 61 62 interface ITargetFactory 63 { 64 abstract @property Path filePath() const; 65 abstract ITarget create(); 66 } 67 68 __gshared ITargetFactory[] targetFactories; 69 70 class TargetWrapper(TargetType) : ITargetFactory 71 { 72 import std.stdio; 73 private: 74 Path m_filePath; 75 76 public: 77 78 override @property Path filePath() const { return m_filePath; } 79 80 alias WrappedType = TargetType; 81 82 this(Path filePath) { 83 import std.conv : to; 84 m_filePath = filePath; 85 } 86 87 override ITarget create() { 88 return new TargetType(); 89 } 90 } 91 92 mixin template registerMageFile(alias T, alias filePath) { 93 import mage.util.reflection; 94 shared static this() { 95 pragma(msg, "[mage] Reflecting module: " ~ T.stringof); 96 foreach(m; __traits(allMembers, T)) { 97 static if(!__traits(compiles, typeof(__traits(getMember, T, m)))) { 98 static if(__traits(compiles, ResolveType!(__traits(getMember, T, m)))) { 99 alias Type = ResolveType!(__traits(getMember, T, m)); 100 static if(is(Type == class)) { 101 if(Type.stringof != "MageFileInstance") { 102 pragma(msg, "[mage] Found a class: " ~ Type.stringof); 103 foreach(uda; __traits(getAttributes, Type)) { 104 static if(is(uda == Target)) { 105 pragma(msg, "[mage] Found a target! " ~ uda.stringof); 106 static if(!__traits(compiles, new Type())) { 107 pragma(msg, "[mage] WARNING: Target is not instantiable with `new`."); 108 } 109 targetFactories ~= new TargetWrapper!Type(Path(filePath)); 110 } 111 else { 112 pragma(msg, "[mage] Found some UDA: " ~ uda.stringof); 113 } 114 } 115 } 116 } 117 else { 118 pragma(msg, "[mage] Found something: " ~ Type.stringof); 119 } 120 } 121 } 122 else { 123 alias Type = typeof(__traits(getMember, T, m)); 124 pragma(msg, "[mage] Module member: " ~ Type.stringof); 125 } 126 } 127 } 128 } 129 130 mixin template M_MageFileMixin() 131 { 132 class MageFileInstance{} 133 134 // The parent of MageFileInstance is the module. 135 mixin registerMageFile!(__traits(parent, MageFileInstance), M_mageFilePath); 136 }