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