~ubuntu-branches/ubuntu/trusty/monodevelop/trusty-proposed

« back to all changes in this revision

Viewing changes to contrib/ICSharpCode.NRefactory.CSharp/TypeSystem/TypeSystemConvertVisitor.cs

  • Committer: Package Import Robot
  • Author(s): Jo Shields
  • Date: 2013-05-12 09:46:03 UTC
  • mto: This revision was merged to the branch mainline in revision 29.
  • Revision ID: package-import@ubuntu.com-20130512094603-mad323bzcxvmcam0
Tags: upstream-4.0.5+dfsg
ImportĀ upstreamĀ versionĀ 4.0.5+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team
2
 
// 
3
 
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
4
 
// software and associated documentation files (the "Software"), to deal in the Software
5
 
// without restriction, including without limitation the rights to use, copy, modify, merge,
6
 
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
7
 
// to whom the Software is furnished to do so, subject to the following conditions:
8
 
// 
9
 
// The above copyright notice and this permission notice shall be included in all copies or
10
 
// substantial portions of the Software.
11
 
// 
12
 
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
13
 
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14
 
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
15
 
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
16
 
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
17
 
// DEALINGS IN THE SOFTWARE.
18
 
 
19
 
using System;
20
 
using System.Collections.Generic;
21
 
using System.Diagnostics;
22
 
using System.IO;
23
 
using System.Linq;
24
 
using System.Text;
25
 
using ICSharpCode.NRefactory.CSharp.Analysis;
26
 
using ICSharpCode.NRefactory.CSharp.Resolver;
27
 
using ICSharpCode.NRefactory.CSharp.TypeSystem;
28
 
using ICSharpCode.NRefactory.CSharp.TypeSystem.ConstantValues;
29
 
using ICSharpCode.NRefactory.TypeSystem;
30
 
using ICSharpCode.NRefactory.TypeSystem.Implementation;
31
 
using ICSharpCode.NRefactory.Utils;
32
 
 
33
 
namespace ICSharpCode.NRefactory.CSharp.TypeSystem
34
 
{
35
 
        /// <summary>
36
 
        /// Produces type and member definitions from the DOM.
37
 
        /// </summary>
38
 
        public class TypeSystemConvertVisitor : DepthFirstAstVisitor<IUnresolvedEntity>
39
 
        {
40
 
                readonly CSharpParsedFile parsedFile;
41
 
                UsingScope usingScope;
42
 
                CSharpUnresolvedTypeDefinition currentTypeDefinition;
43
 
                DefaultUnresolvedMethod currentMethod;
44
 
                
45
 
                IInterningProvider interningProvider = new SimpleInterningProvider();
46
 
                
47
 
                /// <summary>
48
 
                /// Gets/Sets the interning provider to use.
49
 
                /// The default value is a new <see cref="SimpleInterningProvider"/> instance.
50
 
                /// </summary>
51
 
                public IInterningProvider InterningProvider {
52
 
                        get { return interningProvider; }
53
 
                        set { interningProvider = value; }
54
 
                }
55
 
                
56
 
                /// <summary>
57
 
                /// Gets/Sets whether to ignore XML documentation.
58
 
                /// The default value is false.
59
 
                /// </summary>
60
 
                public bool SkipXmlDocumentation { get; set; }
61
 
                
62
 
                /// <summary>
63
 
                /// Creates a new TypeSystemConvertVisitor.
64
 
                /// </summary>
65
 
                /// <param name="fileName">The file name (used for DomRegions).</param>
66
 
                public TypeSystemConvertVisitor(string fileName)
67
 
                {
68
 
                        if (fileName == null)
69
 
                                throw new ArgumentNullException("fileName");
70
 
                        this.parsedFile = new CSharpParsedFile(fileName);
71
 
                        this.usingScope = parsedFile.RootUsingScope;
72
 
                }
73
 
                
74
 
                /// <summary>
75
 
                /// Creates a new TypeSystemConvertVisitor and initializes it with a given context.
76
 
                /// </summary>
77
 
                /// <param name="parsedFile">The parsed file to which members should be added.</param>
78
 
                /// <param name="currentUsingScope">The current using scope.</param>
79
 
                /// <param name="currentTypeDefinition">The current type definition.</param>
80
 
                public TypeSystemConvertVisitor(CSharpParsedFile parsedFile, UsingScope currentUsingScope = null, CSharpUnresolvedTypeDefinition currentTypeDefinition = null)
81
 
                {
82
 
                        if (parsedFile == null)
83
 
                                throw new ArgumentNullException("parsedFile");
84
 
                        this.parsedFile = parsedFile;
85
 
                        this.usingScope = currentUsingScope ?? parsedFile.RootUsingScope;
86
 
                        this.currentTypeDefinition = currentTypeDefinition;
87
 
                }
88
 
                
89
 
                public CSharpParsedFile ParsedFile {
90
 
                        get { return parsedFile; }
91
 
                }
92
 
                
93
 
                DomRegion MakeRegion(TextLocation start, TextLocation end)
94
 
                {
95
 
                        return new DomRegion(parsedFile.FileName, start.Line, start.Column, end.Line, end.Column);
96
 
                }
97
 
                
98
 
                DomRegion MakeRegion(AstNode node)
99
 
                {
100
 
                        if (node == null || node.IsNull)
101
 
                                return DomRegion.Empty;
102
 
                        else
103
 
                                return MakeRegion(node.StartLocation, node.EndLocation);
104
 
                }
105
 
                
106
 
                DomRegion MakeBraceRegion(AstNode node)
107
 
                {
108
 
                        if (node == null || node.IsNull)
109
 
                                return DomRegion.Empty;
110
 
                        else
111
 
                                return MakeRegion(node.GetChildByRole(Roles.LBrace).StartLocation,
112
 
                                                  node.GetChildByRole(Roles.RBrace).EndLocation);
113
 
                }
114
 
                
115
 
                #region Compilation Unit
116
 
                public override IUnresolvedEntity VisitCompilationUnit (CompilationUnit unit)
117
 
                {
118
 
                        parsedFile.Errors = unit.Errors;
119
 
                        return base.VisitCompilationUnit (unit);
120
 
                }
121
 
                #endregion
122
 
                
123
 
                #region Using Declarations
124
 
                public override IUnresolvedEntity VisitExternAliasDeclaration(ExternAliasDeclaration externAliasDeclaration)
125
 
                {
126
 
                        usingScope.ExternAliases.Add(externAliasDeclaration.Name);
127
 
                        return null;
128
 
                }
129
 
                
130
 
                public override IUnresolvedEntity VisitUsingDeclaration(UsingDeclaration usingDeclaration)
131
 
                {
132
 
                        TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
133
 
                        if (u != null) {
134
 
                                if (interningProvider != null)
135
 
                                        u = interningProvider.Intern(u);
136
 
                                usingScope.Usings.Add(u);
137
 
                        }
138
 
                        return null;
139
 
                }
140
 
                
141
 
                public override IUnresolvedEntity VisitUsingAliasDeclaration(UsingAliasDeclaration usingDeclaration)
142
 
                {
143
 
                        TypeOrNamespaceReference u = usingDeclaration.Import.ToTypeReference(NameLookupMode.TypeInUsingDeclaration) as TypeOrNamespaceReference;
144
 
                        if (u != null) {
145
 
                                if (interningProvider != null)
146
 
                                        u = interningProvider.Intern(u);
147
 
                                usingScope.UsingAliases.Add(new KeyValuePair<string, TypeOrNamespaceReference>(usingDeclaration.Alias, u));
148
 
                        }
149
 
                        return null;
150
 
                }
151
 
                #endregion
152
 
                
153
 
                #region Namespace Declaration
154
 
                public override IUnresolvedEntity VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration)
155
 
                {
156
 
                        DomRegion region = MakeRegion(namespaceDeclaration);
157
 
                        UsingScope previousUsingScope = usingScope;
158
 
                        foreach (Identifier ident in namespaceDeclaration.Identifiers) {
159
 
                                usingScope = new UsingScope(usingScope, ident.Name);
160
 
                                usingScope.Region = region;
161
 
                        }
162
 
                        base.VisitNamespaceDeclaration(namespaceDeclaration);
163
 
                        parsedFile.UsingScopes.Add(usingScope); // add after visiting children so that nested scopes come first
164
 
                        usingScope = previousUsingScope;
165
 
                        return null;
166
 
                }
167
 
                #endregion
168
 
                
169
 
                #region Type Definitions
170
 
                CSharpUnresolvedTypeDefinition CreateTypeDefinition(string name)
171
 
                {
172
 
                        CSharpUnresolvedTypeDefinition newType;
173
 
                        if (currentTypeDefinition != null) {
174
 
                                newType = new CSharpUnresolvedTypeDefinition(currentTypeDefinition, name);
175
 
                                foreach (var typeParameter in currentTypeDefinition.TypeParameters)
176
 
                                        newType.TypeParameters.Add(typeParameter);
177
 
                                currentTypeDefinition.NestedTypes.Add(newType);
178
 
                        } else {
179
 
                                newType = new CSharpUnresolvedTypeDefinition(usingScope, name);
180
 
                                parsedFile.TopLevelTypeDefinitions.Add(newType);
181
 
                        }
182
 
                        newType.ParsedFile = parsedFile;
183
 
                        newType.HasExtensionMethods = false; // gets set to true when an extension method is added
184
 
                        return newType;
185
 
                }
186
 
                
187
 
                public override IUnresolvedEntity VisitTypeDeclaration(TypeDeclaration typeDeclaration)
188
 
                {
189
 
                        var td = currentTypeDefinition = CreateTypeDefinition(typeDeclaration.Name);
190
 
                        td.Region = MakeRegion(typeDeclaration);
191
 
                        td.BodyRegion = MakeBraceRegion(typeDeclaration);
192
 
                        AddXmlDocumentation(td, typeDeclaration);
193
 
                        
194
 
                        ApplyModifiers(td, typeDeclaration.Modifiers);
195
 
                        switch (typeDeclaration.ClassType) {
196
 
                                case ClassType.Enum:
197
 
                                        td.Kind = TypeKind.Enum;
198
 
                                        break;
199
 
                                case ClassType.Interface:
200
 
                                        td.Kind = TypeKind.Interface;
201
 
                                        td.IsAbstract = true; // interfaces are implicitly abstract
202
 
                                        break;
203
 
                                case ClassType.Struct:
204
 
                                        td.Kind = TypeKind.Struct;
205
 
                                        td.IsSealed = true; // enums/structs are implicitly sealed
206
 
                                        break;
207
 
                        }
208
 
                        
209
 
                        ConvertAttributes(td.Attributes, typeDeclaration.Attributes);
210
 
                        
211
 
                        ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints, EntityType.TypeDefinition);
212
 
                        
213
 
                        foreach (AstType baseType in typeDeclaration.BaseTypes) {
214
 
                                td.BaseTypes.Add(baseType.ToTypeReference(NameLookupMode.BaseTypeReference));
215
 
                        }
216
 
                        
217
 
                        foreach (EntityDeclaration member in typeDeclaration.Members) {
218
 
                                member.AcceptVisitor(this);
219
 
                        }
220
 
                        
221
 
                        currentTypeDefinition = (CSharpUnresolvedTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
222
 
                        if (interningProvider != null) {
223
 
                                td.ApplyInterningProvider(interningProvider);
224
 
                        }
225
 
                        return td;
226
 
                }
227
 
                
228
 
                public override IUnresolvedEntity VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration)
