5
// Mike Krüger <mkrueger@novell.com>
7
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
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:
17
// The above copyright notice and this permission notice shall be
18
// included in all copies or substantial portions of the Software.
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.
32
namespace MonoDevelop.Projects.Dom
34
public class DomCecilMethod : MonoDevelop.Projects.Dom.DomMethod
36
MethodDefinition methodDefinition;
38
public MethodDefinition MethodDefinition {
40
return methodDefinition;
45
// Check if 'type' has some decorations applied to it
46
if (type is Mono.Cecil.TypeSpecification) {
47
// Go through all levels of 'indirection', 'array dimensions'
48
// and 'generic types' - in the end, we should get the actual
49
// type of the ReturnType (but all data about its array
50
// dimensions, levels of indirection and even its generic
51
// parameters is correctly stored within ArrayCount and
52
// ArrayDimensions, PointerNestingLevel and GenericArguments
54
if (type is ArrayType) {
55
// This return type is obviously an array - add the rank
56
ArrayType at = (ArrayType) type;
58
arrays = new Stack<int>();
60
type = at.ElementType;
61
} else else if (type is Mono.Cecil.ReferenceType) {
62
Mono.Cecil.ReferenceType rt = (Mono.Cecil.ReferenceType) type;
64
type = rt.ElementType;
65
} else if (type is PointerType) {
66
// The type is a pointer
67
PointerType pt = (PointerType) type;
68
++pointerNestingLevel;
69
type = pt.ElementType;
72
// TODO: Check if we loose some relevant info here
73
type = ((TypeSpecification)type).ElementType;
75
public static DomReturnType GetReturnType (TypeReference typeReference)
77
if (typeReference == null)
78
return new DomReturnType (DomReturnType.Void.ToInvariantString ());
80
if (typeReference is Mono.Cecil.GenericInstanceType) {
81
Mono.Cecil.GenericInstanceType genType = (Mono.Cecil.GenericInstanceType)typeReference;
82
DomReturnType result = GetReturnType (genType.ElementType);
84
foreach (TypeReference typeRef in genType.GenericArguments) {
85
DomReturnType param = GetReturnType (typeRef);
87
foreach (IReturnTypePart part in result.Parts) {
88
if (part.Tag is TypeDefinition) {
89
TypeDefinition typeDef = (TypeDefinition)part.Tag;
90
foreach (TypeReference typeParam in typeDef.GenericParameters) {
91
if (typeParam.Name == param.Name) {
92
part.AddTypeParameter (param);
98
result.AddTypeParameter (param);
104
if (typeReference is Mono.Cecil.ArrayType) {
105
Mono.Cecil.ArrayType arrType = (Mono.Cecil.ArrayType)typeReference;
106
DomReturnType result = GetReturnType (arrType.ElementType);
107
result.ArrayDimensions++;
108
result.SetDimension (result.ArrayDimensions - 1, arrType.Rank - 1);
112
if (typeReference is Mono.Cecil.PointerType) {
113
Mono.Cecil.PointerType ptrType = (Mono.Cecil.PointerType)typeReference;
114
DomReturnType result = GetReturnType (ptrType.ElementType);
115
if (result.ArrayDimensions > 0)
116
result.ArrayPointerNestingLevel++;
118
result.PointerNestingLevel++;
121
if (typeReference is Mono.Cecil.ReferenceType)
122
return GetReturnType (((Mono.Cecil.ReferenceType)typeReference).ElementType);
124
if (typeReference is Mono.Cecil.TypeDefinition) {
125
Mono.Cecil.TypeDefinition typeDefinition = (Mono.Cecil.TypeDefinition)typeReference;
126
DomReturnType result;
127
if (typeDefinition.DeclaringType != null) {
128
result = GetReturnType (typeDefinition.DeclaringType);
129
result.Parts.Add (new ReturnTypePart (typeDefinition.Name));
130
result.Tag = typeDefinition;
132
result = new DomReturnType (typeDefinition.Name);
133
result.Namespace = typeDefinition.Namespace;
134
result.Tag = typeDefinition;
139
return new DomReturnType (DomCecilType.RemoveGenericParamSuffix (typeReference.FullName));
142
public static IReturnType GetReturnType (MethodReference methodReference)
144
if (methodReference == null)
145
return DomReturnType.Void;
146
return DomReturnType.GetSharedReturnType (DomCecilType.RemoveGenericParamSuffix (methodReference.DeclaringType.FullName));
149
public static void AddAttributes (AbstractMember member, CustomAttributeCollection attributes)
151
foreach (CustomAttribute customAttribute in attributes) {
152
member.Add (new DomCecilAttribute (customAttribute));
156
public DomCecilMethod (MethodDefinition methodDefinition)
158
this.methodDefinition = methodDefinition;
159
this.name = methodDefinition.Name;
160
if (methodDefinition.Name == ".ctor") {
161
MethodModifier |= MethodModifier.IsConstructor;
164
foreach (GenericParameter param in methodDefinition.GenericParameters) {
165
TypeParameter tp = new TypeParameter (param.FullName);
166
tp.Variance = (TypeParameterVariance)(((uint)param.Attributes) & 3);
167
foreach (TypeReference tr in param.Constraints)
168
tp.AddConstraint (DomCecilMethod.GetReturnType (tr));
169
AddTypeParameter (tp);
172
AddAttributes (this, methodDefinition.CustomAttributes);
173
base.Modifiers = DomCecilType.GetModifiers (methodDefinition);
174
base.ReturnType = DomCecilMethod.GetReturnType (methodDefinition.ReturnType.ReturnType);
175
foreach (ParameterDefinition paramDef in methodDefinition.Parameters) {
176
Add (new DomCecilParameter (paramDef));
180
foreach (IAttribute attr in this.Attributes) {
181
if (attr.Name == "System.Runtime.CompilerServices.ExtensionAttribute") {
182
MethodModifier |= MethodModifier.IsExtension;
188
foreach (MethodReference overrideRef in methodDefinition.Overrides) {
189
if (overrideRef.Name == this.name && IsPublic)
191
AddExplicitInterface (GetReturnType (overrideRef.DeclaringType));