~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric

« back to all changes in this revision

Viewing changes to src/addins/CSharpBinding/MonoDevelop.CSharp.Parser/McsParser.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2011-06-27 17:03:13 UTC
  • mto: (1.8.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 54.
  • Revision ID: james.westby@ubuntu.com-20110627170313-6cvz3s19x6e9hqe9
ImportĀ upstreamĀ versionĀ 2.5.92+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// 
 
2
// McsParser.cs
 
3
//  
 
4
// Author:
 
5
//       Mike KrĆ¼ger <mkrueger@novell.com>
 
6
// 
 
7
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
 
8
// 
 
9
// Permission is hereby granted, free of charge, to any person obtaining a copy
 
10
// of this software and associated documentation files (the "Software"), to deal
 
11
// in the Software without restriction, including without limitation the rights
 
12
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
13
// copies of the Software, and to permit persons to whom the Software is
 
14
// furnished to do so, subject to the following conditions:
 
15
// 
 
16
// The above copyright notice and this permission notice shall be included in
 
17
// all copies or substantial portions of the Software.
 
18
// 
 
19
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
20
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
21
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 
22
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
23
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
24
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 
25
// THE SOFTWARE.
 
26
 
 
27
using System;
 
28
using System.Linq;
 
29
using System.Collections.Generic;
 
30
using System.IO;
 
31
using Mono.CSharp;
 
32
using System.Text;
 
33
using Mono.TextEditor;
 
34
using MonoDevelop.CSharp.Ast;
 
35
using MonoDevelop.Projects.Dom;
 
36
using MonoDevelop.Projects.Dom.Parser;
 
37
using MonoDevelop.CSharp.Resolver;
 
38
using MonoDevelop.Projects;
 
39
using MonoDevelop.CSharp.Project;
 
40
using System.CodeDom;
 
41
 
 
42
namespace MonoDevelop.CSharp.Parser
 
43
{
 
44
        public class McsParser : AbstractParser
 
45
        {
 
46
                public override IExpressionFinder CreateExpressionFinder (ProjectDom dom)
 
47
                {
 
48
                        return new NewCSharpExpressionFinder (dom);
 
49
                }
 
50
 
 
51
                public override IResolver CreateResolver (ProjectDom dom, object editor, string fileName)
 
52
                {
 
53
                        MonoDevelop.Ide.Gui.Document doc = (MonoDevelop.Ide.Gui.Document)editor;
 
54
                        return new NRefactoryResolver (dom, doc.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, doc.Editor, fileName);
 
55
                }
 
56
                
 
57
                public class ErrorReportPrinter : ReportPrinter
 
58
                {
 
59
                        public readonly List<Error> Errors = new List<Error> ();
 
60
                        
 
61
                        public override void Print (AbstractMessage msg)
 
62
                        {
 
63
                                base.Print (msg);
 
64
                                Error newError = new Error (msg.IsWarning ? ErrorType.Warning : ErrorType.Error, msg.Location.Row, msg.Location.Column, msg.Text);
 
65
                                Errors.Add (newError);
 
66
                        }
 
67
                }
 
68
                
 
69
                static string GetLangString (LangVersion ver)
 
70
                {
 
71
                        switch (ver) {
 
72
                        case LangVersion.Default:
 
73
                                return "Default";
 
74
                        case LangVersion.ISO_1:
 
75
                                return "ISO-1";
 
76
                        case LangVersion.ISO_2:
 
77
                                return "ISO-2";
 
78
                        }
 
79
                        return "Default";
 
80
                }
 
81
                
 
82
                public override ParsedDocument Parse (ProjectDom dom, string fileName, string content)
 
83
                {
 
84
                        lock (CompilerCallableEntryPoint.parseLock) {
 
85
                                if (string.IsNullOrEmpty (content))
 
86
                                        return null;
 
87
                                var tagComments = ProjectDomService.SpecialCommentTags.GetNames ();
 
88
                                List<string> compilerArguments = new List<string> ();
 
89
                                if (dom != null && dom.Project != null && MonoDevelop.Ide.IdeApp.Workspace != null) {
 
90
                                        DotNetProjectConfiguration configuration = dom.Project.GetConfiguration (MonoDevelop.Ide.IdeApp.Workspace.ActiveConfiguration) as DotNetProjectConfiguration;
 
91
                                        CSharpCompilerParameters par = configuration != null ? configuration.CompilationParameters as CSharpCompilerParameters : null;
 
92
                                        if (par != null) {
 
93
                                                if (!string.IsNullOrEmpty (par.DefineSymbols)) {
 
94
                                                        compilerArguments.Add ("-define:" + string.Join (";", par.DefineSymbols.Split (';', ',', ' ', '\t')));
 
95
                                                }
 
96
                                                if (par.UnsafeCode)
 
97
                                                        compilerArguments.Add ("-unsafe");
 
98
                                                if (par.TreatWarningsAsErrors)
 
99
                                                        compilerArguments.Add ("-warnaserror");
 
100
                                                if (!string.IsNullOrEmpty (par.NoWarnings))
 
101
                                                        compilerArguments.Add ("-nowarn:"+ string.Join (",", par.NoWarnings.Split (';', ',', ' ', '\t')));
 
102
                                                compilerArguments.Add ("-warn:" + par.WarningLevel);
 
103
                                                compilerArguments.Add ("-langversion:" + GetLangString (par.LangVersion));
 
104
                                                if (par.GenerateOverflowChecks)
 
105
                                                        compilerArguments.Add ("-checked");
 
106
                                        }
 
107
                                }
 
108
                                
 
109
                                var unit =  new MonoDevelop.Projects.Dom.CompilationUnit (fileName);
 
110
                                var result = new ParsedDocument (fileName);
 
111
                                result.CompilationUnit = unit;
 
112
                                
 
113
                                CompilerCompilationUnit top;
 
114
                                ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter ();
 
115
                                using (var stream = new MemoryStream (Encoding.Default.GetBytes (content))) {
 
116
                                        top = CompilerCallableEntryPoint.ParseFile (compilerArguments.ToArray (), stream, fileName, errorReportPrinter);
 
117
                                }
 
118
                                if (top == null)
 
119
                                        return null;
 
120
                                
 
121
                                foreach (var special in top.SpecialsBag.Specials) {
 
122
                                        var comment = special as SpecialsBag.Comment;
 
123
                                        if (comment != null) {
 
124
                                                VisitComment (result, comment, tagComments);
 
125
                                        } else {
 
126
                                                VisitPreprocessorDirective (result, special as SpecialsBag.PreProcessorDirective);
 
127
                                        }
 
128
                                }
 
129
                                
 
130
                                // convert DOM
 
131
                                var conversionVisitor = new ConversionVisitor (top.LocationsBag);
 
132
                                conversionVisitor.Dom = dom;
 
133
                                conversionVisitor.ParsedDocument = result;
 
134
                                conversionVisitor.Unit = unit;
 
135
                                top.UsingsBag.Global.Accept (conversionVisitor);
 
136
                                top.ModuleCompiled.Accept (conversionVisitor);
 
137
                                /*
 
138
                                try {
 
139
                                        unit.Tag = CSharpParser.Parse (top);
 
140
                                } catch (Exception ex) {
 
141
                                        System.Console.WriteLine (ex);
 
142
                                }*/
 
143
                                
 
144
                                // parser errors
 
145
                                errorReportPrinter.Errors.ForEach (e => conversionVisitor.ParsedDocument.Add (e));
 
146
                                return result;
 
147
                        }
 
148
                }
 
149
                
 
150
                void VisitComment (ParsedDocument result, SpecialsBag.Comment comment, string[] tagComments)
 
151
                {
 
152
                        var cmt = new MonoDevelop.Projects.Dom.Comment (comment.Content);
 
153
                        cmt.CommentStartsLine = comment.StartsLine;
 
154
                        switch (comment.CommentType) {
 
155
                        case SpecialsBag.CommentType.Multi:
 
156
                                cmt.CommentType = MonoDevelop.Projects.Dom.CommentType.MultiLine;
 
157
                                cmt.OpenTag = "/*";
 
158
                                cmt.ClosingTag = "*/";
 
159
                                break;
 
160
                        case SpecialsBag.CommentType.Single:
 
161
                                cmt.CommentType = MonoDevelop.Projects.Dom.CommentType.SingleLine;
 
162
                                cmt.OpenTag = "//";
 
163
                                break;
 
164
                        case SpecialsBag.CommentType.Documentation:
 
165
                                cmt.CommentType = MonoDevelop.Projects.Dom.CommentType.SingleLine;
 
166
                                cmt.IsDocumentation = true;
 
167
                                cmt.OpenTag = "///";
 
168
                                break;
 
169
                        }
 
170
                        cmt.Region = new DomRegion (comment.Line, comment.Col, comment.EndLine, comment.EndCol);
 
171
                        result.Comments.Add (cmt);
 
172
                        foreach (string tag in tagComments) {
 
173
                                int idx = comment.Content.IndexOf (tag);
 
174
                                if (idx < 0)
 
175
                                        continue;
 
176
                                result.Add (new Tag (tag, comment.Content, cmt.Region));
 
177
                        }
 
178
                }
 
179
 
 
180
                Stack<SpecialsBag.PreProcessorDirective> regions = new Stack<SpecialsBag.PreProcessorDirective> ();
 
181
                Stack<SpecialsBag.PreProcessorDirective> ifBlocks = new Stack<SpecialsBag.PreProcessorDirective> ();
 
182
                List<SpecialsBag.PreProcessorDirective> elifBlocks = new List<SpecialsBag.PreProcessorDirective> ();
 
183
                SpecialsBag.PreProcessorDirective elseBlock = null;
 
184
 
 
185
                Stack<ConditionalRegion> conditionalRegions = new Stack<ConditionalRegion> ();
 
186
                ConditionalRegion ConditionalRegion {
 
187
                        get {
 
188
                                return conditionalRegions.Count > 0 ? conditionalRegions.Peek () : null;
 
189
                        }
 
190
                }
 
191
 
 
192
                void CloseConditionBlock (DomLocation loc)
 
193
                {
 
194
                        if (ConditionalRegion == null || ConditionalRegion.ConditionBlocks.Count == 0 || !ConditionalRegion.ConditionBlocks[ConditionalRegion.ConditionBlocks.Count - 1].End.IsEmpty)
 
195
                                return;
 
196
                        ConditionalRegion.ConditionBlocks[ConditionalRegion.ConditionBlocks.Count - 1].End = loc;
 
197
                }
 
198
 
 
199
                void AddCurRegion (ParsedDocument result, int line, int col)
 
200
                {
 
201
                        if (ConditionalRegion == null)
 
202
                                return;
 
203
                        ConditionalRegion.End = new DomLocation (line, col);
 
204
                        result.Add (ConditionalRegion);
 
205
                        conditionalRegions.Pop ();
 
206
                }
 
207
 
 
208
                static ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor visitor = new ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor ();
 
209
 
 
210
                void VisitPreprocessorDirective (ParsedDocument result, SpecialsBag.PreProcessorDirective directive)
 
211
                {
 
212
                        DomLocation loc = new DomLocation (directive.Line, directive.Col);
 
213
                        switch (directive.Cmd) {
 
214
                        case Tokenizer.PreprocessorDirective.If:
 
215
                                conditionalRegions.Push (new ConditionalRegion (visitor.Text));
 
216
                                ifBlocks.Push (directive);
 
217
                                ConditionalRegion.Start = loc;
 
218
                                break;
 
219
                        case Tokenizer.PreprocessorDirective.Elif:
 
220
                                CloseConditionBlock (new DomLocation (directive.EndLine, directive.EndCol));
 
221
                                if (ConditionalRegion != null)
 
222
                                        ConditionalRegion.ConditionBlocks.Add (new ConditionBlock (visitor.Text, loc));
 
223
                                break;
 
224
                        case Tokenizer.PreprocessorDirective.Else:
 
225
                                CloseConditionBlock (new DomLocation (directive.EndLine, directive.EndCol));
 
226
                                if (ConditionalRegion != null)
 
227
                                        ConditionalRegion.ElseBlock = new DomRegion (loc, DomLocation.Empty);
 
228
                                break;
 
229
                        case Tokenizer.PreprocessorDirective.Endif:
 
230
                                DomLocation endLoc = new DomLocation (directive.EndLine, directive.EndCol);
 
231
                                CloseConditionBlock (endLoc);
 
232
                                if (ConditionalRegion != null && !ConditionalRegion.ElseBlock.Start.IsEmpty)
 
233
                                        ConditionalRegion.ElseBlock = new DomRegion (ConditionalRegion.ElseBlock.Start, endLoc);
 
234
                                AddCurRegion (result, directive.EndLine, directive.EndCol);
 
235
                                if (ifBlocks.Count > 0) {
 
236
                                        var ifBlock = ifBlocks.Pop ();
 
237
                                        DomRegion dr = new DomRegion (ifBlock.Line, ifBlock.Col, directive.EndLine, directive.EndCol);
 
238
                                        result.Add (new FoldingRegion ("#if " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
 
239
                                        foreach (var d in elifBlocks) {
 
240
                                                dr.Start = new DomLocation (d.Line, d.Col);
 
241
                                                result.Add (new FoldingRegion ("#elif " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
 
242
                                        }
 
243
                                        if (elseBlock != null) {
 
244
                                                dr.Start = new DomLocation (elseBlock.Line, elseBlock.Col);
 
245
                                                result.Add (new FoldingRegion ("#else", dr, FoldType.UserRegion, false));
 
246
                                        }
 
247
                                }
 
248
                                elseBlock = null;
 
249
                                break;
 
250
                        case Tokenizer.PreprocessorDirective.Define:
 
251
                                result.Add (new PreProcessorDefine (directive.Arg, loc));
 
252
                                break;
 
253
                        case Tokenizer.PreprocessorDirective.Region:
 
254
                                regions.Push (directive);
 
255
                                break;
 
256
                        case Tokenizer.PreprocessorDirective.Endregion:
 
257
                                if (regions.Count > 0) {
 
258
                                        var start = regions.Pop ();
 
259
                                        DomRegion dr = new DomRegion (start.Line, start.Col, directive.EndLine, directive.EndCol);
 
260
                                        result.Add (new FoldingRegion (start.Arg, dr, FoldType.UserRegion, true));
 
261
                                }
 
262
                                break;
 
263
                        }
 
264
                }
 
265
                
 
266
                class ConversionVisitor : StructuralVisitor
 
267
                {
 
268
                        public ProjectDom Dom {
 
269
                                get;
 
270
                                set;
 
271
                        }
 
272
                        
 
273
                        public ParsedDocument ParsedDocument {
 
274
                                get;
 
275
                                set;
 
276
                        }
 
277
                        
 
278
                        public LocationsBag LocationsBag  {
 
279
                                get;
 
280
                                private set;
 
281
                        }
 
282
                        
 
283
                        public MonoDevelop.Projects.Dom.CompilationUnit Unit {
 
284
                                get;
 
285
                                set;
 
286
                        }
 
287
                        static string[] keywordTable;
 
288
                        static ConversionVisitor ()
 
289
                        {
 
290
                                keywordTable = new string[255];
 
291
                                for (int i = 0; i < 255; i++) 
 
292
                                        keywordTable [i] = DomReturnType.Void.FullName;
 
293
                                
 
294
                                keywordTable [(int)BuiltinTypeSpec.Type.Other] = DomReturnType.Void.FullName;
 
295
                                keywordTable [(int)BuiltinTypeSpec.Type.String] = DomReturnType.String.FullName;
 
296
                                keywordTable [(int)BuiltinTypeSpec.Type.Int] = DomReturnType.Int32.FullName;
 
297
                                keywordTable [(int)BuiltinTypeSpec.Type.UInt] = DomReturnType.UInt32.FullName;
 
298
                                keywordTable [(int)BuiltinTypeSpec.Type.Long] = DomReturnType.Int64.FullName;
 
299
                                keywordTable [(int)BuiltinTypeSpec.Type.ULong] = DomReturnType.UInt64.FullName;
 
300
                                keywordTable [(int)BuiltinTypeSpec.Type.Object] = DomReturnType.Object.FullName;
 
301
                                keywordTable [(int)BuiltinTypeSpec.Type.Float] = DomReturnType.Float.FullName;
 
302
                                keywordTable [(int)BuiltinTypeSpec.Type.Double] = DomReturnType.Double.FullName;
 
303
                                keywordTable [(int)BuiltinTypeSpec.Type.Byte] = DomReturnType.Byte.FullName;
 
304
                                keywordTable [(int)BuiltinTypeSpec.Type.SByte] = DomReturnType.SByte.FullName;
 
305
                                keywordTable [(int)BuiltinTypeSpec.Type.Short] = DomReturnType.Int16.FullName;
 
306
                                keywordTable [(int)BuiltinTypeSpec.Type.UShort] = DomReturnType.UInt16.FullName;
 
307
                                keywordTable [(int)BuiltinTypeSpec.Type.Decimal] = DomReturnType.Decimal.FullName;
 
308
                                keywordTable [(int)BuiltinTypeSpec.Type.Char] = DomReturnType.Char.FullName;
 
309
                                keywordTable [(int)BuiltinTypeSpec.Type.Bool] = DomReturnType.Bool.FullName;
 
310
                                keywordTable [(int)BuiltinTypeSpec.Type.IntPtr] = DomReturnType.IntPtr.FullName;
 
311
                                keywordTable [(int)BuiltinTypeSpec.Type.UIntPtr] = DomReturnType.UIntPtr.FullName;
 
312
                        }
 
313
                        
 
314
                        public ConversionVisitor (LocationsBag locationsBag)
 
315
                        {
 
316
                                this.LocationsBag = locationsBag;
 
317
                        }
 
318
                        
 
319
                        int lastComment = 0;
 
320
                        string RetrieveDocumentation (int upToLine)
 
321
                        {
 
322
                                StringBuilder result = null;
 
323
                                while (lastComment < ParsedDocument.Comments.Count) {
 
324
                                        var cur = ParsedDocument.Comments[lastComment];
 
325
                                        if (cur.Region.Start.Line >= upToLine)
 
326
                                                break;
 
327
                                        if (cur.IsDocumentation) {
 
328
                                                if (result == null)
 
329
                                                        result = new StringBuilder ();
 
330
                                                result.Append (cur.Text);
 
331
                                        }
 
332
                                        lastComment++;
 
333
                                }
 
334
                                return result == null ? null : result.ToString ();
 
335
                        }
 
336
                        
 
337
                        public static DomLocation Convert (Mono.CSharp.Location loc)
 
338
                        {
 
339
                                return new DomLocation (loc.Row, loc.Column);
 
340
                        }
 
341
                        
 
342
                        public DomRegion ConvertRegion (Mono.CSharp.Location start, Mono.CSharp.Location end)
 
343
                        {
 
344
                                DomLocation startLoc = Convert (start);
 
345
                                var endLoc = Convert (end);
 
346
                                endLoc.Column++;
 
347
                                return new DomRegion (startLoc, endLoc);
 
348
                        }
 
349
                        
 
350
                        static MonoDevelop.Projects.Dom.Modifiers ConvertModifiers (Mono.CSharp.Modifiers modifiers)
 
351
                        {
 
352
                                MonoDevelop.Projects.Dom.Modifiers result = MonoDevelop.Projects.Dom.Modifiers.None;
 
353
                                
 
354
                                if ((modifiers & Mono.CSharp.Modifiers.PUBLIC) != 0)
 
355
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Public;
 
356
                                if ((modifiers & Mono.CSharp.Modifiers.PRIVATE) != 0)
 
357
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Private;
 
358
                                if ((modifiers & Mono.CSharp.Modifiers.PROTECTED) != 0)
 
359
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Protected;
 
360
                                if ((modifiers & Mono.CSharp.Modifiers.INTERNAL) != 0)
 
361
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Internal;
 
362
                                
 
363
                                if ((modifiers & Mono.CSharp.Modifiers.ABSTRACT) != 0)
 
364
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Abstract;
 
365
                                if ((modifiers & Mono.CSharp.Modifiers.NEW) != 0)
 
366
                                        result |= MonoDevelop.Projects.Dom.Modifiers.New;
 
367
                                if ((modifiers & Mono.CSharp.Modifiers.SEALED) != 0)
 
368
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Sealed;
 
369
                                if ((modifiers & Mono.CSharp.Modifiers.READONLY) != 0)
 
370
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Readonly;
 
371
                                if ((modifiers & Mono.CSharp.Modifiers.VIRTUAL) != 0)
 
372
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Virtual;
 
373
                                if ((modifiers & Mono.CSharp.Modifiers.OVERRIDE) != 0)
 
374
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Override;
 
375
                                if ((modifiers & Mono.CSharp.Modifiers.EXTERN) != 0)
 
376
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Extern;
 
377
                                if ((modifiers & Mono.CSharp.Modifiers.VOLATILE) != 0)
 
378
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Volatile;
 
379
                                if ((modifiers & Mono.CSharp.Modifiers.UNSAFE) != 0)
 
380
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Unsafe;
 
381
                                
 
382
                                if ((modifiers & Mono.CSharp.Modifiers.STATIC) != 0)
 
383
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Static;
 
384
                                
 
385
                                if ((modifiers & Mono.CSharp.Modifiers.PARTIAL) != 0)
 
386
                                        result |= MonoDevelop.Projects.Dom.Modifiers.Partial;
 
387
                                return result;
 
388
                        }
 
389
                        
 
390
                        void AddType (IType child)
 
391
                        {
 
392
                                if (typeStack.Count > 0) {
 
393
                                        typeStack.Peek ().Add (child);
 
394
                                } else {
 
395
                                        Unit.Add (child);
 
396
                                }
 
397
                        }
 
398
                        
 
399
                        
 
400
                        void AddTypeArguments (ATypeNameExpression texpr, DomReturnType result)
 
401
                        {
 
402
                                if (!texpr.HasTypeArguments)
 
403
                                        return;
 
404
                                foreach (var arg in texpr.TypeArguments.Args) {
 
405
                                        result.AddTypeParameter (ConvertReturnType (arg));
 
406
                                }
 
407
                        }
 
408
                        
 
409
                        IReturnType ConvertReturnType (Mono.CSharp.Expression typeName)
 
410
                        {
 
411
                                if (typeName is TypeExpression) {
 
412
                                        var typeExpr = (Mono.CSharp.TypeExpression)typeName;
 
413
                                        return new DomReturnType (keywordTable [(int)typeExpr.Type.BuiltinType]);
 
414
                                }
 
415
                                
 
416
                                if (typeName is Mono.CSharp.QualifiedAliasMember) {
 
417
                                        var qam = (Mono.CSharp.QualifiedAliasMember)typeName;
 
418
                                        // TODO: Overwork the return type model - atm we don't have a good representation
 
419
                                        // for qualified alias members.
 
420
                                        return new DomReturnType (qam.Name);
 
421
                                }
 
422
                                
 
423
                                if (typeName is MemberAccess) {
 
424
                                        MemberAccess ma = (MemberAccess)typeName;
 
425
                                        var baseType = (DomReturnType)ConvertReturnType (ma.LeftExpression);
 
426
                                        baseType.Parts.Add (new ReturnTypePart (ma.Name));
 
427
                                        AddTypeArguments (ma, baseType);
 
428
                                        return baseType;
 
429
                                }
 
430
                                
 
431
                                if (typeName is SimpleName) {
 
432
                                        var sn = (SimpleName)typeName;
 
433
                                        var result = new DomReturnType (sn.Name);
 
434
                                        AddTypeArguments (sn, result);
 
435
                                        return result;
 
436
                                }
 
437
                                
 
438
                                if (typeName is ComposedCast) {
 
439
                                        var cc = (ComposedCast)typeName;
 
440
                                        var baseType = (DomReturnType)ConvertReturnType (cc.Left);
 
441
                                        if (cc.Spec.IsNullable) {
 
442
                                                return new DomReturnType ("System.Nullable", true, new IReturnType[] { baseType });
 
443
                                        } else if (cc.Spec.IsPointer) {
 
444
                                                baseType.PointerNestingLevel++;
 
445
                                        } else {
 
446
                                                baseType.ArrayDimensions++;
 
447
                                                baseType.SetDimension (baseType.ArrayDimensions - 1, cc.Spec.Dimension - 1);
 
448
                                        }
 
449
                                        return baseType;
 
450
                                }
 
451
                                MonoDevelop.Core.LoggingService.LogError ("Error while converting :" + typeName + " - unknown type name");
 
452
                                return new DomReturnType (DomReturnType.Void.FullName);
 
453
                        }
 
454
                        
 
455
                        
 
456
                        IReturnType ConvertReturnType (MemberName name)
 
457
                        {
 
458
                                return ConvertReturnType (name.GetTypeExpression ());
 
459
                        }
 
460
                        
 
461
                        #region Global
 
462
                        string currentNamespaceName = "";
 
463
                        Stack<UsingsBag.Namespace> currentNamespace = new Stack<UsingsBag.Namespace> ();
 
464
                        
 
465
                        string ConvertToString (MemberName name)
 
466
                        {
 
467
                                if (name == null)
 
468
                                        return "";
 
469
                                
 
470
                                return name.Left != null ? ConvertToString (name.Left)  + "." + name.Name : name.Name;
 
471
                                
 
472
                        }
 
473
                        
 
474
                        public override void Visit (ModuleContainer mc)
 
475
                        {
 
476
                                foreach (var at in ConvertAttributes (mc.OptAttributes, mc))
 
477
                                        Unit.Add (at);
 
478
                        }
 
479
                        
 
480
                        public override void Visit (UsingsBag.Namespace nspace)
 
481
                        {
 
482
                                string oldNamespace = currentNamespaceName;
 
483
                                currentNamespace.Push (nspace);
 
484
                                if (nspace.Name != null) { // no need to push the global namespace
 
485
                                        string name = ConvertToString (nspace.Name);
 
486
                                        string[] splittedNamespace = name.Split ('.');
 
487
                                        for (int i = splittedNamespace.Length; i > 0; i--) {
 
488
                                                DomUsing domUsing = new DomUsing ();
 
489
                                                domUsing.IsFromNamespace = true;
 
490
                                                domUsing.Region = domUsing.ValidRegion = ConvertRegion (nspace.OpenBrace, nspace.CloseBrace); 
 
491
                                                domUsing.Add (string.Join (".", splittedNamespace, 0, i));
 
492
                                                Unit.Add (domUsing);
 
493
                                        }
 
494
                                        currentNamespaceName = string.IsNullOrEmpty (currentNamespaceName) ? name : currentNamespaceName + "." + name;
 
495
                                }
 
496
                                
 
497
                                VisitNamespaceUsings (nspace);
 
498
                                VisitNamespaceBody (nspace);
 
499
                                currentNamespace.Pop ();
 
500
                                currentNamespaceName = oldNamespace;
 
501
                        }
 
502
                        
 
503
                        public override void Visit (UsingsBag.Using u)
 
504
                        {
 
505
                                if (!string.IsNullOrEmpty (currentNamespaceName)) {
 
506
                                        DomUsing relativeNamespaceUsing = new DomUsing ();
 
507
                                        relativeNamespaceUsing.Region = ConvertRegion (u.UsingLocation, u.SemicolonLocation);
 
508
                                        relativeNamespaceUsing.ValidRegion = ConvertRegion (currentNamespace.Peek ().OpenBrace, currentNamespace.Peek ().CloseBrace); 
 
509
                                        relativeNamespaceUsing.Add (currentNamespaceName + "." + ConvertToString (u.NSpace));
 
510
                                        Unit.Add (relativeNamespaceUsing);
 
511
                                }
 
512
                                DomUsing domUsing = new DomUsing ();
 
513
                                domUsing.Region = ConvertRegion (u.UsingLocation, u.SemicolonLocation);
 
514
                                domUsing.ValidRegion = ConvertRegion (currentNamespace.Peek ().OpenBrace, currentNamespace.Peek ().CloseBrace); 
 
515
                                domUsing.Add (ConvertToString (u.NSpace));
 
516
                                Unit.Add (domUsing);
 
517
                        }
 
518
                        
 
519
                        public override void Visit (UsingsBag.AliasUsing u)
 
520
                        {
 
521
                                DomUsing domUsing = new DomUsing ();
 
522
                                domUsing.Region = ConvertRegion (u.UsingLocation, u.SemicolonLocation);
 
523
                                domUsing.ValidRegion = ConvertRegion (currentNamespace.Peek ().OpenBrace, currentNamespace.Peek ().CloseBrace); 
 
524
                                domUsing.Add (u.Identifier.Value, new DomReturnType (ConvertToString (u.Nspace)));
 
525
                                Unit.Add (domUsing);
 
526
                        }
 
527
                        
 
528
                        public override void Visit (MemberCore member)
 
529
                        {
 
530
                                Console.WriteLine ("Unknown member:");
 
531
                                Console.WriteLine (member.GetType () + "-> Member {0}", member.GetSignatureForError ());
 
532
                        }
 
533
                        
 
534
                        Stack<DomType> typeStack = new Stack<DomType> ();
 
535
                        
 
536
                        void VisitType (TypeContainer c, ClassType classType)
 
537
                        {
 
538
                                DomType newType = new DomType ();
 
539
                                newType.SourceProjectDom = Dom;
 
540
                                newType.CompilationUnit = Unit;
 
541
                                if (typeStack.Count == 0 && !string.IsNullOrEmpty (currentNamespaceName))
 
542
                                        newType.Namespace = currentNamespaceName;
 
543
                                
 
544
                                newType.Name = ConvertQuoted (c.MemberName.Name);
 
545
                                newType.Location = Convert (c.MemberName.Location);
 
546
                                newType.ClassType = classType;
 
547
                                var location = LocationsBag.GetMemberLocation (c);
 
548
                                
 
549
                                if (location != null && location.Count > 2) {
 
550
                                        var region = ConvertRegion (c.MemberName.Location, location[2]);
 
551
                                        region.Start = new DomLocation (region.Start.Line, region.Start.Column + c.MemberName.Name.Length);
 
552
                                        newType.BodyRegion =  region;
 
553
                                } else {
 
554
                                        var region = ConvertRegion (c.MemberName.Location, c.MemberName.Location);
 
555
                                        region.Start = new DomLocation (region.Start.Line, region.Start.Column + c.MemberName.Name.Length);
 
556
                                        region.End = new DomLocation (int.MaxValue, int.MaxValue);
 
557
                                        newType.BodyRegion =  region;
 
558
                                }
 
559
                                
 
560
                                newType.Modifiers = ConvertModifiers (c.ModFlags);
 
561
                                AddAttributes (newType, c.OptAttributes, c);
 
562
                                AddTypeParameter (newType, c);
 
563
                                
 
564
                                if (c.TypeBaseExpressions != null) {
 
565
                                        foreach (var type in c.TypeBaseExpressions) {
 
566
                                                var baseType = ConvertReturnType (type);
 
567
                                        //      Console.WriteLine (newType.Name + " -- " + baseType);
 
568
                                                if (newType.BaseType == null) {
 
569
                                                        newType.BaseType = baseType;
 
570
                                                } else {
 
571
                                                        newType.AddInterfaceImplementation (baseType);
 
572
                                                }
 
573
                                        }
 
574
                                }
 
575
                                
 
576
                                AddType (newType);
 
577
                                // visit members
 
578
                                typeStack.Push (newType);
 
579
                                foreach (MemberCore member in c.OrderedAllMembers) {
 
580
                                        member.Accept (this);
 
581
                                }
 
582
                                typeStack.Pop ();
 
583
                        }
 
584
                        
 
585
                        public override void Visit (Class c)
 
586
                        {
 
587
                                VisitType (c, ClassType.Class);
 
588
                        }
 
589
                        
 
590
                        public override void Visit (Struct s)
 
591
                        {
 
592
                                VisitType (s, ClassType.Struct);
 
593
                        }
 
594
                        
 
595
                        public override void Visit (Interface i)
 
596
                        {
 
597
                                VisitType (i, ClassType.Interface);
 
598
                        }
 
599
                        
 
600
                        public override void Visit (Mono.CSharp.Enum e)
 
601
                        {
 
602
                                VisitType (e, ClassType.Enum);
 
603
                        }
 
604
                        
 
605
                        class CodeAstVisitor : StructuralVisitor
 
606
                        {
 
607
                                public override object Visit (Constant constant)
 
608
                                {
 
609
                                        return new CodePrimitiveExpression (constant.GetValue ());
 
610
                                }
 
611
                                
 
612
                                public override object Visit (Unary unaryExpression)
 
613
                                {
 
614
                                        var exprResult = (CodeExpression)unaryExpression.Expr.Accept (this);
 
615
                                        
 
616
                                        switch (unaryExpression.Oper) {
 
617
                                        case Unary.Operator.UnaryPlus:
 
618
                                                return exprResult;
 
619
                                        case Unary.Operator.UnaryNegation: // -a => 0 - a
 
620
                                                return new CodeBinaryOperatorExpression (new CodePrimitiveExpression (0), CodeBinaryOperatorType.Subtract, exprResult);
 
621
                                        case Unary.Operator.LogicalNot: // !a => a == false
 
622
                                                return new CodeBinaryOperatorExpression (exprResult, CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (false));
 
623
                                        }
 
624
                                        return exprResult;
 
625
                                }
 
626
                                static CodeBinaryOperatorType Convert (Binary.Operator o)
 
627
                                {
 
628
                                        switch (o) {
 
629
                                        case Binary.Operator.Multiply:
 
630
                                                return CodeBinaryOperatorType.Multiply;
 
631
                                        case Binary.Operator.Division:
 
632
                                                return CodeBinaryOperatorType.Divide;
 
633
                                        case Binary.Operator.Modulus:
 
634
                                                return CodeBinaryOperatorType.Modulus;
 
635
                                        case Binary.Operator.Addition:
 
636
                                                return CodeBinaryOperatorType.Add;
 
637
                                        case Binary.Operator.Subtraction:
 
638
                                                return CodeBinaryOperatorType.Subtract;
 
639
                                        case Binary.Operator.LeftShift:
 
640
                                        case Binary.Operator.RightShift:
 
641
                                                return CodeBinaryOperatorType.Multiply; // unsupported
 
642
                                        case Binary.Operator.LessThan:
 
643
                                                return CodeBinaryOperatorType.LessThan;
 
644
                                        case Binary.Operator.GreaterThan:
 
645
                                                return CodeBinaryOperatorType.GreaterThan;
 
646
                                        case Binary.Operator.LessThanOrEqual:
 
647
                                                return CodeBinaryOperatorType.LessThanOrEqual;
 
648
                                        case Binary.Operator.GreaterThanOrEqual:
 
649
                                                return CodeBinaryOperatorType.GreaterThanOrEqual;
 
650
                                        case Binary.Operator.Equality:
 
651
                                                return CodeBinaryOperatorType.IdentityEquality;
 
652
                                        case Binary.Operator.Inequality:
 
653
                                                return CodeBinaryOperatorType.IdentityInequality;
 
654
                                        case Binary.Operator.BitwiseAnd:
 
655
                                                return CodeBinaryOperatorType.BitwiseAnd;
 
656
                                        case Binary.Operator.ExclusiveOr:
 
657
                                                return CodeBinaryOperatorType.BitwiseOr; // unsupported
 
658
                                        case Binary.Operator.BitwiseOr:
 
659
                                                return CodeBinaryOperatorType.BitwiseOr;
 
660
                                        case Binary.Operator.LogicalAnd:
 
661
                                                return CodeBinaryOperatorType.BooleanAnd;
 
662
                                        case Binary.Operator.LogicalOr:
 
663
                                                return CodeBinaryOperatorType.BooleanOr;
 
664
                                                        
 
665
                                        }
 
666
                                        return CodeBinaryOperatorType.Add;
 
667
                                }
 
668
                                
 
669
                                public override object Visit (Binary binaryExpression)
 
670
                                {
 
671
                                        return new CodeBinaryOperatorExpression (
 
672
                                                (CodeExpression)binaryExpression.Left.Accept (this),
 
673
                                                Convert (binaryExpression.Oper),
 
674
                                                (CodeExpression)binaryExpression.Right.Accept (this));
 
675
                                }
 
676
                        }
 
677
 
 
678
                        
 
679
                        System.CodeDom.CodeExpression ResolveMemberAccessExpression (Mono.CSharp.Expression expr)
 
680
                        {
 
681
                                if (expr is MemberAccess) {
 
682
                                        var ma = (MemberAccess)expr;
 
683
                                        return new CodeFieldReferenceExpression (ResolveMemberAccessExpression (ma.LeftExpression), ma.Name);
 
684
                                }
 
685
                                if (expr is SimpleName)
 
686
                                        return new CodeTypeReferenceExpression (((SimpleName)expr).Name);
 
687
                                return null;
 
688
                        }
 
689
                        
 
690
                        IEnumerable<IAttribute> ConvertAttributes (Attributes optAttributes, IMemberContext mc)
 
691
                        {
 
692
                                List<IAttribute> atts = new List<IAttribute> ();
 
693
                                
 
694
                                if (optAttributes == null || optAttributes.Attrs == null)
 
695
                                        return atts;
 
696
                                
 
697
                                ResolveContext ctx = new ResolveContext (mc);
 
698
                                
 
699
                                foreach (var attr in optAttributes.Attrs) {
 
700
                                        DomAttribute domAttribute = new DomAttribute ();
 
701
                                        domAttribute.Name = ConvertQuoted (attr.Name);
 
702
                                        domAttribute.Region = ConvertRegion (attr.Location, attr.Location);
 
703
                                        domAttribute.AttributeType = ConvertReturnType (attr.TypeNameExpression);
 
704
                                        if (attr.PosArguments != null) {
 
705
                                                for (int i = 0; i < attr.PosArguments.Count; i++) {
 
706
                                                        CodeExpression domExp;
 
707
                                                        var exp = attr.PosArguments [i].Expr;
 
708
                                                        if (exp is TypeOf) {
 
709
                                                                TypeOf tof = (TypeOf)exp;
 
710
                                                                IReturnType rt = ConvertReturnType (tof.TypeExpression);
 
711
                                                                domExp = new CodeTypeOfExpression (rt.FullName);
 
712
                                                        } else {
 
713
                                                                try {
 
714
                                                                        domExp = ResolveMemberAccessExpression (exp);
 
715
                                                                        // may be literal
 
716
                                                                        if (domExp == null) {
 
717
                                                                                var res = exp.Resolve (ctx);
 
718
                                                                                var val = res as Constant;
 
719
                                                                                if (val == null)
 
720
                                                                                        continue;
 
721
                                                                                domExp = new CodePrimitiveExpression (val.GetValue ());
 
722
                                                                        }
 
723
                                                                } catch {
 
724
                                                                        continue;
 
725
                                                                }
 
726
                                                        }
 
727
                                                        domAttribute.AddPositionalArgument (domExp);
 
728
                                                }
 
729
                                        }
 
730
                                        if (attr.NamedArguments != null) {
 
731
                                                for (int i = 0; i < attr.NamedArguments.Count; i++) {
 
732
                                                        var val = attr.NamedArguments [i].Expr as Constant;
 
733
                                                        if (val == null)
 
734
                                                                continue;
 
735
                                                        domAttribute.AddNamedArgument (((NamedArgument)attr.NamedArguments [i]).Name, new CodePrimitiveExpression (val.GetValue ()));
 
736
                                                }
 
737
                                        }
 
738
                                        
 
739
                                        atts.Add (domAttribute);
 
740
                                }
 
741
                                return atts;
 
742
                        }
 
743
                        
 
744
                        public void AddAttributes (MonoDevelop.Projects.Dom.AbstractMember member, Attributes optAttributes, IMemberContext mc)
 
745
                        {
 
746
                                foreach (var attr in ConvertAttributes (optAttributes, mc))
 
747
                                        member.Add (attr);
 
748
                        }
 
749
                        
 
750
                        MonoDevelop.Projects.Dom.TypeParameter ConvertTemplateDefinition (Mono.CSharp.TypeParameter parameter)
 
751
                        {
 
752
                                var result = new MonoDevelop.Projects.Dom.TypeParameter (parameter.Name);
 
753
                                if (parameter.Constraints != null) {
 
754
                                        foreach (var constraintExpr in parameter.Constraints.ConstraintExpressions) {
 
755
                                                if (constraintExpr is SpecialContraintExpr) {
 
756
                                                        var sce = (SpecialContraintExpr)constraintExpr;
 
757
                                                        if (sce.Constraint == SpecialConstraint.Struct)
 
758
                                                                result.AddConstraint (DomReturnType.ValueType);
 
759
                                                        if (sce.Constraint == SpecialConstraint.Class)
 
760
                                                                result.AddConstraint (DomReturnType.Object);
 
761
                                                        if (sce.Constraint == SpecialConstraint.Constructor)
 
762
                                                                result.TypeParameterModifier |= TypeParameterModifier.HasDefaultConstructorConstraint;
 
763
                                                } else {
 
764
                                                        result.AddConstraint (ConvertReturnType (constraintExpr));
 
765
                                                }
 
766
                                        }
 
767
                                }
 
768
                                return result;
 
769
                        }
 
770
 
 
771
                        public void AddTypeParameter (AbstractTypeParameterMember member, DeclSpace decl)
 
772
                        {
 
773
                                if (!decl.IsGeneric || decl.CurrentTypeParameters == null)
 
774
                                        return;
 
775
                                
 
776
                                foreach (var typeParameter in decl.CurrentTypeParameters) {
 
777
                                        var par = ConvertTemplateDefinition (typeParameter);
 
778
                                        member.AddTypeParameter (par);
 
779
                                }
 
780
                        }
 
781
 
 
782
                        public override void Visit (Mono.CSharp.Delegate d)
 
783
                        {
 
784
                                DomType delegateType = DomType.CreateDelegate (Unit, d.MemberName.Name, Convert (d.MemberName.Location), ConvertReturnType (d.ReturnType), null);
 
785
                                delegateType.SourceProjectDom = Dom;
 
786
                                delegateType.Location = Convert (d.MemberName.Location);
 
787
                                delegateType.Documentation = RetrieveDocumentation (d.MemberName.Location.Row);
 
788
                                delegateType.Modifiers = ConvertModifiers (d.ModFlags);
 
789
                                AddAttributes (delegateType, d.OptAttributes, d);
 
790
                                
 
791
                                AddParameter ((MonoDevelop.Projects.Dom.AbstractMember)delegateType.Methods.First (), d.Parameters);
 
792
                                AddTypeParameter (delegateType, d);
 
793
                                AddType (delegateType);
 
794
                        
 
795
                        }
 
796
                        #endregion
 
797
                        
 
798
                        #region Type members
 
799
 
 
800
                        
 
801
                        public override void Visit (FixedField f)
 
802
                        {
 
803
                                DomField field = new DomField ();
 
804
                                field.Name = ConvertQuoted (f.MemberName.Name);
 
805
                                field.Documentation = RetrieveDocumentation (f.Location.Row);
 
806
                                field.Location = Convert (f.MemberName.Location);
 
807
                                field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Fixed;
 
808
                                field.ReturnType = ConvertReturnType (f.TypeName);
 
809
                                AddAttributes (field, f.OptAttributes, f);
 
810
                                field.DeclaringType = typeStack.Peek ();
 
811
                                typeStack.Peek ().Add (field);
 
812
                                if (f.Declarators != null) {
 
813
                                        foreach (var decl in f.Declarators) {
 
814
                                                field = new DomField ();
 
815
                                                field.Name = ConvertQuoted (decl.Name.Value);
 
816
                                                field.Location = Convert (decl.Name.Location);
 
817
                                                field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Fixed;
 
818
                                                field.ReturnType = ConvertReturnType (f.TypeName);
 
819
                                                AddAttributes (field, f.OptAttributes, f);
 
820
                                                field.DeclaringType = typeStack.Peek ();
 
821
                                                typeStack.Peek ().Add (field);
 
822
                                        }
 
823
                                }
 
824
                        }
 
825
                        
 
826
                        public override void Visit (Field f)
 
827
                        {
 
828
                                var field = new DomField ();
 
829
                                field.Name = ConvertQuoted (f.MemberName.Name);
 
830
                                field.Documentation = RetrieveDocumentation (f.Location.Row);
 
831
                                field.Location = Convert (f.MemberName.Location);
 
832
                                field.Modifiers = ConvertModifiers (f.ModFlags);
 
833
                                field.ReturnType = ConvertReturnType (f.TypeName);
 
834
                                AddAttributes (field, f.OptAttributes, f);
 
835
                                field.DeclaringType = typeStack.Peek ();
 
836
                                typeStack.Peek ().Add (field);
 
837
                                
 
838
                                if (f.Declarators != null) {
 
839
                                        foreach (var decl in f.Declarators) {
 
840
                                                field = new DomField ();
 
841
                                                field.Name = ConvertQuoted (decl.Name.Value);
 
842
                                                field.Location = Convert (decl.Name.Location);
 
843
                                                field.Modifiers = ConvertModifiers (f.ModFlags);
 
844
                                                field.ReturnType = ConvertReturnType (f.TypeName);
 
845
                                                AddAttributes (field, f.OptAttributes, f);
 
846
                                                field.DeclaringType = typeStack.Peek ();
 
847
                                                typeStack.Peek ().Add (field);
 
848
                                        }
 
849
                                }
 
850
                        }
 
851
                        
 
852
                        public override void Visit (Const f)
 
853
                        {
 
854
                                DomField field = new DomField ();
 
855
                                field.Name = ConvertQuoted (f.MemberName.Name);
 
856
                                field.Documentation = RetrieveDocumentation (f.Location.Row);
 
857
                                field.Location = Convert (f.MemberName.Location);
 
858
                                field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Const;
 
859
                                field.ReturnType = ConvertReturnType (f.TypeName);
 
860
                                AddAttributes (field, f.OptAttributes, f);
 
861
                                field.DeclaringType = typeStack.Peek ();
 
862
                                typeStack.Peek ().Add (field);
 
863
                                if (f.Declarators != null) {
 
864
                                        foreach (var decl in f.Declarators) {
 
865
                                                field = new DomField ();
 
866
                                                field.Name = ConvertQuoted (decl.Name.Value);
 
867
                                                field.Location = Convert (decl.Name.Location);
 
868
                                                field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Const;
 
869
                                                field.ReturnType = ConvertReturnType (f.TypeName);
 
870
                                                AddAttributes (field, f.OptAttributes, f);
 
871
                                                field.DeclaringType = typeStack.Peek ();
 
872
                                                typeStack.Peek ().Add (field);
 
873
                                        }
 
874
                                }
 
875
                        }
 
876
                        
 
877
                        void AddExplicitInterfaces (MonoDevelop.Projects.Dom.AbstractMember member, InterfaceMemberBase mcsMember)
 
878
                        {
 
879
                                if (!mcsMember.IsExplicitImpl)
 
880
                                        return;
 
881
                                member.AddExplicitInterface (ConvertReturnType (mcsMember.MemberName.Left));
 
882
                        }
 
883
 
 
884
                        public override void Visit (EventField e)
 
885
                        {
 
886
                                var evt = new DomEvent ();
 
887
                                evt.Name = ConvertQuoted (e.MemberName.Name);
 
888
                                evt.Documentation = RetrieveDocumentation (e.Location.Row);
 
889
                                evt.Location = Convert (e.MemberName.Location);
 
890
                                evt.Modifiers = ConvertModifiers (e.ModFlags);
 
891
                                evt.ReturnType = ConvertReturnType (e.TypeName);
 
892
                                AddAttributes (evt, e.OptAttributes, e);
 
893
                                AddExplicitInterfaces (evt, e);
 
894
                                evt.DeclaringType = typeStack.Peek ();
 
895
                                typeStack.Peek ().Add (evt);
 
896
                                if (e.Declarators != null) {
 
897
                                        foreach (var decl in e.Declarators) {
 
898
                                                evt = new DomEvent ();
 
899
                                                evt.Name = ConvertQuoted (decl.Name.Value);
 
900
                                                evt.Location = Convert (decl.Name.Location);
 
901
                                                evt.Modifiers = ConvertModifiers (e.ModFlags);
 
902
                                                evt.ReturnType = ConvertReturnType (e.TypeName);
 
903
                                                AddAttributes (evt, e.OptAttributes, e);
 
904
                                                evt.DeclaringType = typeStack.Peek ();
 
905
                                                typeStack.Peek ().Add (evt);
 
906
                                        }
 
907
                                }
 
908
                        }
 
909
                        
 
910
                        public override void Visit (EventProperty e)
 
911
                        {
 
912
                                DomEvent evt = new DomEvent ();
 
913
                                evt.Name = ConvertQuoted (e.MemberName.Name);
 
914
                                evt.Documentation = RetrieveDocumentation (e.Location.Row);
 
915
                                evt.Location = Convert (e.MemberName.Location);
 
916
                                evt.Modifiers = ConvertModifiers (e.ModFlags);
 
917
                                evt.ReturnType = ConvertReturnType (e.TypeName);
 
918
                                var location = LocationsBag.GetMemberLocation (e);
 
919
                                if (location != null)
 
920
                                        evt.BodyRegion = ConvertRegion (location[1], location[2]);
 
921
                                
 
922
                                AddAttributes (evt, e.OptAttributes, e);
 
923
                                AddExplicitInterfaces (evt, e);
 
924
                                
 
925
                                evt.DeclaringType = typeStack.Peek ();
 
926
                                typeStack.Peek ().Add (evt);
 
927
                        }
 
928
                        
 
929
                        public override void Visit (Property p)
 
930
                        {
 
931
                                DomProperty property = new DomProperty ();
 
932
                                property.Name = ConvertQuoted (p.MemberName.Name);
 
933
                                property.Documentation = RetrieveDocumentation (p.Location.Row);
 
934
                                property.Location = Convert (p.MemberName.Location);
 
935
                                property.GetterModifier = property.SetterModifier = ConvertModifiers (p.ModFlags);
 
936
                                
 
937
                                var location = LocationsBag.GetMemberLocation (p);
 
938
                                if (location != null && location.Count >= 1) {
 
939
                                        var endLoc = location.Count == 1 ? location[0] : location[1];
 
940
                                        property.BodyRegion = ConvertRegion (location[0], endLoc);
 
941
                                } else {
 
942
                                        property.BodyRegion = DomRegion.Empty;
 
943
                                }
 
944
                                property.ReturnType = ConvertReturnType (p.TypeName);
 
945
                                
 
946
                                AddAttributes (property, p.OptAttributes, p);
 
947
                                AddExplicitInterfaces (property, p);
 
948
                                
 
949
                                if (p.Get != null) {
 
950
                                        property.PropertyModifier |= PropertyModifier.HasGet;
 
951
                                        if ((p.Get.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
 
952
                                                property.GetterModifier = ConvertModifiers (p.Get.ModFlags);
 
953
                                        if (p.Get.Block != null) {
 
954
                                                property.GetRegion = ConvertRegion (p.Get.Location, p.Get.Block.EndLocation);
 
955
                                        } else {
 
956
                                                var getLocation = LocationsBag.GetMemberLocation (p.Get);
 
957
                                                property.GetRegion = ConvertRegion (p.Get.Location, getLocation.Count > 0 ? getLocation[0] : p.Get.Location);
 
958
                                        }
 
959
                                }
 
960
                                
 
961
                                if (p.Set != null) {
 
962
                                        property.PropertyModifier |= PropertyModifier.HasSet;
 
963
                                        if ((p.Set.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
 
964
                                                property.SetterModifier = ConvertModifiers (p.Set.ModFlags);
 
965
                                        if (p.Set.Block != null) {
 
966
                                                property.SetRegion = ConvertRegion (p.Set.Location, p.Set.Block.EndLocation);
 
967
                                        } else {
 
968
                                                var setLocation = LocationsBag.GetMemberLocation (p.Set);
 
969
                                                property.SetRegion = ConvertRegion (p.Set.Location, setLocation.Count > 0 ? setLocation[0] : p.Set.Location);
 
970
                                        }
 
971
                                }
 
972
                                property.DeclaringType = typeStack.Peek ();
 
973
                                typeStack.Peek ().Add (property);
 
974
                        }
 
975
 
 
976
                        static string ConvertQuoted (string name)
 
977
                        {
 
978
                                if (name == null)
 
979
                                        return null;
 
980
                                return name.StartsWith ("@") ? name.Substring (1) : name;
 
981
                        }
 
982
 
 
983
                        public void AddParameter (MonoDevelop.Projects.Dom.AbstractMember member, AParametersCollection parameters)
 
984
                        {
 
985
                                for (int i = 0; i < parameters.Count; i++) {
 
986
                                        var p = (Parameter)parameters.FixedParameters[i];
 
987
                                        DomParameter parameter = new DomParameter ();
 
988
                                        parameter.Name = ConvertQuoted (p.Name);
 
989
                                        parameter.Location = Convert (p.Location);
 
990
                                        parameter.ReturnType = ConvertReturnType (p.TypeExpression);
 
991
                                        var modifiers = MonoDevelop.Projects.Dom.ParameterModifiers.None;
 
992
                                        if ((p.ParameterModifier & Parameter.Modifier.OUT) == Parameter.Modifier.OUT)
 
993
                                                modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.Out;
 
994
                                        if ((p.ParameterModifier & Parameter.Modifier.REF) == Parameter.Modifier.REF)
 
995
                                                modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.Ref;
 
996
                                        if ((p.ParameterModifier & Parameter.Modifier.PARAMS) == Parameter.Modifier.PARAMS)
 
997
                                                modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.Params;
 
998
                                        if ((p.ParameterModifier & Parameter.Modifier.This) == Parameter.Modifier.This)
 
999
                                                modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.This;
 
1000
                                        parameter.ParameterModifiers = modifiers;
 
1001
                                        member.Add (parameter);
 
1002
                                }
 
1003
                        }
 
1004
 
 
1005
                        public override void Visit (Indexer i)
 
1006
                        {
 
1007
                                DomProperty indexer = new DomProperty ();
 
1008
                                indexer.PropertyModifier |= PropertyModifier.IsIndexer;
 
1009
                                indexer.Name = "this";
 
1010
                                indexer.Documentation = RetrieveDocumentation (i.Location.Row);
 
1011
                                indexer.Location = Convert (i.Location);
 
1012
                                indexer.GetterModifier = indexer.SetterModifier = ConvertModifiers (i.ModFlags);
 
1013
                                var location = LocationsBag.GetMemberLocation (i);
 
1014
                                if (location != null && location.Count >= 1) {
 
1015
                                        var endLoc = location.Count == 1 ? location[0] : location[1];
 
1016
                                        indexer.BodyRegion = ConvertRegion (location[0], endLoc);
 
1017
                                } else {
 
1018
                                        indexer.BodyRegion = DomRegion.Empty;
 
1019
                                }
 
1020
                                
 
1021
                                indexer.ReturnType = ConvertReturnType (i.TypeName);
 
1022
                                AddParameter (indexer, i.ParameterInfo);
 
1023
                                
 
1024
                                AddAttributes (indexer, i.OptAttributes, i);
 
1025
                                AddExplicitInterfaces (indexer, i);
 
1026
                                
 
1027
                                if (i.Get != null) {
 
1028
                                        indexer.PropertyModifier |= PropertyModifier.HasGet;
 
1029
                                        if ((i.Get.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
 
1030
                                                indexer.GetterModifier = ConvertModifiers (i.Get.ModFlags);
 
1031
                                        if (i.Get.Block != null) {
 
1032
                                                indexer.GetRegion = ConvertRegion (i.Get.Location, i.Get.Block.EndLocation);
 
1033
                                        } else {
 
1034
                                                var getLocation = LocationsBag.GetMemberLocation (i.Get);
 
1035
                                                indexer.GetRegion = ConvertRegion (i.Get.Location, getLocation.Count > 0 ? getLocation[0] : i.Get.Location);
 
1036
                                        }
 
1037
                                }
 
1038
                                
 
1039
                                if (i.Set != null) {
 
1040
                                        indexer.PropertyModifier |= PropertyModifier.HasSet;
 
1041
                                        if ((i.Set.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
 
1042
                                                indexer.SetterModifier = ConvertModifiers (i.Set.ModFlags);
 
1043
                                        if (i.Set.Block != null) {
 
1044
                                                indexer.SetRegion = ConvertRegion (i.Set.Location, i.Set.Block.EndLocation);
 
1045
                                        } else {
 
1046
                                                var setLocation = LocationsBag.GetMemberLocation (i.Set);
 
1047
                                                indexer.SetRegion = ConvertRegion (i.Set.Location, setLocation.Count > 0 ? setLocation[0] : i.Set.Location);
 
1048
                                        }
 
1049
                                }
 
1050
                                indexer.DeclaringType = typeStack.Peek ();
 
1051
                                typeStack.Peek ().Add (indexer);
 
1052
                        }
 
1053
 
 
1054
                        public override void Visit (Method m)
 
1055
                        {
 
1056
                                DomMethod method = new DomMethod ();
 
1057
                                method.Name = ConvertQuoted (m.MemberName.Name);
 
1058
                                method.Documentation = RetrieveDocumentation (m.Location.Row);
 
1059
                                method.Location = Convert (m.MemberName.Location);
 
1060
                                method.Modifiers = ConvertModifiers (m.ModFlags);
 
1061
                                if (m.Block != null) {
 
1062
                                        var location = LocationsBag.GetMemberLocation (m);
 
1063
                                        var region = ConvertRegion (location != null ? location[1] : m.Block.StartLocation, m.Block.EndLocation);
 
1064
                                        if (location != null)
 
1065
                                                region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
 
1066
                                        method.BodyRegion = region;
 
1067
                                }
 
1068
                                
 
1069
                                method.ReturnType = ConvertReturnType (m.TypeName);
 
1070
                                AddAttributes (method, m.OptAttributes, m);
 
1071
                                AddParameter (method, m.ParameterInfo);
 
1072
                                AddExplicitInterfaces (method, m);
 
1073
                                method.Modifiers = ConvertModifiers (m.ModFlags);
 
1074
                                if (method.IsStatic && method.Parameters.Count > 0 && method.Parameters[0].ParameterModifiers == ParameterModifiers.This)
 
1075
                                        method.MethodModifier |= MethodModifier.IsExtension;
 
1076
                                if (m.GenericMethod != null)
 
1077
                                        AddTypeParameter (method, m.GenericMethod);
 
1078
                                method.DeclaringType = typeStack.Peek ();
 
1079
                                typeStack.Peek ().Add (method);
 
1080
                        }
 
1081
 
 
1082
                        public override void Visit (Operator o)
 
1083
                        {
 
1084
                                DomMethod method = new DomMethod ();
 
1085
                                method.Name = ConvertQuoted (o.MemberName.Name);
 
1086
                                method.Documentation = RetrieveDocumentation (o.Location.Row);
 
1087
                                method.Location = Convert (o.MemberName.Location);
 
1088
                                method.Modifiers = ConvertModifiers (o.ModFlags);
 
1089
                                if (o.Block != null) {
 
1090
                                        var location = LocationsBag.GetMemberLocation (o);
 
1091
                                        var region = ConvertRegion (location != null ? location[1] : o.Block.StartLocation, o.Block.EndLocation);
 
1092
                                        if (location != null)
 
1093
                                                region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
 
1094
                                        method.BodyRegion = region;
 
1095
                                }
 
1096
                                method.Modifiers = ConvertModifiers (o.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.SpecialName;
 
1097
                                method.ReturnType = ConvertReturnType (o.TypeName);
 
1098
                                AddAttributes (method, o.OptAttributes, o);
 
1099
                                AddParameter (method, o.ParameterInfo);
 
1100
                                AddExplicitInterfaces (method, o);
 
1101
                                
 
1102
                                method.DeclaringType = typeStack.Peek ();
 
1103
                                typeStack.Peek ().Add (method);
 
1104
                        }
 
1105
 
 
1106
                        public override void Visit (Constructor c)
 
1107
                        {
 
1108
                                DomMethod method = new DomMethod ();
 
1109
                                method.Name = ".ctor";
 
1110
                                method.Documentation = RetrieveDocumentation (c.Location.Row);
 
1111
                                method.Location = Convert (c.MemberName.Location);
 
1112
                                method.Modifiers = ConvertModifiers (c.ModFlags);
 
1113
                                if (c.Block != null) {
 
1114
                                        var location = LocationsBag.GetMemberLocation (c);
 
1115
                                        var region = ConvertRegion (location != null ? location[1] : c.Block.StartLocation, c.Block.EndLocation);
 
1116
                                        if (location != null)
 
1117
                                                region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
 
1118
                                        method.BodyRegion = region;
 
1119
                                }
 
1120
                                method.Modifiers = ConvertModifiers (c.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.SpecialName;
 
1121
                                method.MethodModifier |= MethodModifier.IsConstructor;
 
1122
                                AddAttributes (method, c.OptAttributes, c);
 
1123
                                AddParameter (method, c.ParameterInfo);
 
1124
                                AddExplicitInterfaces (method, c);
 
1125
                                method.DeclaringType = typeStack.Peek ();
 
1126
                                typeStack.Peek ().Add (method);
 
1127
                        }
 
1128
 
 
1129
                        public override void Visit (Destructor d)
 
1130
                        {
 
1131
                                DomMethod method = new DomMethod ();
 
1132
                                method.Name = ".dtor";
 
1133
                                method.Documentation = RetrieveDocumentation (d.Location.Row);
 
1134
                                method.Location = Convert (d.MemberName.Location);
 
1135
                                if (d.Block != null) {
 
1136
                                        var location = LocationsBag.GetMemberLocation (d);
 
1137
                                        var region = ConvertRegion (location != null ? location[1] : d.Block.StartLocation, d.Block.EndLocation);
 
1138
                                        if (location != null)
 
1139
                                                region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
 
1140
                                        method.BodyRegion = region;
 
1141
                                }
 
1142
                                method.Modifiers = ConvertModifiers (d.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.SpecialName;
 
1143
                                method.MethodModifier |= MethodModifier.IsFinalizer;
 
1144
                                AddAttributes (method, d.OptAttributes, d);
 
1145
                                AddExplicitInterfaces (method, d);
 
1146
                                method.DeclaringType = typeStack.Peek ();
 
1147
                                typeStack.Peek ().Add (method);
 
1148
                        }
 
1149
                        
 
1150
                        public override void Visit (EnumMember f)
 
1151
                        {
 
1152
                                DomField field = new DomField ();
 
1153
                                field.Name = ConvertQuoted (f.MemberName.Name);
 
1154
                                field.Documentation = RetrieveDocumentation (f.Location.Row);
 
1155
                                // return types for enum fields are == null
 
1156
                                field.Location = Convert (f.MemberName.Location);
 
1157
                                field.Modifiers = MonoDevelop.Projects.Dom.Modifiers.Const | MonoDevelop.Projects.Dom.Modifiers.SpecialName| MonoDevelop.Projects.Dom.Modifiers.Public;
 
1158
                                AddAttributes (field, f.OptAttributes, f);
 
1159
                                field.DeclaringType = typeStack.Peek ();
 
1160
                                typeStack.Peek ().Add (field);
 
1161
                        }
 
1162
                        #endregion
 
1163
                }
 
1164
        }
 
1165
}