1 module glued.codescan.scanner;
2 
3 import std.meta;
4 
5 import glued.codescan.unrollscan;
6 public import glued.codescan.listener;
7 public import glued.codescan.scannable;
8 
9 import glued.logging;
10 import glued.mirror;
11 
12 class CodebaseScanner(State, Listeners...) 
13 //    if (__traits(compiles, new CompositeListener!(State, Listeners)()))  //todo?
14 {   
15     mixin CreateLogger;
16     private Logger log;
17     private bool _frozen = false;
18     private CompositeListener!(State, Listeners) listener = new CompositeListener!(State, Listeners);
19     
20     this(State initialState, LogSink sink=new VoidSink) {
21         log = Logger(sink);
22         log.info.emit("Initializing scan listeners with ", initialState);
23         listener.init(initialState);
24     }
25     
26     void scan(scannables...)() 
27     {
28         static foreach (s; scannables){
29             scan!s();
30         }
31     }
32     
33     void scan(alias scannable)()
34         if (isScannable!(scannable))
35     { 
36         //todo assert not frozen
37         //todo if we move these into private methods, we can log.trace whats going on
38 //        enum typeConsumer(string m, string n) = "listener.onType!(import_!(\""~m~"\", \""~n~"\"))();";
39         enum typeConsumer(string m, string n) = "onType!(\""~m~"\", \""~n~"\")();";
40         enum bundleConsumer(string modName) = "listener.onBundleModule!(\""~modName~"\")();";
41         
42         mixin unrollLoopThrough!(scannable, "void doScan() { ", typeConsumer, bundleConsumer, "}");
43         listener.onScannable!(scannable)();
44         log.info.emit("Scanning ", scannable);
45         doScan();
46         log.info.emit("Scan of ", scannable, " finished");
47     }
48     
49     private void onType(string m, string n)(){
50         alias T = import_!(m, n);
51         listener.onType!T();
52     }
53     
54     void freeze(){
55         log.info.emit("Freezing scanner");
56         _frozen = true;
57         listener.onScannerFreeze();
58     }
59     
60     @property
61     bool frozen(){
62         return _frozen;
63     }
64 }
65 
66