229
 
                {
230
 
                        var td = currentTypeDefinition = CreateTypeDefinition(delegateDeclaration.Name);
231
 
                        td.Kind = TypeKind.Delegate;
232
 
                        td.Region = MakeRegion(delegateDeclaration);
233
 
                        td.BaseTypes.Add(KnownTypeReference.MulticastDelegate);
234
 
                        AddXmlDocumentation(td, delegateDeclaration);
235
 
                        
236
 
                        ApplyModifiers(td, delegateDeclaration.Modifiers);
237
 
                        td.IsSealed = true; // delegates are implicitly sealed
238
 
                        
239
 
                        ConvertTypeParameters(td.TypeParameters, delegateDeclaration.TypeParameters, delegateDeclaration.Constraints, EntityType.TypeDefinition);
240
 
                        
241
 
                        ITypeReference returnType = delegateDeclaration.ReturnType.ToTypeReference();
242
 
                        List<IUnresolvedParameter> parameters = new List<IUnresolvedParameter>();
243
 
                        ConvertParameters(parameters, delegateDeclaration.Parameters);
244
 
                        AddDefaultMethodsToDelegate(td, returnType, parameters);
245
 
                        
246
 
                        foreach (AttributeSection section in delegateDeclaration.Attributes) {
247
 
                                if (section.AttributeTarget == "return") {
248
 
                                        List<IUnresolvedAttribute> returnTypeAttributes = new List<IUnresolvedAttribute>();
249
 
                                        ConvertAttributes(returnTypeAttributes, section);
250
 
                                        IUnresolvedMethod invokeMethod = (IUnresolvedMethod)td.Members.Single(m => m.Name == "Invoke");
251
 
                                        IUnresolvedMethod endInvokeMethod = (IUnresolvedMethod)td.Members.Single(m => m.Name == "EndInvoke");
252
 
                                        foreach (IUnresolvedAttribute attr in returnTypeAttributes) {
253
 
                                                invokeMethod.ReturnTypeAttributes.Add(attr);
254
 
                                                endInvokeMethod.ReturnTypeAttributes.Add(attr);
255
 
                                        }
256
 
                                } else {
257
 
                                        ConvertAttributes(td.Attributes, section);
258
 
                                }
259
 
                        }
260
 
                        
261
 
                        currentTypeDefinition = (CSharpUnresolvedTypeDefinition)currentTypeDefinition.DeclaringTypeDefinition;
262
 
                        if (interningProvider != null) {
263
 
                                td.ApplyInterningProvider(interningProvider);
264
 
                        }
265
 
                        return td;
266
 
                }
267
 
                
268
 
                static readonly IUnresolvedParameter delegateObjectParameter = MakeParameter(KnownTypeReference.Object, "object");
269
 
                static readonly IUnresolvedParameter delegateIntPtrMethodParameter = MakeParameter(KnownTypeReference.IntPtr, "method");
270
 
                static readonly IUnresolvedParameter delegateAsyncCallbackParameter = MakeParameter(typeof(AsyncCallback).ToTypeReference(), "callback");
271
 
                static readonly IUnresolvedParameter delegateResultParameter = MakeParameter(typeof(IAsyncResult).ToTypeReference(), "result");
272
 
                
273
 
                static IUnresolvedParameter MakeParameter(ITypeReference type, string name)
274
 
                {
275
 
                        DefaultUnresolvedParameter p = new DefaultUnresolvedParameter(type, name);
276
 
                        p.Freeze();
277
 
                        return p;
278
 
                }
279
 
                
280
 
                /// <summary>
281
 
                /// Adds the 'Invoke', 'BeginInvoke', 'EndInvoke' methods, and a constructor, to the <paramref name="delegateType"/>.
282
 
                /// </summary>
283
 
                public static void AddDefaultMethodsToDelegate(DefaultUnresolvedTypeDefinition delegateType, ITypeReference returnType, IEnumerable<IUnresolvedParameter> parameters)
284
 
                {
285
 
                        if (delegateType == null)
286
 
                                throw new ArgumentNullException("delegateType");
287
 
                        if (returnType == null)
288
 
                                throw new ArgumentNullException("returnType");
289
 
                        if (parameters == null)
290
 
                                throw new ArgumentNullException("parameters");
291
 
                        
292
 
                        DomRegion region = delegateType.Region;
293
 
                        region = new DomRegion(region.FileName, region.BeginLine, region.BeginColumn); // remove end position
294
 
                        
295
 
                        DefaultUnresolvedMethod invoke = new DefaultUnresolvedMethod(delegateType, "Invoke");
296
 
                        invoke.Accessibility = Accessibility.Public;
297
 
                        invoke.IsSynthetic = true;
298
 
                        foreach (var p in parameters)
299
 
                                invoke.Parameters.Add(p);
300
 
                        invoke.ReturnType = returnType;
301
 
                        invoke.Region = region;
302
 
                        delegateType.Members.Add(invoke);
303
 
                        
304
 
                        DefaultUnresolvedMethod beginInvoke = new DefaultUnresolvedMethod(delegateType, "BeginInvoke");
305
 
                        beginInvoke.Accessibility = Accessibility.Public;
306
 
                        beginInvoke.IsSynthetic = true;
307
 
                        foreach (var p in parameters)
308
 
                                beginInvoke.Parameters.Add(p);
309
 
                        beginInvoke.Parameters.Add(delegateAsyncCallbackParameter);
310
 
                        beginInvoke.Parameters.Add(delegateObjectParameter);
311
 
                        beginInvoke.ReturnType = delegateResultParameter.Type;
312
 
                        beginInvoke.Region = region;
313
 
                        delegateType.Members.Add(beginInvoke);
314
 
                        
315
 
                        DefaultUnresolvedMethod endInvoke = new DefaultUnresolvedMethod(delegateType, "EndInvoke");
316
 
                        endInvoke.Accessibility = Accessibility.Public;
317
 
                        endInvoke.IsSynthetic = true;
318
 
                        endInvoke.Parameters.Add(delegateResultParameter);
319
 
                        endInvoke.ReturnType = invoke.ReturnType;
320
 
                        endInvoke.Region = region;
321
 
                        delegateType.Members.Add(endInvoke);
322
 
                        
323
 
                        DefaultUnresolvedMethod ctor = new DefaultUnresolvedMethod(delegateType, ".ctor");
324
 
                        ctor.EntityType = EntityType.Constructor;
325
 
                        ctor.Accessibility = Accessibility.Public;
326
 
                        ctor.IsSynthetic = true;
327
 
                        ctor.Parameters.Add(delegateObjectParameter);
328
 
                        ctor.Parameters.Add(delegateIntPtrMethodParameter);
329
 
                        ctor.ReturnType = delegateType;
330
 
                        ctor.Region = region;
331
 
                        delegateType.Members.Add(ctor);
332
 
                }
