1 // 2 // FieldDefinition.cs 3 // 4 // Author: 5 // Jb Evain (jbevain@gmail.com) 6 // 7 // Copyright (c) 2008 - 2011 Jb Evain 8 // 9 // Permission is hereby granted, free of charge, to any person obtaining 10 // a copy of this software and associated documentation files (the 11 // "Software"), to deal in the Software without restriction, including 12 // without limitation the rights to use, copy, modify, merge, publish, 13 // distribute, sublicense, and/or sell copies of the Software, and to 14 // permit persons to whom the Software is furnished to do so, subject to 15 // the following conditions: 16 // 17 // The above copyright notice and this permission notice shall be 18 // included in all copies or substantial portions of the Software. 19 // 20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 // 28 29 using Mono.Collections.Generic; 30 31 namespace Mono.Cecil { 32 33 public sealed class FieldDefinition : FieldReference, IMemberDefinition, IConstantProvider, IMarshalInfoProvider { 34 35 ushort attributes; 36 Collection<CustomAttribute> custom_attributes; 37 38 int offset = Mixin.NotResolvedMarker; 39 40 internal int rva = Mixin.NotResolvedMarker; 41 byte [] initial_value; 42 43 object constant = Mixin.NotResolved; 44 45 MarshalInfo marshal_info; 46 ResolveLayout()47 void ResolveLayout () 48 { 49 if (offset != Mixin.NotResolvedMarker) 50 return; 51 52 if (!HasImage) { 53 offset = Mixin.NoDataMarker; 54 return; 55 } 56 57 offset = Module.Read (this, (field, reader) => reader.ReadFieldLayout (field)); 58 } 59 60 public bool HasLayoutInfo { 61 get { 62 if (offset >= 0) 63 return true; 64 65 ResolveLayout (); 66 67 return offset >= 0; 68 } 69 } 70 71 public int Offset { 72 get { 73 if (offset >= 0) 74 return offset; 75 76 ResolveLayout (); 77 78 return offset >= 0 ? offset : -1; 79 } 80 set { offset = value; } 81 } 82 ResolveRVA()83 void ResolveRVA () 84 { 85 if (rva != Mixin.NotResolvedMarker) 86 return; 87 88 if (!HasImage) 89 return; 90 91 rva = Module.Read (this, (field, reader) => reader.ReadFieldRVA (field)); 92 } 93 94 public int RVA { 95 get { 96 if (rva > 0) 97 return rva; 98 99 ResolveRVA (); 100 101 return rva > 0 ? rva : 0; 102 } 103 } 104 105 public byte [] InitialValue { 106 get { 107 if (initial_value != null) 108 return initial_value; 109 110 ResolveRVA (); 111 112 if (initial_value == null) 113 initial_value = Empty<byte>.Array; 114 115 return initial_value; 116 } 117 set { initial_value = value; } 118 } 119 120 public FieldAttributes Attributes { 121 get { return (FieldAttributes) attributes; } 122 set { attributes = (ushort) value; } 123 } 124 125 public bool HasConstant { 126 get { 127 ResolveConstant (); 128 129 return constant != Mixin.NoValue; 130 } 131 set { if (!value) constant = Mixin.NoValue; } 132 } 133 134 public object Constant { 135 get { return HasConstant ? constant : null; } 136 set { constant = value; } 137 } 138 ResolveConstant()139 void ResolveConstant () 140 { 141 if (constant != Mixin.NotResolved) 142 return; 143 144 this.ResolveConstant (ref constant, Module); 145 } 146 147 public bool HasCustomAttributes { 148 get { 149 if (custom_attributes != null) 150 return custom_attributes.Count > 0; 151 152 return this.GetHasCustomAttributes (Module); 153 } 154 } 155 156 public Collection<CustomAttribute> CustomAttributes { 157 get { return custom_attributes ?? (custom_attributes = this.GetCustomAttributes (Module)); } 158 } 159 160 public bool HasMarshalInfo { 161 get { 162 if (marshal_info != null) 163 return true; 164 165 return this.GetHasMarshalInfo (Module); 166 } 167 } 168 169 public MarshalInfo MarshalInfo { 170 get { return marshal_info ?? (marshal_info = this.GetMarshalInfo (Module)); } 171 set { marshal_info = value; } 172 } 173 174 #region FieldAttributes 175 176 public bool IsCompilerControlled { 177 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled); } 178 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.CompilerControlled, value); } 179 } 180 181 public bool IsPrivate { 182 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private); } 183 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Private, value); } 184 } 185 186 public bool IsFamilyAndAssembly { 187 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem); } 188 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamANDAssem, value); } 189 } 190 191 public bool IsAssembly { 192 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly); } 193 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Assembly, value); } 194 } 195 196 public bool IsFamily { 197 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family); } 198 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Family, value); } 199 } 200 201 public bool IsFamilyOrAssembly { 202 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem); } 203 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.FamORAssem, value); } 204 } 205 206 public bool IsPublic { 207 get { return attributes.GetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public); } 208 set { attributes = attributes.SetMaskedAttributes ((ushort) FieldAttributes.FieldAccessMask, (ushort) FieldAttributes.Public, value); } 209 } 210 211 public bool IsStatic { 212 get { return attributes.GetAttributes ((ushort) FieldAttributes.Static); } 213 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Static, value); } 214 } 215 216 public bool IsInitOnly { 217 get { return attributes.GetAttributes ((ushort) FieldAttributes.InitOnly); } 218 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.InitOnly, value); } 219 } 220 221 public bool IsLiteral { 222 get { return attributes.GetAttributes ((ushort) FieldAttributes.Literal); } 223 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.Literal, value); } 224 } 225 226 public bool IsNotSerialized { 227 get { return attributes.GetAttributes ((ushort) FieldAttributes.NotSerialized); } 228 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.NotSerialized, value); } 229 } 230 231 public bool IsSpecialName { 232 get { return attributes.GetAttributes ((ushort) FieldAttributes.SpecialName); } 233 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.SpecialName, value); } 234 } 235 236 public bool IsPInvokeImpl { 237 get { return attributes.GetAttributes ((ushort) FieldAttributes.PInvokeImpl); } 238 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.PInvokeImpl, value); } 239 } 240 241 public bool IsRuntimeSpecialName { 242 get { return attributes.GetAttributes ((ushort) FieldAttributes.RTSpecialName); } 243 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.RTSpecialName, value); } 244 } 245 246 public bool HasDefault { 247 get { return attributes.GetAttributes ((ushort) FieldAttributes.HasDefault); } 248 set { attributes = attributes.SetAttributes ((ushort) FieldAttributes.HasDefault, value); } 249 } 250 251 #endregion 252 253 public override bool IsDefinition { 254 get { return true; } 255 } 256 257 public new TypeDefinition DeclaringType { 258 get { return (TypeDefinition) base.DeclaringType; } 259 set { base.DeclaringType = value; } 260 } 261 FieldDefinition(string name, FieldAttributes attributes, TypeReference fieldType)262 public FieldDefinition (string name, FieldAttributes attributes, TypeReference fieldType) 263 : base (name, fieldType) 264 { 265 this.attributes = (ushort) attributes; 266 } 267 Resolve()268 public override FieldDefinition Resolve () 269 { 270 return this; 271 } 272 } 273 274 static partial class Mixin { 275 276 public const int NotResolvedMarker = -2; 277 public const int NoDataMarker = -1; 278 } 279 } 280