1 using System;
2 using System.Collections.Generic;
3 using System.Text;
4 using System.Reflection;
5 using C = Mono.Cecil;
6 using Mono.Cecil.Metadata;
7 
8 namespace Mono.Debugger.Soft
9 {
10 	public class PropertyInfoMirror : Mirror {
11 
12 		TypeMirror parent;
13 		string name;
14 		PropertyAttributes attrs;
15 		MethodMirror get_method, set_method;
16 		CustomAttributeDataMirror[] cattrs;
17 		C.PropertyDefinition meta;
18 
PropertyInfoMirror(TypeMirror parent, long id, string name, MethodMirror get_method, MethodMirror set_method, PropertyAttributes attrs)19 		public PropertyInfoMirror (TypeMirror parent, long id, string name, MethodMirror get_method, MethodMirror set_method, PropertyAttributes attrs) : base (parent.VirtualMachine, id) {
20 			this.parent = parent;
21 			this.name = name;
22 			this.attrs = attrs;
23 			this.get_method = get_method;
24 			this.set_method = set_method;
25 		}
26 
27 		public TypeMirror DeclaringType {
28 			get {
29 				return parent;
30 			}
31 		}
32 
33 		public string Name {
34 			get {
35 				return name;
36 			}
37 		}
38 
39 		public TypeMirror PropertyType {
40 			get {
41 				if (get_method != null)
42 					return get_method.ReturnType;
43 				else {
44 					ParameterInfoMirror[] parameters = set_method.GetParameters ();
45 
46 					return parameters [parameters.Length - 1].ParameterType;
47 				}
48 			}
49 		}
50 
51 		public PropertyAttributes Attributes {
52 			get {
53 				return attrs;
54 			}
55 		}
56 
57 		public bool IsSpecialName {
58 			get {return (Attributes & PropertyAttributes.SpecialName) != 0;}
59 		}
60 
GetGetMethod()61 		public MethodMirror GetGetMethod ()
62 		{
63 			return GetGetMethod (false);
64 		}
65 
GetGetMethod(bool nonPublic)66 		public MethodMirror GetGetMethod (bool nonPublic)
67 		{
68 			if (get_method != null && (nonPublic || get_method.IsPublic))
69 				return get_method;
70 			else
71 				return null;
72 		}
73 
GetSetMethod()74 		public MethodMirror GetSetMethod ()
75 		{
76 			return GetSetMethod (false);
77 		}
78 
GetSetMethod(bool nonPublic)79 		public MethodMirror GetSetMethod (bool nonPublic)
80 		{
81 			if (set_method != null && (nonPublic || set_method.IsPublic))
82 				return set_method;
83 			else
84 				return null;
85 		}
86 
GetIndexParameters()87 		public ParameterInfoMirror[] GetIndexParameters()
88 		{
89 			if (get_method != null)
90 				return get_method.GetParameters ();
91 			return new ParameterInfoMirror [0];
92 		}
93 
94 		public C.PropertyDefinition Metadata {
95 			get {
96 				if (parent.Metadata == null)
97 					return null;
98 				// FIXME: Speed this up
99 				foreach (var def in parent.Metadata.Properties) {
100 					if (def.Name == Name) {
101 						meta = def;
102 						break;
103 					}
104 				}
105 				if (meta == null)
106 					/* Shouldn't happen */
107 					throw new NotImplementedException ();
108 				return meta;
109 			}
110 		}
111 
GetCustomAttributes(bool inherit)112 		public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
113 			return GetCAttrs (null, inherit);
114 		}
115 
GetCustomAttributes(TypeMirror attributeType, bool inherit)116 		public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
117 			if (attributeType == null)
118 				throw new ArgumentNullException ("attributeType");
119 			return GetCAttrs (attributeType, inherit);
120 		}
121 
GetCAttrs(TypeMirror type, bool inherit)122 		CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
123 			if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes)
124 				cattrs = new CustomAttributeDataMirror [0];
125 
126 			// FIXME: Handle inherit
127 			if (cattrs == null) {
128 				CattrInfo[] info = vm.conn.Type_GetPropertyCustomAttributes (DeclaringType.Id, id, 0, false);
129 				cattrs = CustomAttributeDataMirror.Create (vm, info);
130 			}
131 			var res = new List<CustomAttributeDataMirror> ();
132 			foreach (var attr in cattrs)
133 				if (type == null || attr.Constructor.DeclaringType == type)
134 					res.Add (attr);
135 			return res.ToArray ();
136 		}
137 	}
138 }
139 
140