333
 
                #endregion
334
 
                
335
 
                #region Fields
336
 
                public override IUnresolvedEntity VisitFieldDeclaration(FieldDeclaration fieldDeclaration)
337
 
                {
338
 
                        bool isSingleField = fieldDeclaration.Variables.Count == 1;
339
 
                        Modifiers modifiers = fieldDeclaration.Modifiers;
340
 
                        DefaultUnresolvedField field = null;
341
 
                        foreach (VariableInitializer vi in fieldDeclaration.Variables) {
342
 
                                field = new DefaultUnresolvedField(currentTypeDefinition, vi.Name);
343
 
                                
344
 
                                field.Region = isSingleField ? MakeRegion(fieldDeclaration) : MakeRegion(vi);
345
 
                                field.BodyRegion = MakeRegion(vi);
346
 
                                ConvertAttributes(field.Attributes, fieldDeclaration.Attributes);
347
 
                                AddXmlDocumentation(field, fieldDeclaration);
348
 
                                
349
 
                                ApplyModifiers(field, modifiers);
350
 
                                field.IsVolatile = (modifiers & Modifiers.Volatile) != 0;
351
 
                                field.IsReadOnly = (modifiers & Modifiers.Readonly) != 0;
352
 
                                
353
 
                                field.ReturnType = fieldDeclaration.ReturnType.ToTypeReference();
354
 
                                
355
 
                                if ((modifiers & Modifiers.Const) != 0) {
356
 
                                        field.ConstantValue = ConvertConstantValue(field.ReturnType, vi.Initializer);
357
 
                                        field.IsStatic = true;
358
 
                                }
359
 
                                
360
 
                                currentTypeDefinition.Members.Add(field);
361
 
                                if (interningProvider != null) {
362
 
                                        field.ApplyInterningProvider(interningProvider);
363
 
                                }
364
 
                        }
365
 
                        return isSingleField ? field : null;
366
 
                }
367
 
                
368
 
                public override IUnresolvedEntity VisitFixedFieldDeclaration(FixedFieldDeclaration fixedFieldDeclaration)
369
 
                {
370
 
                        // TODO: add support for fixed fields
371
 
                        return base.VisitFixedFieldDeclaration(fixedFieldDeclaration);
372
 
                }
373
 
                
374
 
                public override IUnresolvedEntity VisitEnumMemberDeclaration(EnumMemberDeclaration enumMemberDeclaration)
375
 
                {
376
 
                        DefaultUnresolvedField field = new DefaultUnresolvedField(currentTypeDefinition, enumMemberDeclaration.Name);
377
 
                        field.Region = field.BodyRegion = MakeRegion(enumMemberDeclaration);
378
 
                        ConvertAttributes(field.Attributes, enumMemberDeclaration.Attributes);
379
 
                        AddXmlDocumentation(field, enumMemberDeclaration);
380
 
                        
381
 
                        if (currentTypeDefinition.TypeParameters.Count == 0) {
382
 
                                field.ReturnType = currentTypeDefinition;
383
 
                        } else {
384
 
                                ITypeReference[] typeArgs = new ITypeReference[currentTypeDefinition.TypeParameters.Count];
385
 
                                for (int i = 0; i < typeArgs.Length; i++) {
386
 
                                        typeArgs[i] = new TypeParameterReference(EntityType.TypeDefinition, i);
387
 
                                }
388
 
                                field.ReturnType = new ParameterizedTypeReference(currentTypeDefinition, typeArgs);
389
 
                        }
390
 
                        field.Accessibility = Accessibility.Public;
391
 
                        field.IsStatic = true;
392
 
                        if (!enumMemberDeclaration.Initializer.IsNull) {
393
 
                                field.ConstantValue = ConvertConstantValue(field.ReturnType, enumMemberDeclaration.Initializer);
394
 
                        } else {
395
 
                                DefaultUnresolvedField prevField = currentTypeDefinition.Members.LastOrDefault() as DefaultUnresolvedField;
396
 
                                if (prevField == null || prevField.ConstantValue == null) {
397
 
                                        field.ConstantValue = ConvertConstantValue(field.ReturnType, new PrimitiveExpression(0));
398
 
                                } else {
399
 
                                        field.ConstantValue = new IncrementConstantValue(prevField.ConstantValue);
400
 
                                }
401
 
                        }
402
 
                        
403
 
                        currentTypeDefinition.Members.Add(field);
404
 
                        if (interningProvider != null) {
405
 
                                field.ApplyInterningProvider(interningProvider);
406
 
                        }
407
 
                        return field;
408
 
                }
409
 
                #endregion
410
 
                
411
 
                #region Methods
412
 
                public override IUnresolvedEntity VisitMethodDeclaration(MethodDeclaration methodDeclaration)
413
 
                {
414
 
                        DefaultUnresolvedMethod m = new DefaultUnresolvedMethod(currentTypeDefinition, methodDeclaration.Name);
415
 
                        currentMethod = m; // required for resolving type parameters
416
 
                        m.Region = MakeRegion(methodDeclaration);
417
 
                        m.BodyRegion = MakeRegion(methodDeclaration.Body);
418
 
                        AddXmlDocumentation(m, methodDeclaration);
419
 
                        
420
 
                        if (InheritsConstraints(methodDeclaration) && methodDeclaration.Constraints.Count == 0) {
421
 
                                int index = 0;
422
 
                                foreach (TypeParameterDeclaration tpDecl in methodDeclaration.TypeParameters) {
423
 
                                        var tp = new MethodTypeParameterWithInheritedConstraints(index++, tpDecl.Name);
424
 
                                        tp.Region = MakeRegion(tpDecl);
425
 
                                        ConvertAttributes(tp.Attributes, tpDecl.Attributes);
426
 
                                        tp.Variance = tpDecl.Variance;
427
 
                                        m.TypeParameters.Add(tp);
428
 
                                }
429
 
                        } else {
430
 
                                ConvertTypeParameters(m.TypeParameters, methodDeclaration.TypeParameters, methodDeclaration.Constraints, EntityType.Method);
431
 
                        }
432
 
                        m.ReturnType = methodDeclaration.ReturnType.ToTypeReference();
433
 
                        ConvertAttributes(m.Attributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget != "return"));
434
 
                        ConvertAttributes(m.ReturnTypeAttributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget == "return"));
435
 
                        
436
 
                        ApplyModifiers(m, methodDeclaration.Modifiers);
437
 
                        if (methodDeclaration.IsExtensionMethod) {
438
 
                                m.IsExtensionMethod = true;
439
 
                                currentTypeDefinition.HasExtensionMethods = true;
440
 
                        }
441
 
                        if (methodDeclaration.HasModifier(Modifiers.Partial)) {
442
 
                                if (methodDeclaration.Body.IsNull)
443
 
                                        m.IsPartialMethodDeclaration = true;
444
 
                                else
445
 
                                        m.IsPartialMethodImplementation = true;
446
 
                        }
447
 
                        
448
 
                        ConvertParameters(m.Parameters, methodDeclaration.Parameters);
449
 
                        if (!methodDeclaration.PrivateImplementationType.IsNull) {
450
 
                                m.Accessibility = Accessibility.None;
451
 
                                m.IsExplicitInterfaceImplementation = true;
452
 
                                m.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
453
 
                                        m.EntityType, methodDeclaration.PrivateImplementationType.ToTypeReference(), m.Name,
454
 
                                        m.TypeParameters.Count, GetParameterTypes(m.Parameters)));
455
 
                        }
456
 
                        
457
 
                        currentTypeDefinition.Members.Add(m);
