1 //------------------------------------------------------------------------------ 2 // <copyright file="WebCodeGenerator.cs" company="Microsoft"> 3 // Copyright (c) Microsoft Corporation. All rights reserved. 4 // </copyright> 5 //------------------------------------------------------------------------------ 6 7 namespace System.Web.Services.Description { 8 9 10 using System; 11 using System.Globalization; 12 using System.Collections; 13 using System.IO; 14 using System.CodeDom; 15 using System.CodeDom.Compiler; 16 using System.Diagnostics; 17 using System.Reflection; 18 using System.ComponentModel; 19 using System.Xml.Serialization; 20 using System.Threading; 21 using System.Web.Services.Protocols; 22 23 internal enum CodeFlags { 24 IsPublic = 0x1, 25 IsAbstract = 0x2, 26 IsStruct = 0x4, 27 IsNew = 0x8, 28 IsByRef = 0x10, 29 IsOut = 0x20, 30 IsInterface = 0x40 31 } 32 33 internal class WebCodeGenerator { 34 private static CodeAttributeDeclaration generatedCodeAttribute; WebCodeGenerator()35 private WebCodeGenerator() { } 36 37 internal static CodeAttributeDeclaration GeneratedCodeAttribute { 38 get { 39 if (generatedCodeAttribute == null) { 40 CodeAttributeDeclaration decl = new CodeAttributeDeclaration(typeof(GeneratedCodeAttribute).FullName); 41 42 Assembly a = Assembly.GetEntryAssembly(); 43 if (a == null) { 44 a = Assembly.GetExecutingAssembly(); 45 if (a == null) { 46 a = typeof(WebCodeGenerator).Assembly; 47 } 48 } 49 AssemblyName assemblyName = a.GetName(); 50 decl.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(assemblyName.Name))); 51 string version = GetProductVersion(a); 52 decl.Arguments.Add(new CodeAttributeArgument(new CodePrimitiveExpression(version == null ? assemblyName.Version.ToString() : version))); 53 generatedCodeAttribute = decl; 54 } 55 return generatedCodeAttribute; 56 } 57 } 58 GetProductVersion(Assembly assembly)59 private static string GetProductVersion(Assembly assembly) { 60 object[] attributes = assembly.GetCustomAttributes(true); 61 for ( int i = 0; i < attributes.Length; i++ ) { 62 if (attributes[i] is AssemblyInformationalVersionAttribute) { 63 AssemblyInformationalVersionAttribute version = (AssemblyInformationalVersionAttribute)attributes[i]; 64 return version.InformationalVersion; 65 } 66 } 67 return null; 68 } 69 GetNamespacesForTypes(Type[] types)70 internal static string[] GetNamespacesForTypes(Type[] types) { 71 Hashtable names = new Hashtable(); 72 for (int i = 0; i < types.Length; i++) { 73 string name = types[i].FullName; 74 int dot = name.LastIndexOf('.'); 75 if (dot > 0) 76 names[name.Substring(0, dot)] = types[i]; 77 } 78 string[] ns = new string[names.Keys.Count]; 79 names.Keys.CopyTo(ns, 0); 80 return ns; 81 } 82 AddImports(CodeNamespace codeNamespace, string[] namespaces)83 internal static void AddImports(CodeNamespace codeNamespace, string[] namespaces) { 84 Debug.Assert(codeNamespace != null, "Inalid (null) CodeNamespace"); 85 foreach (string ns in namespaces) 86 codeNamespace.Imports.Add(new CodeNamespaceImport(ns)); 87 } 88 CreatePropertyDeclaration(CodeMemberField field, string name, string typeName)89 static CodeMemberProperty CreatePropertyDeclaration(CodeMemberField field, string name, string typeName) { 90 CodeMemberProperty prop = new CodeMemberProperty(); 91 prop.Type = new CodeTypeReference(typeName); 92 prop.Name = name; 93 //add get 94 CodeMethodReturnStatement ret = new CodeMethodReturnStatement(); 95 ret.Expression = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name); 96 prop.GetStatements.Add(ret); 97 98 CodeExpression left = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name); 99 CodeExpression right = new CodeArgumentReferenceExpression("value"); 100 prop.SetStatements.Add(new CodeAssignStatement(left, right)); 101 return prop; 102 } 103 AddMember(CodeTypeDeclaration codeClass, string typeName, string memberName, CodeExpression initializer, CodeAttributeDeclarationCollection metadata, CodeFlags flags, CodeGenerationOptions options)104 internal static CodeTypeMember AddMember(CodeTypeDeclaration codeClass, string typeName, string memberName, CodeExpression initializer, CodeAttributeDeclarationCollection metadata, CodeFlags flags, CodeGenerationOptions options) { 105 CodeTypeMember member; 106 bool generateProperty = (options & CodeGenerationOptions.GenerateProperties) != 0; 107 string fieldName = generateProperty ? MakeFieldName(memberName) : memberName; 108 109 CodeMemberField field = new CodeMemberField(typeName, fieldName); 110 field.InitExpression = initializer; 111 112 if (generateProperty) { 113 codeClass.Members.Add(field); 114 member = CreatePropertyDeclaration(field, memberName, typeName); 115 } 116 else { 117 member = field; 118 } 119 120 member.CustomAttributes = metadata; 121 if ((flags & CodeFlags.IsPublic) != 0) 122 member.Attributes = (field.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; 123 124 codeClass.Members.Add(member); 125 return member; 126 } 127 FullTypeName(XmlMemberMapping mapping, CodeDomProvider codeProvider)128 internal static string FullTypeName(XmlMemberMapping mapping, CodeDomProvider codeProvider) { 129 return mapping.GenerateTypeName(codeProvider); 130 } 131 MakeFieldName(string name)132 static string MakeFieldName(string name) { 133 return CodeIdentifier.MakeCamel(name) + "Field"; 134 } 135 AddConstructor(CodeTypeDeclaration codeClass, string[] parameterTypeNames, string[] parameterNames, CodeAttributeDeclarationCollection metadata, CodeFlags flags)136 internal static CodeConstructor AddConstructor(CodeTypeDeclaration codeClass, string[] parameterTypeNames, string[] parameterNames, CodeAttributeDeclarationCollection metadata, CodeFlags flags) { 137 CodeConstructor ctor = new CodeConstructor(); 138 139 if ((flags & CodeFlags.IsPublic) != 0) 140 ctor.Attributes = (ctor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; 141 if ((flags & CodeFlags.IsAbstract) != 0) 142 ctor.Attributes |= MemberAttributes.Abstract; 143 144 ctor.CustomAttributes = metadata; 145 146 Debug.Assert(parameterTypeNames.Length == parameterNames.Length, "invalid set of parameters"); 147 for (int i = 0; i < parameterTypeNames.Length; i++) { 148 CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(parameterTypeNames[i], parameterNames[i]); 149 ctor.Parameters.Add(param); 150 } 151 codeClass.Members.Add(ctor); 152 return ctor; 153 } 154 AddMethod(CodeTypeDeclaration codeClass, string methodName, CodeFlags[] parameterFlags, string[] parameterTypeNames, string[] parameterNames, string returnTypeName, CodeAttributeDeclarationCollection metadata, CodeFlags flags)155 internal static CodeMemberMethod AddMethod(CodeTypeDeclaration codeClass, string methodName, 156 CodeFlags[] parameterFlags, string[] parameterTypeNames, string[] parameterNames, 157 string returnTypeName, CodeAttributeDeclarationCollection metadata, CodeFlags flags) { 158 159 return AddMethod(codeClass, methodName, parameterFlags, 160 parameterTypeNames, parameterNames, new CodeAttributeDeclarationCollection[0], 161 returnTypeName, metadata, flags); 162 } 163 AddMethod(CodeTypeDeclaration codeClass, string methodName, CodeFlags[] parameterFlags, string[] parameterTypeNames, string[] parameterNames, CodeAttributeDeclarationCollection[] parameterAttributes, string returnTypeName, CodeAttributeDeclarationCollection metadata, CodeFlags flags)164 internal static CodeMemberMethod AddMethod(CodeTypeDeclaration codeClass, string methodName, 165 CodeFlags[] parameterFlags, string[] parameterTypeNames, string[] parameterNames, 166 CodeAttributeDeclarationCollection[] parameterAttributes, string returnTypeName, CodeAttributeDeclarationCollection metadata, CodeFlags flags) { 167 168 CodeMemberMethod method = new CodeMemberMethod(); 169 method.Name = methodName; 170 method.ReturnType = new CodeTypeReference(returnTypeName); 171 method.CustomAttributes = metadata; 172 173 if ((flags & CodeFlags.IsPublic) != 0) 174 method.Attributes = (method.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; 175 if ((flags & CodeFlags.IsAbstract) != 0) 176 method.Attributes = (method.Attributes & ~MemberAttributes.ScopeMask) | MemberAttributes.Abstract; 177 178 if ((flags & CodeFlags.IsNew) != 0) 179 method.Attributes = (method.Attributes & ~MemberAttributes.VTableMask) | MemberAttributes.New; 180 181 Debug.Assert(parameterFlags.Length == parameterTypeNames.Length && parameterTypeNames.Length == parameterNames.Length, "invalid set of parameters"); 182 for (int i = 0; i < parameterNames.Length; i++) { 183 CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(parameterTypeNames[i], parameterNames[i]); 184 185 if ((parameterFlags[i] & CodeFlags.IsByRef) != 0) 186 param.Direction = FieldDirection.Ref; 187 else if ((parameterFlags[i] & CodeFlags.IsOut) != 0) 188 param.Direction = FieldDirection.Out; 189 190 if (i < parameterAttributes.Length) { 191 param.CustomAttributes = parameterAttributes[i]; 192 } 193 method.Parameters.Add(param); 194 } 195 codeClass.Members.Add(method); 196 return method; 197 } 198 AddClass(CodeNamespace codeNamespace, string className, string baseClassName, string[] implementedInterfaceNames, CodeAttributeDeclarationCollection metadata, CodeFlags flags, bool isPartial)199 internal static CodeTypeDeclaration AddClass(CodeNamespace codeNamespace, string className, string baseClassName, string[] implementedInterfaceNames, CodeAttributeDeclarationCollection metadata, CodeFlags flags, bool isPartial) { 200 CodeTypeDeclaration codeClass = CreateClass(className, baseClassName, implementedInterfaceNames, metadata, flags, isPartial); 201 codeNamespace.Types.Add(codeClass); 202 return codeClass; 203 } 204 CreateClass(string className, string baseClassName, string[] implementedInterfaceNames, CodeAttributeDeclarationCollection metadata, CodeFlags flags, bool isPartial)205 internal static CodeTypeDeclaration CreateClass(string className, string baseClassName, string[] implementedInterfaceNames, CodeAttributeDeclarationCollection metadata, CodeFlags flags, bool isPartial) { 206 CodeTypeDeclaration codeClass = new CodeTypeDeclaration(className); 207 208 if (baseClassName != null && baseClassName.Length > 0) 209 codeClass.BaseTypes.Add(baseClassName); 210 foreach (string interfaceName in implementedInterfaceNames) 211 codeClass.BaseTypes.Add(interfaceName); 212 codeClass.IsStruct = (flags & CodeFlags.IsStruct) != 0; 213 if ((flags & CodeFlags.IsPublic) != 0) 214 codeClass.TypeAttributes |= TypeAttributes.Public; 215 else 216 codeClass.TypeAttributes &= ~TypeAttributes.Public; 217 if ((flags & CodeFlags.IsAbstract) != 0) 218 codeClass.TypeAttributes |= TypeAttributes.Abstract; 219 else 220 codeClass.TypeAttributes &= ~TypeAttributes.Abstract; 221 222 if ((flags & CodeFlags.IsInterface) != 0) 223 codeClass.IsInterface = true; 224 else 225 codeClass.IsPartial = isPartial; 226 227 codeClass.CustomAttributes = metadata; 228 codeClass.CustomAttributes.Add(GeneratedCodeAttribute); 229 return codeClass; 230 } 231 AddCustomAttribute(CodeAttributeDeclarationCollection metadata, Type type, CodeAttributeArgument[] arguments)232 internal static CodeAttributeDeclarationCollection AddCustomAttribute(CodeAttributeDeclarationCollection metadata, Type type, CodeAttributeArgument[] arguments) { 233 if (metadata == null) metadata = new CodeAttributeDeclarationCollection(); 234 CodeAttributeDeclaration attribute = new CodeAttributeDeclaration(type.FullName, arguments); 235 metadata.Add(attribute); 236 return metadata; 237 } 238 AddCustomAttribute(CodeAttributeDeclarationCollection metadata, Type type, CodeExpression[] arguments)239 internal static CodeAttributeDeclarationCollection AddCustomAttribute(CodeAttributeDeclarationCollection metadata, Type type, CodeExpression[] arguments) { 240 return AddCustomAttribute(metadata, type, arguments, new string[0], new CodeExpression[0]); 241 } 242 AddCustomAttribute(CodeAttributeDeclarationCollection metadata, Type type, CodeExpression[] parameters, string[] propNames, CodeExpression[] propValues)243 internal static CodeAttributeDeclarationCollection AddCustomAttribute(CodeAttributeDeclarationCollection metadata, Type type, CodeExpression[] parameters, string[] propNames, CodeExpression[] propValues) { 244 Debug.Assert(propNames.Length == propValues.Length, "propNames.Length != propValues.Length"); 245 int count = (parameters == null ? 0 : parameters.Length) + (propNames == null ? 0 : propNames.Length); 246 CodeAttributeArgument[] arguments = new CodeAttributeArgument[count]; 247 248 for (int i = 0; i < parameters.Length; i++) 249 arguments[i] = new CodeAttributeArgument(null, parameters[i]); 250 251 for (int i = 0; i < propNames.Length; i++) 252 arguments[parameters.Length + i] = new CodeAttributeArgument(propNames[i], propValues[i]); 253 254 return AddCustomAttribute(metadata, type, arguments); 255 } 256 257 // public event xxxCompletedEventHandler xxxCompleted; AddEvent(CodeTypeMemberCollection members, string handlerType, string handlerName)258 internal static void AddEvent(CodeTypeMemberCollection members, string handlerType, string handlerName) { 259 CodeMemberEvent eventCompleted = new CodeMemberEvent(); 260 eventCompleted.Type = new CodeTypeReference(handlerType); 261 eventCompleted.Name = handlerName; 262 eventCompleted.Attributes = (eventCompleted.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; 263 eventCompleted.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); 264 members.Add(eventCompleted); 265 } 266 267 // public delegate void xxxCompletedEventHandler(object sender, System.ComponentModel.AsyncCompletedEventArgs args); AddDelegate(CodeTypeDeclarationCollection codeClasses, string handlerType, string handlerArgs)268 internal static void AddDelegate(CodeTypeDeclarationCollection codeClasses, string handlerType, string handlerArgs) { 269 CodeTypeDelegate handler = new CodeTypeDelegate(handlerType); 270 handler.CustomAttributes.Add(GeneratedCodeAttribute); 271 handler.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "sender")); 272 handler.Parameters.Add(new CodeParameterDeclarationExpression(handlerArgs, "e")); 273 handler.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); 274 codeClasses.Add(handler); 275 } 276 277 // private SendOrPostCallback xxxOperationCompleted; AddCallbackDeclaration(CodeTypeMemberCollection members, string callbackMember)278 internal static void AddCallbackDeclaration(CodeTypeMemberCollection members, string callbackMember) { 279 CodeMemberField callback = new CodeMemberField(); 280 callback.Type = new CodeTypeReference(typeof(SendOrPostCallback)); 281 callback.Name = callbackMember; 282 members.Add(callback); 283 } 284 285 // private void On_xxx_OperationCompleted(object arg) {..} AddCallbackImplementation(CodeTypeDeclaration codeClass, string callbackName, string handlerName, string handlerArgs, bool methodHasOutParameters)286 internal static void AddCallbackImplementation(CodeTypeDeclaration codeClass, string callbackName, string handlerName, string handlerArgs, bool methodHasOutParameters) { 287 CodeMemberMethod asyncCompleted = WebCodeGenerator.AddMethod(codeClass, callbackName, 288 new CodeFlags[1] { 0 }, new string[] { typeof(object).FullName }, new string[] { "arg" }, 289 typeof(void).FullName, null, 0); 290 291 CodeEventReferenceExpression member = new CodeEventReferenceExpression(new CodeThisReferenceExpression(), handlerName); 292 CodeBinaryOperatorExpression checkIfNull = new CodeBinaryOperatorExpression(member, CodeBinaryOperatorType.IdentityInequality, new CodePrimitiveExpression(null)); 293 294 CodeStatement[] trueStatements = new CodeStatement[2]; 295 trueStatements[0] = new CodeVariableDeclarationStatement(typeof(InvokeCompletedEventArgs), "invokeArgs", new CodeCastExpression(typeof(InvokeCompletedEventArgs), new CodeArgumentReferenceExpression("arg"))); 296 CodeVariableReferenceExpression invokeArgs = new CodeVariableReferenceExpression("invokeArgs"); 297 CodeObjectCreateExpression create = new CodeObjectCreateExpression(); 298 299 if (methodHasOutParameters) { 300 create.CreateType = new CodeTypeReference(handlerArgs); 301 create.Parameters.Add(new CodePropertyReferenceExpression(invokeArgs, "Results")); 302 } 303 else { 304 create.CreateType = new CodeTypeReference(typeof(AsyncCompletedEventArgs)); 305 } 306 create.Parameters.Add(new CodePropertyReferenceExpression(invokeArgs, "Error")); 307 create.Parameters.Add(new CodePropertyReferenceExpression(invokeArgs, "Cancelled")); 308 create.Parameters.Add(new CodePropertyReferenceExpression(invokeArgs, "UserState")); 309 trueStatements[1] = new CodeExpressionStatement(new CodeDelegateInvokeExpression(new CodeEventReferenceExpression(new CodeThisReferenceExpression(), handlerName), new CodeExpression[] { new CodeThisReferenceExpression(), create })); 310 311 asyncCompleted.Statements.Add(new CodeConditionStatement(checkIfNull, trueStatements, new CodeStatement[0])); 312 } 313 AddAsyncMethod(CodeTypeDeclaration codeClass, string methodName, string[] parameterTypeNames, string[] parameterNames, string callbackMember, string callbackName, string userState)314 internal static CodeMemberMethod AddAsyncMethod(CodeTypeDeclaration codeClass, string methodName, 315 string[] parameterTypeNames, string[] parameterNames, string callbackMember, string callbackName, string userState) { 316 317 CodeMemberMethod asyncCodeMethod = WebCodeGenerator.AddMethod(codeClass, methodName, 318 new CodeFlags[parameterNames.Length], parameterTypeNames, parameterNames, typeof(void).FullName, null, CodeFlags.IsPublic); 319 320 asyncCodeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); 321 CodeMethodInvokeExpression invoke = new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), methodName); 322 323 for (int i = 0; i < parameterNames.Length; i++) { 324 invoke.Parameters.Add(new CodeArgumentReferenceExpression(parameterNames[i])); 325 } 326 invoke.Parameters.Add(new CodePrimitiveExpression(null)); 327 asyncCodeMethod.Statements.Add(invoke); 328 329 asyncCodeMethod = WebCodeGenerator.AddMethod(codeClass, methodName, 330 new CodeFlags[parameterNames.Length], parameterTypeNames, parameterNames, typeof(void).FullName, null, CodeFlags.IsPublic); 331 332 asyncCodeMethod.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); 333 334 asyncCodeMethod.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), userState)); 335 336 CodeFieldReferenceExpression member = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), callbackMember); 337 CodeBinaryOperatorExpression checkIfNull = new CodeBinaryOperatorExpression(member, CodeBinaryOperatorType.IdentityEquality, new CodePrimitiveExpression(null)); 338 CodeDelegateCreateExpression createDelegate = new CodeDelegateCreateExpression(); 339 createDelegate.DelegateType = new CodeTypeReference(typeof(SendOrPostCallback)); 340 createDelegate.TargetObject = new CodeThisReferenceExpression(); 341 createDelegate.MethodName = callbackName; 342 343 CodeStatement[] trueStatements = new CodeStatement[] { new CodeAssignStatement(member, createDelegate) }; 344 asyncCodeMethod.Statements.Add(new CodeConditionStatement(checkIfNull, trueStatements, new CodeStatement[0])); 345 346 return asyncCodeMethod; 347 } 348 CreateArgsClass(string name, string[] paramTypes, string[] paramNames, bool isPartial)349 internal static CodeTypeDeclaration CreateArgsClass(string name, string[] paramTypes, string[] paramNames, bool isPartial) { 350 CodeTypeDeclaration codeClass = new CodeTypeDeclaration(name); 351 codeClass.CustomAttributes.Add(GeneratedCodeAttribute); 352 353 // Add [DebuggerStepThrough] 354 codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DebuggerStepThroughAttribute).FullName)); 355 // Add [DesignerCategory("code")] 356 codeClass.CustomAttributes.Add(new CodeAttributeDeclaration(typeof(DesignerCategoryAttribute).FullName, new CodeAttributeArgument[] { new CodeAttributeArgument(new CodePrimitiveExpression("code")) })); 357 358 codeClass.IsPartial = isPartial; 359 codeClass.BaseTypes.Add(new CodeTypeReference(typeof(AsyncCompletedEventArgs))); 360 361 CodeIdentifiers identifiers = new CodeIdentifiers(); 362 identifiers.AddUnique("Error", "Error"); 363 identifiers.AddUnique("Cancelled", "Cancelled"); 364 identifiers.AddUnique("UserState", "UserState"); 365 366 for (int i = 0; i < paramNames.Length; i++) { 367 if (paramNames[i] != null) { 368 identifiers.AddUnique(paramNames[i], paramNames[i]); 369 } 370 } 371 string results = identifiers.AddUnique("results", "results"); 372 CodeMemberField data = new CodeMemberField(typeof(object[]), results); 373 codeClass.Members.Add(data); 374 375 CodeConstructor ctor = new CodeConstructor(); 376 ctor.Attributes = (ctor.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Assembly; 377 378 CodeParameterDeclarationExpression param = new CodeParameterDeclarationExpression(typeof(object[]), results); 379 ctor.Parameters.Add(param); 380 ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(Exception), "exception")); 381 ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(bool), "cancelled")); 382 ctor.Parameters.Add(new CodeParameterDeclarationExpression(typeof(object), "userState")); 383 384 ctor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("exception")); 385 ctor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("cancelled")); 386 ctor.BaseConstructorArgs.Add(new CodeArgumentReferenceExpression("userState")); 387 388 ctor.Statements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), data.Name), new CodeArgumentReferenceExpression(results))); 389 390 codeClass.Members.Add(ctor); 391 392 int index = 0; 393 for (int i = 0; i < paramNames.Length; i++) { 394 if (paramNames[i] != null) { 395 codeClass.Members.Add(CreatePropertyDeclaration(data, paramNames[i], paramTypes[i], index++)); 396 } 397 } 398 codeClass.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); 399 return codeClass; 400 } 401 CreatePropertyDeclaration(CodeMemberField field, string name, string typeName, int index)402 static CodeMemberProperty CreatePropertyDeclaration(CodeMemberField field, string name, string typeName, int index) { 403 CodeMemberProperty prop = new CodeMemberProperty(); 404 prop.Type = new CodeTypeReference(typeName); 405 prop.Name = name; 406 prop.Attributes = (prop.Attributes & ~MemberAttributes.AccessMask) | MemberAttributes.Public; 407 //add get 408 prop.GetStatements.Add(new CodeMethodInvokeExpression(new CodeThisReferenceExpression(), "RaiseExceptionIfNecessary", new CodeExpression[0])); 409 CodeArrayIndexerExpression valueRef = new CodeArrayIndexerExpression(); 410 valueRef.TargetObject = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), field.Name); 411 valueRef.Indices.Add(new CodePrimitiveExpression(index)); 412 413 CodeMethodReturnStatement ret = new CodeMethodReturnStatement(); 414 ret.Expression = new CodeCastExpression(typeName, valueRef); 415 prop.GetStatements.Add(ret); 416 417 prop.Comments.Add(new CodeCommentStatement(Res.GetString(Res.CodeRemarks), true)); 418 return prop; 419 } 420 } 421 } 422