I had a week of no internet access, so I had far too much time on my hands.
[mono.git] / mcs / tools / type-reflector / TypeLoader.cs
1 //
2 // TypeLoader.cs: Loads types from a list of Assemblies
3 //
4 // Author: Jonathan Pryor (jonpryor@vt.edu)
5 //
6 // (C) 2002 Jonathan Pryor
7 //
8
9 using System;
10 using System.Collections;
11 using System.IO;
12 using System.Diagnostics;
13 using System.Reflection;
14 using System.Text;
15 using System.Text.RegularExpressions;
16
17 namespace Mono.TypeReflector
18 {
19         public class TypeLoader {
20
21                 private static TraceSwitch info = 
22                         new TraceSwitch ("type-loader", "TypeLoader messages");
23
24                 // String collection
25                 private ICollection assemblies = null;
26
27                 private bool matchFullName = true;
28                 private bool matchName = false;
29                 private bool matchBase = false;
30                 private bool matchMethodReturnType = false;
31                 private bool matchNamespace = false;
32
33                 public bool MatchFullName {
34                         get {return matchFullName;}
35                         set {matchFullName = value;}
36                 }
37
38                 public bool MatchClassName {
39                         get {return matchName;}
40                         set {matchName = value;}
41                 }
42
43                 public bool MatchBase {
44                         get {return matchBase;}
45                         set {matchBase = value;}
46                 }
47
48                 public bool MatchMethodReturnType {
49                         get {return matchMethodReturnType;}
50                         set {matchMethodReturnType = value;}
51                 }
52
53                 public bool MatchNamespace {
54                         get {return matchNamespace;}
55                         set {matchNamespace = value;}
56                 }
57
58                 public TypeLoader ()
59                 {
60                 }
61
62                 public TypeLoader (ICollection assemblies)
63                 {
64                         this.assemblies = assemblies;
65                 }
66
67                 public ICollection Assemblies {
68                         get {return assemblies;}
69                         set {assemblies = value;}
70                 }
71
72                 public ICollection LoadTypes (IList match)
73                 {
74                         if (assemblies == null)
75                                 throw new ArgumentNullException ("Assemblies");
76                         if (match == null || match.Count == 0)
77                                 throw new ArgumentNullException ("match");
78
79                         StringBuilder regex = new StringBuilder ();
80                         regex.Append (match[0]);
81                         for (int i = 1; i < match.Count; ++i)
82                                 regex.AppendFormat ("|{0}", match[i]);
83
84                         Regex re = new Regex (regex.ToString());
85
86                         Trace.WriteLineIf (info.TraceInfo, 
87                                         string.Format ("using regex: '{0}'", regex.ToString()));
88
89                         IList found = new ArrayList ();
90
91                         foreach (string a in assemblies) {
92                                 LoadMatchingTypesFrom (a, regex.ToString(), re, found);
93                         }
94
95                         return found;
96                 }
97
98                 private void LoadMatchingTypesFrom (string where, string regex, Regex re, IList types)
99                 {
100                         try {
101                                 Assembly a = Assembly.LoadFrom (where);
102                                 Type[] _types = a.GetTypes();
103                                 foreach (Type t in _types) {
104                                         if (Matches (re, t))
105                                                 types.Add (t);
106                                 }
107                         } catch (Exception e) {
108                                 Trace.WriteLineIf (info.TraceError, String.Format (
109                                         "Unable to load type regex `{0}' from `{1}'.",
110                                         regex, where));
111                                 Trace.WriteLineIf (info.TraceError, e.ToString());
112                         }
113                 }
114
115                 private bool Matches (Regex r, Type t)
116                 {
117                         bool f, c, b, rt, n;
118                         f = c = b = rt = n = false;
119                         if (MatchFullName)
120                                 f = r.Match(t.FullName).Success;
121                         else if (MatchClassName)
122                                 c = r.Match(t.Name).Success;
123                         else if (MatchNamespace)
124                                 n = r.Match(t.Namespace).Success;
125                         if (MatchBase) {
126                                 b = (!MatchFullName ? false : r.Match (t.BaseType.FullName).Success) ||
127                                     (!MatchClassName ? false : r.Match (t.BaseType.Name).Success) ||
128                                     (!MatchNamespace ? false : r.Match (t.BaseType.Namespace).Success);
129                         }
130                         // TODO: MatchMethodReturnType
131                         Trace.WriteLineIf (info.TraceInfo, String.Format("TypeLoader.Matches: c={0}, b={1}, rt={2}, n={3}", c, b, rt, n));
132                         return f || c || b || rt || n;
133                 }
134         }
135 }
136