458
 
                        currentMethod = null;
459
 
                        if (interningProvider != null) {
460
 
                                m.ApplyInterningProvider(interningProvider);
461
 
                        }
462
 
                        return m;
463
 
                }
464
 
                
465
 
                IList<ITypeReference> GetParameterTypes(IList<IUnresolvedParameter> parameters)
466
 
                {
467
 
                        if (parameters.Count == 0)
468
 
                                return EmptyList<ITypeReference>.Instance;
469
 
                        ITypeReference[] types = new ITypeReference[parameters.Count];
470
 
                        for (int i = 0; i < types.Length; i++) {
471
 
                                types[i] = parameters[i].Type;
472
 
                        }
473
 
                        return types;
474
 
                }
475
 
                
476
 
                bool InheritsConstraints(MethodDeclaration methodDeclaration)
477
 
                {
478
 
                        // overrides and explicit interface implementations inherit constraints
479
 
                        if ((methodDeclaration.Modifiers & Modifiers.Override) == Modifiers.Override)
480
 
                                return true;
481
 
                        return !methodDeclaration.PrivateImplementationType.IsNull;
482
 
                }
483
 
                
484
 
                void ConvertTypeParameters(IList<IUnresolvedTypeParameter> output, AstNodeCollection<TypeParameterDeclaration> typeParameters,
485
 
                                           AstNodeCollection<Constraint> constraints, EntityType ownerType)
486
 
                {
487
 
                        // output might be non-empty when type parameters were copied from an outer class
488
 
                        int index = output.Count;
489
 
                        List<DefaultUnresolvedTypeParameter> list = new List<DefaultUnresolvedTypeParameter>();
490
 
                        foreach (TypeParameterDeclaration tpDecl in typeParameters) {
491
 
                                DefaultUnresolvedTypeParameter tp = new DefaultUnresolvedTypeParameter(ownerType, index++, tpDecl.Name);
492
 
                                tp.Region = MakeRegion(tpDecl);
493
 
                                ConvertAttributes(tp.Attributes, tpDecl.Attributes);
494
 
                                tp.Variance = tpDecl.Variance;
495
 
                                list.Add(tp);
496
 
                                output.Add(tp); // tp must be added to list here so that it can be referenced by constraints
497
 
                        }
498
 
                        foreach (Constraint c in constraints) {
499
 
                                foreach (var tp in list) {
500
 
                                        if (tp.Name == c.TypeParameter.Identifier) {
501
 
                                                foreach (AstType type in c.BaseTypes) {
502
 
                                                        PrimitiveType primType = type as PrimitiveType;
503
 
                                                        if (primType != null) {
504
 
                                                                if (primType.Keyword == "new") {
505
 
                                                                        tp.HasDefaultConstructorConstraint = true;
506
 
                                                                        continue;
507
 
                                                                } else if (primType.Keyword == "class") {
508
 
                                                                        tp.HasReferenceTypeConstraint = true;
509
 
                                                                        continue;
510
 
                                                                } else if (primType.Keyword == "struct") {
511
 
                                                                        tp.HasValueTypeConstraint = true;
512
 
                                                                        continue;
513
 
                                                                }
514
 
                                                        }
515
 
                                                        tp.Constraints.Add(type.ToTypeReference());
516
 
                                                }
517
 
                                                break;
518
 
                                        }
519
 
                                }
520
 
                        }
521
 
                }
522
 
                
523
 
                IMemberReference ConvertInterfaceImplementation(AstType interfaceType, AbstractUnresolvedMember unresolvedMember)
524
 
                {
525
 
                        ITypeReference interfaceTypeReference = interfaceType.ToTypeReference();
526
 
                        int typeParameterCount = 0;
527
 
                        IList<ITypeReference> parameterTypes = null;
528
 
                        if (unresolvedMember.EntityType == EntityType.Method) {
529
 
                                typeParameterCount = ((IUnresolvedMethod)unresolvedMember).TypeParameters.Count;
530
 
                        }
531
 
                        IUnresolvedParameterizedMember parameterizedMember = unresolvedMember as IUnresolvedParameterizedMember;
532
 
                        if (parameterizedMember != null) {
533
 
                                parameterTypes = new ITypeReference[parameterizedMember.Parameters.Count];
534
 
                                for (int i = 0; i < parameterTypes.Count; i++) {
535
 
                                        parameterTypes[i] = parameterizedMember.Parameters[i].Type;
536
 
                                }
537
 
                        }
538
 
                        return new DefaultMemberReference(unresolvedMember.EntityType, interfaceTypeReference, unresolvedMember.Name, typeParameterCount, parameterTypes);
539
 
                }
540
 
                #endregion
541
 
                
542
 
                #region Operators
543
 
                public override IUnresolvedEntity VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration)
544
 
                {
545
 
                        DefaultUnresolvedMethod m = new DefaultUnresolvedMethod(currentTypeDefinition, operatorDeclaration.Name);
546
 
                        m.EntityType = EntityType.Operator;
547
 
                        m.Region = MakeRegion(operatorDeclaration);
548
 
                        m.BodyRegion = MakeRegion(operatorDeclaration.Body);
549
 
                        AddXmlDocumentation(m, operatorDeclaration);
550
 
                        
551
 
                        m.ReturnType = operatorDeclaration.ReturnType.ToTypeReference();
552
 
                        ConvertAttributes(m.Attributes, operatorDeclaration.Attributes.Where(s => s.AttributeTarget != "return"));
553
 
                        ConvertAttributes(m.ReturnTypeAttributes, operatorDeclaration.Attributes.Where(s => s.AttributeTarget == "return"));
554
 
                        
555
 
                        ApplyModifiers(m, operatorDeclaration.Modifiers);
556
 
                        
557
 
                        ConvertParameters(m.Parameters, operatorDeclaration.Parameters);
558
 
                        
559
 
                        currentTypeDefinition.Members.Add(m);
560
 
                        if (interningProvider != null) {
561
 
                                m.ApplyInterningProvider(interningProvider);
562
 
                        }
563
 
                        return m;
564
 
                }
565
 
                #endregion
566
 
                
567
 
                #region Constructors
568
 
                public override IUnresolvedEntity VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration)
569
 
                {
570
 
                        Modifiers modifiers = constructorDeclaration.Modifiers;
571
 
                        bool isStatic = (modifiers & Modifiers.Static) != 0;
572
 
                        DefaultUnresolvedMethod ctor = new DefaultUnresolvedMethod(currentTypeDefinition, isStatic ? ".cctor" : ".ctor");
573
 
                        ctor.EntityType = EntityType.Constructor;
574
 
                        ctor.Region = MakeRegion(constructorDeclaration);
575
 
                        if (!constructorDeclaration.Initializer.IsNull) {
576
 
                                ctor.BodyRegion = MakeRegion(constructorDeclaration.Initializer.StartLocation, constructorDeclaration.EndLocation);
577
 
                        } else {
578
 
                                ctor.BodyRegion = MakeRegion(constructorDeclaration.Body);
579
 
                        }
580
 
                        ctor.ReturnType = KnownTypeReference.Void;
581
 
                        
582
 
                        ConvertAttributes(ctor.Attributes, constructorDeclaration.Attributes);
583
 
                        ConvertParameters(ctor.Parameters, constructorDeclaration.Parameters);
584
 
                        AddXmlDocumentation(ctor, constructorDeclaration);
585
 
                        
586
 
                        if (isStatic)
587
 
                                ctor.IsStatic = true;
588
 
                        else
589
 
                                ApplyModifiers(ctor, modifiers);
590
 
                        
591
 
                        currentTypeDefinition.Members.Add(ctor);
592
 
                        if (interningProvider != null) {
593
 
                                ctor.ApplyInterningProvider(interningProvider);
594
 
                        }
595
 
                        return ctor;
596
 
                }
597
 
                #endregion
598
 
                
599
 
                #region Destructors
600
 
                public override IUnresolvedEntity VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration)
601
 
                {
602
 
                        DefaultUnresolvedMethod dtor = new DefaultUnresolvedMethod(currentTypeDefinition, "Finalize");
603
 
                        dtor.EntityType = EntityType.Destructor;
604
 
                        dtor.Region = MakeRegion(destructorDeclaration);
605
 
                        dtor.BodyRegion = MakeRegion(destructorDeclaration.Body);
606
 
                        dtor.Accessibility = Accessibility.Protected;
607
 
                        dtor.IsOverride = true;
608
 
                        dtor.ReturnType = KnownTypeReference.Void;
609
 
                        
610
 
                        ConvertAttributes(dtor.Attributes, destructorDeclaration.Attributes);
611
 
                        AddXmlDocumentation(dtor, destructorDeclaration);
612
 
                        
613
 
                        currentTypeDefinition.Members.Add(dtor);
614
 
                        if (interningProvider != null) {
615
 
                                dtor.ApplyInterningProvider(interningProvider);
616
 
                        }
617
 
                        return dtor;
618
 
                }
