a7f911669f6c19d509d59f6909c74c6806af81b6
[mono.git] / mcs / class / referencesource / System.Workflow.Activities / Common / DelegateTypeInfo.cs
1 // Copyright (c) Microsoft Corporation. All rights reserved. 
2 //  
3 // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
4 // WHETHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
5 // WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE. 
6 // THE ENTIRE RISK OF USE OR RESULTS IN CONNECTION WITH THE USE OF THIS CODE 
7 // AND INFORMATION REMAINS WITH THE USER. 
8 //  
9
10 /*********************************************************************
11  * NOTE: A copy of this file exists at: WF\Common\Shared
12  * The two files must be kept in sync.  Any change made here must also
13  * be made to WF\Common\Shared\DelegateTypeInfo.cs
14 *********************************************************************/
15
16 namespace System.Workflow.Activities.Common
17 {
18     using System;
19     using System.CodeDom;
20     using System.Collections;
21     using System.Globalization;
22     using System.ComponentModel;
23     using System.ComponentModel.Design;
24     using System.Reflection;
25     using System.Diagnostics.CodeAnalysis;
26
27     internal class DelegateTypeInfo
28     {
29         private CodeParameterDeclarationExpression[] parameters;
30         private Type[] parameterTypes;
31         private CodeTypeReference returnType;
32
33         internal CodeParameterDeclarationExpression[] Parameters
34         {
35             get
36             {
37                 return parameters;
38             }
39         }
40
41         internal Type[] ParameterTypes
42         {
43             get
44             {
45                 return parameterTypes;
46             }
47         }
48
49         internal CodeTypeReference ReturnType
50         {
51             get
52             {
53                 return returnType;
54             }
55         }
56
57         internal DelegateTypeInfo(Type delegateClass)
58         {
59             Resolve(delegateClass);
60         }
61
62         [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "EndsWith(\"&\") not a security issue.")]
63         private void Resolve(Type delegateClass)
64         {
65             MethodInfo invokeMethod = delegateClass.GetMethod("Invoke");
66             if (invokeMethod == null)
67                 throw new ArgumentException("delegateClass");
68             Resolve(invokeMethod);
69         }
70
71         [SuppressMessage("Microsoft.Globalization", "CA1307:SpecifyStringComparison", Justification = "EndsWith(\"&\") not a security issue.")]
72         private void Resolve(MethodInfo method)
73         {
74             // Here we build up an array of argument types, separated
75             // by commas.
76             ParameterInfo[] argTypes = method.GetParameters();
77
78             parameters = new CodeParameterDeclarationExpression[argTypes.Length];
79             parameterTypes = new Type[argTypes.Length];
80             for (int index = 0; index < argTypes.Length; index++)
81             {
82                 string paramName = argTypes[index].Name;
83                 Type paramType = argTypes[index].ParameterType;
84
85                 if (paramName == null || paramName.Length == 0)
86                     paramName = "param" + index.ToString(CultureInfo.InvariantCulture);
87
88                 FieldDirection fieldDir = FieldDirection.In;
89
90                 // check for the '&' that means ref (gotta love it!) 
91                 // and we need to strip that & before we continue.  Ouch.
92                 if (paramType.IsByRef)
93                 {
94                     if (paramType.FullName.EndsWith("&"))
95                     {
96                         // strip the & and reload the type without it.
97                         paramType = paramType.Assembly.GetType(paramType.FullName.Substring(0, paramType.FullName.Length - 1), true);
98                     }
99                     fieldDir = FieldDirection.Ref;
100                 }
101                 if (argTypes[index].IsOut)
102                 {
103                     if (argTypes[index].IsIn)
104                         fieldDir = FieldDirection.Ref;
105                     else
106                         fieldDir = FieldDirection.Out;
107                 }
108                 parameters[index] = new CodeParameterDeclarationExpression(new CodeTypeReference(paramType), paramName);
109                 parameters[index].Direction = fieldDir;
110                 parameterTypes[index] = paramType;
111             }
112             this.returnType = new CodeTypeReference(method.ReturnType);
113         }
114         public override bool Equals(object other)
115         {
116             if (other == null)
117                 return false;
118
119             DelegateTypeInfo dtiOther = other as DelegateTypeInfo;
120
121             if (dtiOther == null)
122                 return false;
123
124             if (ReturnType.BaseType != dtiOther.ReturnType.BaseType || Parameters.Length != dtiOther.Parameters.Length)
125                 return false;
126
127             for (int parameter = 0; parameter < Parameters.Length; parameter++)
128             {
129                 CodeParameterDeclarationExpression otherParam = dtiOther.Parameters[parameter];
130                 if (otherParam.Type.BaseType != Parameters[parameter].Type.BaseType)
131                     return false;
132             }
133             return true;
134         }
135         public override int GetHashCode()
136         {
137             return base.GetHashCode();
138         }
139     }
140 }