* Makefile.am:
[monodevelop.git] / extras / MonoDevelop.Debugger.Mdb / Mono.Debugging.Server.Mdb / NamespaceValueReference.cs
blob0e7a2b728a962ce216daa8f7f62907718359a973
1 // NamespaceValueReference.cs
2 //
3 // Author:
4 // Lluis Sanchez Gual <lluis@novell.com>
5 //
6 // Copyright (c) 2008 Novell, Inc (http://www.novell.com)
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining a copy
9 // of this software and associated documentation files (the "Software"), to deal
10 // in the Software without restriction, including without limitation the rights
11 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 // copies of the Software, and to permit persons to whom the Software is
13 // furnished to do so, subject to the following conditions:
15 // The above copyright notice and this permission notice shall be included in
16 // all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 // THE SOFTWARE.
28 using System;
29 using System.Reflection;
30 using System.Collections;
31 using System.Collections.Generic;
32 using Mono.Debugger;
33 using Mono.Debugger.Languages;
34 using MD = Mono.Debugger;
35 using Mono.Debugging.Client;
37 namespace DebuggerServer
39 public class NamespaceValueReference: ValueReference
41 string name;
42 string namspace;
43 string[] namespaces;
45 public NamespaceValueReference (EvaluationContext ctx, string name): base (ctx)
47 this.namspace = name;
48 int i = namspace.LastIndexOf ('.');
49 if (i != -1)
50 this.name = namspace.Substring (i+1);
51 else
52 this.name = namspace;
55 public override Mono.Debugger.Languages.TargetObject Value {
56 get {
57 throw new NotSupportedException();
59 set {
60 throw new NotSupportedException();
65 public override Mono.Debugger.Languages.TargetType Type {
66 get {
67 throw new NotSupportedException();
72 public override object ObjectValue {
73 get {
74 throw new NotSupportedException ();
79 public override string Name {
80 get {
81 return name;
86 public override ObjectValueFlags Flags {
87 get {
88 return ObjectValueFlags.Namespace;
92 public override ValueReference GetChild (string name)
94 string newNs = namspace + "." + name;
96 TargetType t = Context.Frame.Language.LookupType (newNs);
97 if (t != null)
98 return new TypeValueReference (Context, t);
100 if (namespaces == null)
101 namespaces = Context.Frame.Method.GetNamespaces ();
103 foreach (string ns in namespaces) {
104 if (ns == newNs || ns.StartsWith (newNs + "."))
105 return new NamespaceValueReference (Context, newNs);
107 return null;
110 public override ObjectValue[] GetChildren (Mono.Debugging.Client.ObjectPath path, int index, int count)
112 List<ObjectValue> obs = new List<ObjectValue> ();
113 foreach (ValueReference val in GetChildReferences ()) {
114 obs.Add (val.CreateObjectValue ());
116 return obs.ToArray ();
119 public override IEnumerable<ValueReference> GetChildReferences ()
121 // Child types
123 List<string> types = new List<string> ();
124 HashSet<string> namespaces = new HashSet<string> ();
125 HashSet<object> visited = new HashSet<object> ();
126 object methodHandle = Context.Frame.Method.MethodHandle;
128 if (methodHandle != null && methodHandle.GetType ().FullName == "Mono.Cecil.MethodDefinition") {
129 object declaringType = GetProp (methodHandle, "DeclaringType");
130 object module = GetProp (declaringType, "Module");
131 object assembly = GetProp (module, "Assembly");
132 object resolver = GetProp (assembly, "Resolver");
133 FindTypes (resolver, visited, types, namespaces, assembly);
136 foreach (string typeName in types) {
137 TargetType tt = Context.Frame.Language.LookupType (typeName);
138 if (tt != null)
139 yield return new TypeValueReference (Context, tt);
142 // Child namespaces
143 foreach (string ns in namespaces)
144 yield return new NamespaceValueReference (Context, ns);
147 public void FindTypes (object resolver, HashSet<object> visited, List<string> types, HashSet<string> namespaces, object asm)
149 if (!visited.Add (asm))
150 return;
152 string namspaceDotted = namspace + ".";
153 object mainModule = GetProp (asm, "MainModule");
154 foreach (object typeDefinition in (IEnumerable) GetProp (mainModule, "Types")) {
155 bool isPublic = (bool) GetProp (typeDefinition, "IsPublic");
156 bool isInterface = (bool) GetProp (typeDefinition, "IsInterface");
157 bool isEnum = (bool) GetProp (typeDefinition, "IsEnum");
158 string typeNamespace = (string) GetProp (typeDefinition, "Namespace");
159 if (isPublic && !isInterface && !isEnum) {
160 if (typeNamespace == namspace)
161 types.Add ((string) GetProp (typeDefinition, "FullName"));
162 else if (typeNamespace.StartsWith (namspaceDotted)) {
163 int i = typeNamespace.IndexOf ('.', namspaceDotted.Length);
164 if (i != -1)
165 typeNamespace = typeNamespace.Substring (0, i);
166 namespaces.Add (typeNamespace);
171 Type assemblyNameReferenceType = resolver.GetType ().Assembly.GetType ("Mono.Cecil.AssemblyNameReference");
172 MethodInfo resolveMet = resolver.GetType ().GetMethod ("Resolve", new Type[] { assemblyNameReferenceType });
173 foreach (object an in (IEnumerable) GetProp (mainModule, "AssemblyReferences")) {
174 object refAsm = resolveMet.Invoke (resolver, new object[] {an});
175 if (refAsm != null)
176 FindTypes (resolver, visited, types, namespaces, refAsm);
180 static object GetProp (object obj, string name)
182 return obj.GetType ().GetProperty (name).GetValue (obj, null);
185 protected override Mono.Debugging.Client.ObjectValue OnCreateObjectValue ()
187 return Mono.Debugging.Client.ObjectValue.CreateObject (this, new ObjectPath (Name), "<namespace>", namspace, Flags, null);
190 public override string CallToString ()
192 return namspace;