619
 
                #endregion
620
 
                
621
 
                #region Properties / Indexers
622
 
                public override IUnresolvedEntity VisitPropertyDeclaration(PropertyDeclaration propertyDeclaration)
623
 
                {
624
 
                        DefaultUnresolvedProperty p = new DefaultUnresolvedProperty(currentTypeDefinition, propertyDeclaration.Name);
625
 
                        p.Region = MakeRegion(propertyDeclaration);
626
 
                        p.BodyRegion = MakeBraceRegion(propertyDeclaration);
627
 
                        ApplyModifiers(p, propertyDeclaration.Modifiers);
628
 
                        p.ReturnType = propertyDeclaration.ReturnType.ToTypeReference();
629
 
                        ConvertAttributes(p.Attributes, propertyDeclaration.Attributes);
630
 
                        AddXmlDocumentation(p, propertyDeclaration);
631
 
                        if (!propertyDeclaration.PrivateImplementationType.IsNull) {
632
 
                                p.Accessibility = Accessibility.None;
633
 
                                p.IsExplicitInterfaceImplementation = true;
634
 
                                p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
635
 
                                        p.EntityType, propertyDeclaration.PrivateImplementationType.ToTypeReference(), p.Name));
636
 
                        }
637
 
                        p.Getter = ConvertAccessor(propertyDeclaration.Getter, p, "get_");
638
 
                        p.Setter = ConvertAccessor(propertyDeclaration.Setter, p, "set_");
639
 
                        currentTypeDefinition.Members.Add(p);
640
 
                        if (interningProvider != null) {
641
 
                                p.ApplyInterningProvider(interningProvider);
642
 
                        }
643
 
                        return p;
644
 
                }
645
 
                
646
 
                public override IUnresolvedEntity VisitIndexerDeclaration(IndexerDeclaration indexerDeclaration)
647
 
                {
648
 
                        DefaultUnresolvedProperty p = new DefaultUnresolvedProperty(currentTypeDefinition, "Item");
649
 
                        p.EntityType = EntityType.Indexer;
650
 
                        p.Region = MakeRegion(indexerDeclaration);
651
 
                        p.BodyRegion = MakeBraceRegion(indexerDeclaration);
652
 
                        ApplyModifiers(p, indexerDeclaration.Modifiers);
653
 
                        p.ReturnType = indexerDeclaration.ReturnType.ToTypeReference();
654
 
                        ConvertAttributes(p.Attributes, indexerDeclaration.Attributes);
655
 
                        AddXmlDocumentation(p, indexerDeclaration);
656
 
                        
657
 
                        ConvertParameters(p.Parameters, indexerDeclaration.Parameters);
658
 
                        p.Getter = ConvertAccessor(indexerDeclaration.Getter, p, "get_");
659
 
                        p.Setter = ConvertAccessor(indexerDeclaration.Setter, p, "set_");
660
 
                        
661
 
                        if (!indexerDeclaration.PrivateImplementationType.IsNull) {
662
 
                                p.Accessibility = Accessibility.None;
663
 
                                p.IsExplicitInterfaceImplementation = true;
664
 
                                p.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
665
 
                                        p.EntityType, indexerDeclaration.PrivateImplementationType.ToTypeReference(), p.Name, 0, GetParameterTypes(p.Parameters)));
666
 
                        }
667
 
                        
668
 
                        currentTypeDefinition.Members.Add(p);
669
 
                        if (interningProvider != null) {
670
 
                                p.ApplyInterningProvider(interningProvider);
671
 
                        }
672
 
                        return p;
673
 
                }
674
 
                
675
 
                DefaultUnresolvedMethod ConvertAccessor(Accessor accessor, IUnresolvedMember p, string prefix)
676
 
                {
677
 
                        if (accessor.IsNull)
678
 
                                return null;
679
 
                        var a = new DefaultUnresolvedMethod(currentTypeDefinition, prefix + p.Name);
680
 
                        a.Accessibility = GetAccessibility(accessor.Modifiers) ?? p.Accessibility;
681
 
                        a.IsAbstract = p.IsAbstract;
682
 
                        a.IsOverride = p.IsOverridable;
683
 
                        a.IsSealed = p.IsSealed;
684
 
                        a.IsStatic = p.IsStatic;
685
 
                        a.IsSynthetic = p.IsSynthetic;
686
 
                        a.IsVirtual = p.IsVirtual;
687
 
                        
688
 
                        a.Region = MakeRegion(accessor);
689
 
                        if (p.EntityType == EntityType.Indexer) {
690
 
                                foreach (var indexerParam in ((IUnresolvedProperty)p).Parameters)
691
 
                                        a.Parameters.Add(indexerParam);
692
 
                        }
693
 
                        DefaultUnresolvedParameter param = null;
694
 
                        if (accessor.Role == PropertyDeclaration.GetterRole) {
695
 
                                a.ReturnType = p.ReturnType;
696
 
                        } else {
697
 
                                param = new DefaultUnresolvedParameter(p.ReturnType, "value");
698
 
                                a.Parameters.Add(param);
699
 
                                a.ReturnType = KnownTypeReference.Void;
700
 
                        }
701
 
                        foreach (AttributeSection section in accessor.Attributes) {
702
 
                                if (section.AttributeTarget == "return") {
703
 
                                        ConvertAttributes(a.ReturnTypeAttributes, section);
704
 
                                } else if (param != null && section.AttributeTarget == "param") {
705
 
                                        ConvertAttributes(param.Attributes, section);
706
 
                                } else {
707
 
                                        ConvertAttributes(a.Attributes, section);
708
 
                                }
709
 
                        }
710
 
                        return a;
711
 
                }
712
 
                #endregion
713
 
                
714
 
                #region Events
715
 
                public override IUnresolvedEntity VisitEventDeclaration(EventDeclaration eventDeclaration)
716
 
                {
717
 
                        bool isSingleEvent = eventDeclaration.Variables.Count == 1;
718
 
                        Modifiers modifiers = eventDeclaration.Modifiers;
719
 
                        DefaultUnresolvedEvent ev = null;
720
 
                        foreach (VariableInitializer vi in eventDeclaration.Variables) {
721
 
                                ev = new DefaultUnresolvedEvent(currentTypeDefinition, vi.Name);
722
 
                                
723
 
                                ev.Region = isSingleEvent ? MakeRegion(eventDeclaration) : MakeRegion(vi);
724
 
                                ev.BodyRegion = MakeRegion(vi);
725
 
                                
726
 
                                ApplyModifiers(ev, modifiers);
727
 
                                AddXmlDocumentation(ev, eventDeclaration);
728
 
                                
729
 
                                ev.ReturnType = eventDeclaration.ReturnType.ToTypeReference();
730
 
                                
731
 
                                var valueParameter = new DefaultUnresolvedParameter(ev.ReturnType, "value");
732
 
                                ev.AddAccessor = CreateDefaultEventAccessor(ev, "add_" + ev.Name, valueParameter);
733
 
                                ev.RemoveAccessor = CreateDefaultEventAccessor(ev, "remove_" + ev.Name, valueParameter);
734
 
                                
735
 
                                foreach (AttributeSection section in eventDeclaration.Attributes) {
736
 
                                        if (section.AttributeTarget == "method") {
737
 
                                                foreach (var attrNode in section.Attributes) {
738
 
                                                        IUnresolvedAttribute attr = ConvertAttribute(attrNode);
739
 
                                                        ev.AddAccessor.Attributes.Add(attr);
740
 
                                                        ev.RemoveAccessor.Attributes.Add(attr);
741
 
                                                }
742
 
                                        } else if (section.AttributeTarget != "field") {
743
 
                                                ConvertAttributes(ev.Attributes, section);
744
 
                                        }
745
 
                                }
746
 
                                
747
 
                                currentTypeDefinition.Members.Add(ev);
748
 
                                if (interningProvider != null) {
749
 
                                        ev.ApplyInterningProvider(interningProvider);
750
 
                                }
751
 
                        }
752
 
                        return isSingleEvent ? ev : null;
753
 
                }
754
 
                
755
 
                DefaultUnresolvedMethod CreateDefaultEventAccessor(IUnresolvedEvent ev, string name, IUnresolvedParameter valueParameter)
756
 
                {
757
 
                        var a = new DefaultUnresolvedMethod(currentTypeDefinition, name);
758
 
                        a.Region = ev.BodyRegion;
759
 
                        a.BodyRegion = ev.BodyRegion;
760
 
                        a.Accessibility = ev.Accessibility;
761
 
                        a.IsAbstract = ev.IsAbstract;
762
 
                        a.IsOverride = ev.IsOverridable;
763
 
                        a.IsSealed = ev.IsSealed;
764
 
                        a.IsStatic = ev.IsStatic;
765
 
                        a.IsSynthetic = ev.IsSynthetic;
766
 
                        a.IsVirtual = ev.IsVirtual;
767
 
                        a.ReturnType = KnownTypeReference.Void;
768
 
                        a.Parameters.Add(valueParameter);
769
 
                        return a;
770
 
                }
771
 
                
772
 
                public override IUnresolvedEntity VisitCustomEventDeclaration(CustomEventDeclaration eventDeclaration)
773
 
                {
774
 
                        DefaultUnresolvedEvent e = new DefaultUnresolvedEvent(currentTypeDefinition, eventDeclaration.Name);
775
 
                        e.Region = MakeRegion(eventDeclaration);
776
 
                        e.BodyRegion = MakeBraceRegion(eventDeclaration);
777
 
                        ApplyModifiers(e, eventDeclaration.Modifiers);
778
 
                        e.ReturnType = eventDeclaration.ReturnType.ToTypeReference();
779
 
                        ConvertAttributes(e.Attributes, eventDeclaration.Attributes);
780
 
                        AddXmlDocumentation(e, eventDeclaration);
781
 
                        
782
 
                        if (!eventDeclaration.PrivateImplementationType.IsNull) {
783
 
                                e.Accessibility = Accessibility.None;
784
 
                                e.IsExplicitInterfaceImplementation = true;
785
 
                                e.ExplicitInterfaceImplementations.Add(new DefaultMemberReference(
786
 
                                        e.EntityType, eventDeclaration.PrivateImplementationType.ToTypeReference(), e.Name));
787
 
                        }
788
 
                        
789
 
                        e.AddAccessor = ConvertAccessor(eventDeclaration.AddAccessor, e, "add_");
790
 
                        e.RemoveAccessor = ConvertAccessor(eventDeclaration.RemoveAccessor, e, "remove_");
791
 
                        
792
 
                        currentTypeDefinition.Members.Add(e);
793
 
                        if (interningProvider != null) {
794
 
                                e.ApplyInterningProvider(interningProvider);
795
 
                        }
796
 
                        return e;
797
 
                }
798
 
                #endregion
799
 
                
800
 
                #region Modifiers
801
 
                static void ApplyModifiers(DefaultUnresolvedTypeDefinition td, Modifiers modifiers)
802
 
                {
803
 
                        td.Accessibility = GetAccessibility(modifiers) ?? (td.DeclaringTypeDefinition != null ? Accessibility.Private : Accessibility.Internal);
804
 
                        td.IsAbstract = (modifiers & (Modifiers.Abstract | Modifiers.Static)) != 0;
805
 
                        td.IsSealed = (modifiers & (Modifiers.Sealed | Modifiers.Static)) != 0;
806
 
                        td.IsShadowing = (modifiers & Modifiers.New) != 0;
807
 
                }
808
 
                
809
 
                static void ApplyModifiers(AbstractUnresolvedMember m, Modifiers modifiers)
810
 
                {
811
 
                        // members from interfaces are always Public+Abstract.
812
 
                        if (m.DeclaringTypeDefinition.Kind == TypeKind.Interface) {
813
 
                                m.Accessibility = Accessibility.Public;
814
 
                                m.IsAbstract = true;
815
 
                                return;
816
 
                        }
817
 
                        m.Accessibility = GetAccessibility(modifiers) ?? Accessibility.Private;
818
 
                        m.IsAbstract = (modifiers & Modifiers.Abstract) != 0;
819
 
                        m.IsOverride = (modifiers & Modifiers.Override) != 0;
820
 
                        m.IsSealed = (modifiers & Modifiers.Sealed) != 0;
821
 
                        m.IsShadowing = (modifiers & Modifiers.New) != 0;
822
 
                        m.IsStatic = (modifiers & Modifiers.Static) != 0;
823
 
                        m.IsVirtual = (modifiers & Modifiers.Virtual) != 0;
824
 
                        //m.IsPartial = (modifiers & Modifiers.Partial) != 0;
825
 
                }
826
 
                
827
 
                static Accessibility? GetAccessibility(Modifiers modifiers)
828
 
                {
829
 
                        switch (modifiers & Modifiers.VisibilityMask) {
830
 
                                case Modifiers.Private:
831
 
                                        return Accessibility.Private;
832
 
                                case Modifiers.Internal:
833
 
                                        return Accessibility.Internal;
834
 
                                case Modifiers.Protected | Modifiers.Internal:
835
 
                                        return Accessibility.ProtectedOrInternal;
836
 
                                case Modifiers.Protected:
837
 
                                        return Accessibility.Protected;
838
 
                                case Modifiers.Public:
839
 
                                        return Accessibility.Public;
840
 
                                default:
841
 
                                        return null;
842
 
                        }
843
 
                }
844
 
                #endregion
845
 
                
846
 
                #region Attributes
847
 
                public override IUnresolvedEntity VisitAttributeSection(AttributeSection attributeSection)
848
 
                {
849
 
                        // non-assembly attributes are handled by their parent entity
850
 
                        if (attributeSection.AttributeTarget == "assembly") {
851
 
                                ConvertAttributes(parsedFile.AssemblyAttributes, attributeSection);
852
 
                        } else if (attributeSection.AttributeTarget == "module") {
853
 
                                ConvertAttributes(parsedFile.ModuleAttributes, attributeSection);
854
 
                        }
855
 
                        return null;
856
 
                }
857
 
                
858
 
                void ConvertAttributes(IList<IUnresolvedAttribute> outputList, IEnumerable<AttributeSection> attributes)
859
 
                {
860
 
                        foreach (AttributeSection section in attributes) {
861
 
                                ConvertAttributes(outputList, section);
862
 
                        }
863
 
                }
864
 
                
865
 
                void ConvertAttributes(IList<IUnresolvedAttribute> outputList, AttributeSection attributeSection)
866
 
                {
867
 
                        foreach (CSharp.Attribute attr in attributeSection.Attributes) {
868
 
                                outputList.Add(ConvertAttribute(attr));
869
 
                        }
870
 
                }
871
 
                
872
 
                internal static ITypeReference ConvertAttributeType(AstType type)
873
 
                {
874
 
                        ITypeReference tr = type.ToTypeReference();
875
 
                        if (!type.GetChildByRole(Roles.Identifier).IsVerbatim) {
876
 
                                // Try to add "Attribute" suffix, but only if the identifier
877
 
                                // (=last identifier in fully qualified name) isn't a verbatim identifier.
878
 
                                SimpleTypeOrNamespaceReference st = tr as SimpleTypeOrNamespaceReference;
879
 
                                MemberTypeOrNamespaceReference mt = tr as MemberTypeOrNamespaceReference;
880
 
                                if (st != null)
881
 
                                        return new AttributeTypeReference(st, st.AddSuffix("Attribute"));
882
 
                                else if (mt != null)
883
 
                                        return new AttributeTypeReference(mt, mt.AddSuffix("Attribute"));
884
 
                        }
885
 
                        return tr;
886
 
                }
887
 
                
888
 
                CSharpAttribute ConvertAttribute(CSharp.Attribute attr)
889
 
                {
890
 
                        DomRegion region = MakeRegion(attr);
891
 
                        ITypeReference type = ConvertAttributeType(attr.Type);
892
 
                        List<IConstantValue> positionalArguments = null;
893
 
                        List<KeyValuePair<string, IConstantValue>> namedCtorArguments = null;
894
 
                        List<KeyValuePair<string, IConstantValue>> namedArguments = null;
895
 
                        foreach (Expression expr in attr.Arguments) {
896
 
                                NamedArgumentExpression nae = expr as NamedArgumentExpression;
897
 
                                if (nae != null) {
898
 
                                        if (namedCtorArguments == null)
899
 
                                                namedCtorArguments = new List<KeyValuePair<string, IConstantValue>>();
900
 
                                        namedCtorArguments.Add(new KeyValuePair<string, IConstantValue>(nae.Name, ConvertAttributeArgument(nae.Expression)));
901
 
                                } else {
902
 
                                        NamedExpression namedExpression = expr as NamedExpression;
903
 
                                        if (namedExpression != null) {
904
 
                                                string name = namedExpression.Name;
905
 
                                                if (namedArguments == null)
906
 
                                                        namedArguments = new List<KeyValuePair<string, IConstantValue>>();
907
 
                                                namedArguments.Add(new KeyValuePair<string, IConstantValue>(name, ConvertAttributeArgument(namedExpression.Expression)));
908
 
                                        } else {
909
 
                                                if (positionalArguments == null)
910
 
                                                        positionalArguments = new List<IConstantValue>();
911
 
                                                positionalArguments.Add(ConvertAttributeArgument(expr));
912
 
                                        }
913
 
                                }
914
 
                        }
915
 
                        return new CSharpAttribute(type, region, positionalArguments, namedCtorArguments, namedArguments);
916
 
                }
917
 
                #endregion
918
 
                
919
 
                #region Types
920
 
                [Obsolete("Use AstType.ToTypeReference() instead.")]
921
 
                public static ITypeReference ConvertType(AstType type, NameLookupMode lookupMode = NameLookupMode.Type)
922
 
                {
923
 
                        return type.ToTypeReference(lookupMode);
924
 
                }
925
 
                #endregion
926
 
                
927
 
                #region Constant Values
928
 
                IConstantValue ConvertConstantValue(ITypeReference targetType, AstNode expression)
929
 
                {
930
 
                        return ConvertConstantValue(targetType, expression, currentTypeDefinition, currentMethod, usingScope);
931
 
                }
932
 
                
933
 
                internal static IConstantValue ConvertConstantValue(
934
 
                        ITypeReference targetType, AstNode expression,
935
 
                        IUnresolvedTypeDefinition parentTypeDefinition, IUnresolvedMethod parentMethodDefinition, UsingScope parentUsingScope)
936
 
                {
937
 
                        ConstantValueBuilder b = new ConstantValueBuilder(false);
938
 
                        ConstantExpression c = expression.AcceptVisitor(b);
939
 
                        if (c == null)
940
 
                                return new ErrorConstantValue(targetType);
941
 
                        PrimitiveConstantExpression pc = c as PrimitiveConstantExpression;
942
 
                        if (pc != null && pc.Type == targetType) {
943
 
                                // Save memory by directly using a SimpleConstantValue.
944
 
                                return new SimpleConstantValue(targetType, pc.Value);
945
 
                        }
946
 
                        // cast to the desired type
947
 
                        return new ConstantCast(targetType, c);
948
 
                }
949
 
                
950
 
                IConstantValue ConvertAttributeArgument(Expression expression)
951
 
                {
952
 
                        ConstantValueBuilder b = new ConstantValueBuilder(true);
953
 
                        return expression.AcceptVisitor(b);
954
 
                }
955
 
                
956
 
                sealed class ConstantValueBuilder : DepthFirstAstVisitor<ConstantExpression>
957
 
                {
958
 
                        readonly bool isAttributeArgument;
959
 
                        
960
 
                        public ConstantValueBuilder(bool isAttributeArgument)
961
 
                        {
962
 
                                this.isAttributeArgument = isAttributeArgument;
963
 
                        }
964
 
                        
965
 
                        protected override ConstantExpression VisitChildren(AstNode node)
966
 
                        {
967
 
                                return null;
968
 
                        }
969
 
                        
970
 
                        public override ConstantExpression VisitNullReferenceExpression(NullReferenceExpression nullReferenceExpression)
971
 
                        {
972
 
                                return new PrimitiveConstantExpression(KnownTypeReference.Object, null);
973
 
                        }
974
 
                        
975
 
                        public override ConstantExpression VisitPrimitiveExpression(PrimitiveExpression primitiveExpression)
976
 
                        {
977
 
                                TypeCode typeCode = Type.GetTypeCode(primitiveExpression.Value.GetType());
978
 
                                return new PrimitiveConstantExpression(typeCode.ToTypeReference(), primitiveExpression.Value);
979
 
                        }
980
 
                        
981
 
                        IList<ITypeReference> ConvertTypeArguments(AstNodeCollection<AstType> types)
982
 
                        {
983
 
                                int count = types.Count;
984
 
                                if (count == 0)
985
 
                                        return null;
986
 
                                ITypeReference[] result = new ITypeReference[count];
987
 
                                int pos = 0;
988
 
                                foreach (AstType type in types) {
989
 
                                        result[pos++] = type.ToTypeReference();
990
 
                                }
991
 
                                return result;
992
 
                        }
993
 
                        
994
 
                        public override ConstantExpression VisitIdentifierExpression(IdentifierExpression identifierExpression)
995
 
                        {
996
 
                                return new ConstantIdentifierReference(identifierExpression.Identifier, ConvertTypeArguments(identifierExpression.TypeArguments));
997
 
                        }
998
 
                        
999
 
                        public override ConstantExpression VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression)
1000
 
                        {
1001
 
                                TypeReferenceExpression tre = memberReferenceExpression.Target as TypeReferenceExpression;
1002
 
                                if (tre != null) {
1003
 
                                        // handle "int.MaxValue"
1004
 
                                        return new ConstantMemberReference(
1005
 
                                                tre.Type.ToTypeReference(),
1006
 
                                                memberReferenceExpression.MemberName,
1007
 
                                                ConvertTypeArguments(memberReferenceExpression.TypeArguments));
1008
 
                                }
1009
 
                                ConstantExpression v = memberReferenceExpression.Target.AcceptVisitor(this);
1010
 
                                if (v == null)
1011
 
                                        return null;
1012
 
                                return new ConstantMemberReference(
1013
 
                                        v, memberReferenceExpression.MemberName,
1014
 
                                        ConvertTypeArguments(memberReferenceExpression.TypeArguments));
1015
 
                        }
1016
 
                        
1017
 
                        public override ConstantExpression VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression)
1018
 
                        {
1019
 
                                return parenthesizedExpression.Expression.AcceptVisitor(this);
1020
 
                        }
1021
 
                        
1022
 
                        public override ConstantExpression VisitCastExpression(CastExpression castExpression)
1023
 
                        {
1024
 
                                ConstantExpression v = castExpression.Expression.AcceptVisitor(this);
1025
 
                                if (v == null)
1026
 
                                        return null;
1027
 
                                return new ConstantCast(castExpression.Type.ToTypeReference(), v);
1028
 
                        }
1029
 
                        
1030
 
                        public override ConstantExpression VisitCheckedExpression(CheckedExpression checkedExpression)
1031
 
                        {
1032
 
                                ConstantExpression v = checkedExpression.Expression.AcceptVisitor(this);
1033
 
                                if (v != null)
1034
 
                                        return new ConstantCheckedExpression(true, v);
1035
 
                                else
1036
 
                                        return null;
1037
 
                        }
1038
 
                        
1039
 
                        public override ConstantExpression VisitUncheckedExpression(UncheckedExpression uncheckedExpression)
1040
 
                        {
1041
 
                                ConstantExpression v = uncheckedExpression.Expression.AcceptVisitor(this);
1042
 
                                if (v != null)
1043
 
                                        return new ConstantCheckedExpression(false, v);
1044
 
                                else
1045
 
                                        return null;
1046
 
                        }
1047
 
                        
1048
 
                        public override ConstantExpression VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression)
1049
 
                        {
1050
 
                                return new ConstantDefaultValue(defaultValueExpression.Type.ToTypeReference());
1051
 
                        }
1052
 
                        
1053
 
                        public override ConstantExpression VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression)
1054
 
                        {
1055
 
                                ConstantExpression v = unaryOperatorExpression.Expression.AcceptVisitor(this);
1056
 
                                if (v == null)
1057
 
                                        return null;
1058
 
                                switch (unaryOperatorExpression.Operator) {
1059
 
                                        case UnaryOperatorType.Not:
1060
 
                                        case UnaryOperatorType.BitNot:
1061
 
                                        case UnaryOperatorType.Minus:
1062
 
                                        case UnaryOperatorType.Plus:
1063
 
                                                return new ConstantUnaryOperator(unaryOperatorExpression.Operator, v);
1064
 
                                        default:
1065
 
                                                return null;
1066
 
                                }
1067
 
                        }
1068
 
                        
1069
 
                        public override ConstantExpression VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression)
1070
 
                        {
1071
 
                                ConstantExpression left = binaryOperatorExpression.Left.AcceptVisitor(this);
1072
 
                                ConstantExpression right = binaryOperatorExpression.Right.AcceptVisitor(this);
1073
 
                                if (left == null || right == null)
1074
 
                                        return null;
1075
 
                                return new ConstantBinaryOperator(left, binaryOperatorExpression.Operator, right);
1076
 
                        }
1077
 
                        
1078
 
                        public override ConstantExpression VisitTypeOfExpression(TypeOfExpression typeOfExpression)
1079
 
                        {
1080
 
                                if (isAttributeArgument) {
1081
 
                                        return new TypeOfConstantExpression(typeOfExpression.Type.ToTypeReference());
1082
 
                                } else {
1083
 
                                        return null;
1084
 
                                }
1085
 
                        }
1086
 
                        
1087
 
                        public override ConstantExpression VisitArrayCreateExpression(ArrayCreateExpression arrayCreateExpression)
1088
 
                        {
1089
 
                                var initializer = arrayCreateExpression.Initializer;
1090
 
                                // Attributes only allow one-dimensional arrays
1091
 
                                if (isAttributeArgument && !initializer.IsNull && arrayCreateExpression.Arguments.Count < 2) {
1092
 
                                        ITypeReference type;
1093
 
                                        if (arrayCreateExpression.Type.IsNull) {
1094
 
                                                type = null;
1095
 
                                        } else {
1096
 
                                                type = arrayCreateExpression.Type.ToTypeReference();
1097
 
                                                foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) {
1098
 
                                                        type = new ArrayTypeReference(type, spec.Dimensions);
1099
 
                                                }
1100
 
                                        }
1101
 
                                        ConstantExpression[] elements = new ConstantExpression[initializer.Elements.Count];
1102
 
                                        int pos = 0;
1103
 
                                        foreach (Expression expr in initializer.Elements) {
1104
 
                                                ConstantExpression c = expr.AcceptVisitor(this);
1105
 
                                                if (c == null)
1106
 
                                                        return null;
1107
 
                                                elements[pos++] = c;
1108
 
                                        }
1109
 
                                        return new ConstantArrayCreation(type, elements);
1110
 
                                } else {
1111
 
                                        return null;
1112
 
                                }
1113
 
                        }
1114
 
                }
1115
 
                #endregion
1116
 
                
1117
 
                #region Parameters
1118
 
                void ConvertParameters(IList<IUnresolvedParameter> outputList, IEnumerable<ParameterDeclaration> parameters)
1119
 
                {
1120
 
                        foreach (ParameterDeclaration pd in parameters) {
1121
 
                                DefaultUnresolvedParameter p = new DefaultUnresolvedParameter(pd.Type.ToTypeReference(), pd.Name);
1122
 
                                p.Region = MakeRegion(pd);
1123
 
                                ConvertAttributes(p.Attributes, pd.Attributes);
1124
 
                                switch (pd.ParameterModifier) {
1125
 
                                        case ParameterModifier.Ref:
1126
 
                                                p.IsRef = true;
1127
 
                                                p.Type = new ByReferenceTypeReference(p.Type);
1128
 
                                                break;
1129
 
                                        case ParameterModifier.Out:
1130
 
                                                p.IsOut = true;
1131
 
                                                p.Type = new ByReferenceTypeReference(p.Type);
1132
 
                                                break;
1133
 
                                        case ParameterModifier.Params:
1134
 
                                                p.IsParams = true;
1135
 
                                                break;
1136
 
                                }
1137
 
                                if (!pd.DefaultExpression.IsNull)
1138
 
                                        p.DefaultValue = ConvertConstantValue(p.Type, pd.DefaultExpression);
1139
 
                                outputList.Add(p);
1140
 
                        }
1141
 
                }
1142
 
                
1143
 
                internal static IList<ITypeReference> GetParameterTypes(IEnumerable<ParameterDeclaration> parameters)
1144
 
                {
1145
 
                        List<ITypeReference> result = new List<ITypeReference>();
1146
 
                        foreach (ParameterDeclaration pd in parameters) {
1147
 
                                ITypeReference type = pd.Type.ToTypeReference();
1148
 
                                if (pd.ParameterModifier == ParameterModifier.Ref || pd.ParameterModifier == ParameterModifier.Out)
1149
 
                                        type = new ByReferenceTypeReference(type);
1150
 
                                result.Add(type);
1151
 
                        }
1152
 
                        return result;
1153
 
                }
1154
 
                #endregion
1155
 
                
1156
 
                #region XML Documentation
1157
 
                void AddXmlDocumentation(IUnresolvedEntity entity, AstNode entityDeclaration)
1158
 
                {
1159
 
                        if (this.SkipXmlDocumentation)
1160
 
                                return;
1161
 
                        List<string> documentation = null;
1162
 
                        // traverse AST backwards until the next non-whitespace node
1163
 
                        for (AstNode node = entityDeclaration.PrevSibling; node != null && node.NodeType == NodeType.Whitespace; node = node.PrevSibling) {
1164
 
                                Comment c = node as Comment;
1165
 
                                if (c != null && (c.CommentType == CommentType.Documentation || c.CommentType == CommentType.MultiLineDocumentation)) {
1166
 
                                        if (documentation == null)
1167
 
                                                documentation = new List<string>();
1168
 
                                        if (c.CommentType == CommentType.MultiLineDocumentation) {
1169
 
                                                documentation.Add(PrepareMultilineDocumentation(c.Content));
1170
 
                                        } else {
1171
 
                                                if (c.Content.Length > 0 && c.Content[0] == ' ')
1172
 
                                                        documentation.Add(c.Content.Substring(1));
1173
 
                                                else
1174
 
                                                        documentation.Add(c.Content);
1175
 
                                        }
1176
 
                                }
1177
 
                        }
1178
 
                        if (documentation != null) {
1179
 
                                documentation.Reverse(); // bring documentation in correct order
1180
 
                                parsedFile.AddDocumentation(entity, string.Join(Environment.NewLine, documentation));
1181
 
                        }
1182
 
                }
1183
 
                
1184
 
                string PrepareMultilineDocumentation(string content)
1185
 
                {
1186
 
                        StringBuilder b = new StringBuilder();
1187
 
                        using (var reader = new StringReader(content)) {
1188
 
                                string firstLine = reader.ReadLine();
1189
 
                                // Add first line only if it's not empty:
1190
 
                                if (!string.IsNullOrWhiteSpace(firstLine)) {
1191
 
                                        if (firstLine[0] == ' ')
1192
 
                                                b.Append(firstLine, 1, firstLine.Length - 1);
1193
 
                                        else
1194
 
                                                b.Append(firstLine);
1195
 
                                }
1196
 
                                // Read lines into list:
1197
 
                                List<string> lines = new List<string>();
1198
 
                                string line;
1199
 
                                while ((line = reader.ReadLine()) != null)
1200
 
                                        lines.Add(line);
1201
 
                                // If the last line (the line with '*/' delimiter) is white space only, ignore it.
1202
 
                                if (lines.Count > 0 && string.IsNullOrWhiteSpace(lines[lines.Count - 1]))
1203
 
                                        lines.RemoveAt(lines.Count - 1);
1204
 
                                if (lines.Count > 0) {
1205
 
                                        // Extract pattern from lines[0]: whitespace, asterisk, whitespace
1206
 
                                        int patternLength = 0;
1207
 
                                        string secondLine = lines[0];
1208
 
                                        while (patternLength < secondLine.Length && char.IsWhiteSpace(secondLine[patternLength]))
1209
 
                                                patternLength++;
1210
 
                                        if (patternLength < secondLine.Length && secondLine[patternLength] == '*') {
1211
 
                                                patternLength++;
1212
 
                                                while (patternLength < secondLine.Length && char.IsWhiteSpace(secondLine[patternLength]))
1213
 
                                                        patternLength++;
1214
 
                                        } else {
1215
 
                                                // no asterisk
1216
 
                                                patternLength = 0;
1217
 
                                        }
1218
 
                                        // Now reduce pattern length to the common pattern:
1219
 
                                        for (int i = 1; i < lines.Count; i++) {
1220
 
                                                line = lines[i];
1221
 
                                                if (line.Length < patternLength)
1222
 
                                                        patternLength = line.Length;
1223
 
                                                for (int j = 0; j < patternLength; j++) {
1224
 
                                                        if (secondLine[j] != line[j])
1225
 
                                                                patternLength = j;
1226
 
                                                }
1227
 
                                        }
1228
 
                                        // Append the lines to the string builder:
1229
 
                                        for (int i = 0; i < lines.Count; i++) {
1230
 
                                                if (b.Length > 0 || i > 0)
1231
 
                                                        b.Append(Environment.NewLine);
1232
 
                                                b.Append(lines[i], patternLength, lines[i].Length - patternLength);
1233
 
                                        }
1234
 
                                }
1235
 
                        }
1236
 
                        return b.ToString();
1237
 
                }
1238
 
                #endregion
1239
 
        }
1240
 
}