~ubuntu-branches/ubuntu/natty/monodevelop/natty

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2010-01-07 19:06:58 UTC
  • mto: (1.6.1 upstream)
  • mto: This revision was merged to the branch mainline in revision 46.
  • Revision ID: james.westby@ubuntu.com-20100107190658-z9z95lgk4kwfes7p
ImportĀ upstreamĀ versionĀ 2.2+dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// NRefactoryParser.cs
 
3
//
 
4
// Author:
 
5
//   Mike KrĆ¼ger <mkrueger@novell.com>
 
6
//
 
7
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
 
8
//
 
9
// Permission is hereby granted, free of charge, to any person obtaining
 
10
// a copy of this software and associated documentation files (the
 
11
// "Software"), to deal in the Software without restriction, including
 
12
// without limitation the rights to use, copy, modify, merge, publish,
 
13
// distribute, sublicense, and/or sell copies of the Software, and to
 
14
// permit persons to whom the Software is furnished to do so, subject to
 
15
// the following conditions:
 
16
// 
 
17
// The above copyright notice and this permission notice shall be
 
18
// included in all copies or substantial portions of the Software.
 
19
// 
 
20
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 
21
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 
22
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 
23
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 
24
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 
25
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 
26
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
27
//
 
28
 
 
29
using System;
 
30
using System.Collections;
 
31
using System.Collections.Generic;
 
32
using System.IO;
 
33
using System.Text;
 
34
using System.CodeDom;
 
35
using MonoDevelop.Projects;
 
36
using MonoDevelop.Projects.Dom;
 
37
using MonoDevelop.Projects.Dom.Parser;
 
38
using MonoDevelop.Refactoring;
 
39
using ICSharpCode.NRefactory.Visitors;
 
40
using ICSharpCode.NRefactory;
 
41
using MonoDevelop.CSharp.Resolver;
 
42
using MonoDevelop.CSharp.Project;
 
43
 
 
44
namespace MonoDevelop.CSharp.Parser
 
45
{
 
46
        public class NRefactoryParser : AbstractParser
 
47
        {
 
48
                public override bool CanParse (string fileName)
 
49
                {
 
50
                        return Path.GetExtension (fileName) == ".cs";
 
51
                }
 
52
 
 
53
                public NRefactoryParser () : base("C#", "text/x-csharp")
 
54
                {
 
55
                }
 
56
 
 
57
                public override IExpressionFinder CreateExpressionFinder (ProjectDom dom)
 
58
                {
 
59
                        return new NewCSharpExpressionFinder (dom);
 
60
                }
 
61
 
 
62
                public override IResolver CreateResolver (ProjectDom dom, object editor, string fileName)
 
63
                {
 
64
                        MonoDevelop.Ide.Gui.Document doc = (MonoDevelop.Ide.Gui.Document)editor;
 
65
                        return new NRefactoryResolver (dom, doc.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, doc.TextEditor, fileName);
 
66
                }
 
67
 
 
68
                class SpecialTracker : ICSharpCode.NRefactory.ISpecialVisitor
 
69
                {
 
70
                        ParsedDocument result;
 
71
 
 
72
                        public SpecialTracker (ParsedDocument result)
 
73
                        {
 
74
                                this.result = result;
 
75
                        }
 
76
 
 
77
                        public object Visit (ICSharpCode.NRefactory.ISpecial special, object data)
 
78
                        {
 
79
                                return null;
 
80
                        }
 
81
 
 
82
                        public object Visit (ICSharpCode.NRefactory.BlankLine special, object data)
 
83
                        {
 
84
                                return null;
 
85
                        }
 
86
 
 
87
                        public object Visit (ICSharpCode.NRefactory.Comment comment, object data)
 
88
                        {
 
89
                                MonoDevelop.Projects.Dom.Comment newComment = new MonoDevelop.Projects.Dom.Comment ();
 
90
                                newComment.CommentStartsLine = comment.CommentStartsLine;
 
91
                                newComment.Text = comment.CommentText;
 
92
                                int commentTagLength = comment.CommentType == ICSharpCode.NRefactory.CommentType.Documentation ? 3 : 2;
 
93
                                int commentEndOffset = comment.CommentType == ICSharpCode.NRefactory.CommentType.Block ? 0 : 1;
 
94
                                newComment.Region = new DomRegion (comment.StartPosition.Line, comment.StartPosition.Column - commentTagLength, comment.EndPosition.Line, comment.EndPosition.Column - commentEndOffset);
 
95
                                switch (comment.CommentType) {
 
96
                                case ICSharpCode.NRefactory.CommentType.Block:
 
97
                                        newComment.CommentType = MonoDevelop.Projects.Dom.CommentType.MultiLine;
 
98
                                        break;
 
99
                                case ICSharpCode.NRefactory.CommentType.Documentation:
 
100
                                        newComment.CommentType = MonoDevelop.Projects.Dom.CommentType.SingleLine;
 
101
                                        newComment.IsDocumentation = true;
 
102
                                        break;
 
103
                                default:
 
104
                                        newComment.CommentType = MonoDevelop.Projects.Dom.CommentType.SingleLine;
 
105
                                        break;
 
106
                                }
 
107
 
 
108
                                result.Add (newComment);
 
109
                                return null;
 
110
                        }
 
111
 
 
112
                        Stack<ICSharpCode.NRefactory.PreprocessingDirective> regions = new Stack<ICSharpCode.NRefactory.PreprocessingDirective> ();
 
113
                        Stack<ICSharpCode.NRefactory.PreprocessingDirective> ifBlocks = new Stack<ICSharpCode.NRefactory.PreprocessingDirective> ();
 
114
                        List<ICSharpCode.NRefactory.PreprocessingDirective> elifBlocks = new List<ICSharpCode.NRefactory.PreprocessingDirective> ();
 
115
                        ICSharpCode.NRefactory.PreprocessingDirective elseBlock = null;
 
116
 
 
117
                        Stack<ConditionalRegion> conditionalRegions = new Stack<ConditionalRegion> ();
 
118
                        ConditionalRegion ConditionalRegion {
 
119
                                get {
 
120
                                        return conditionalRegions.Count > 0 ? conditionalRegions.Peek () : null;
 
121
                                }
 
122
                        }
 
123
 
 
124
                        void CloseConditionBlock (DomLocation loc)
 
125
                        {
 
126
                                if (ConditionalRegion == null || ConditionalRegion.ConditionBlocks.Count == 0 || !ConditionalRegion.ConditionBlocks[ConditionalRegion.ConditionBlocks.Count - 1].End.IsEmpty)
 
127
                                        return;
 
128
                                ConditionalRegion.ConditionBlocks[ConditionalRegion.ConditionBlocks.Count - 1].End = loc;
 
129
                        }
 
130
 
 
131
                        void AddCurRegion (ICSharpCode.NRefactory.Location loc)
 
132
                        {
 
133
                                if (ConditionalRegion == null)
 
134
                                        return;
 
135
                                ConditionalRegion.End = new DomLocation (loc.Line, loc.Column);
 
136
                                result.Add (ConditionalRegion);
 
137
                                conditionalRegions.Pop ();
 
138
                        }
 
139
 
 
140
                        static ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor visitor = new ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor ();
 
141
 
 
142
                        public object Visit (ICSharpCode.NRefactory.PreprocessingDirective directive, object data)
 
143
                        {
 
144
                                DomLocation loc = new DomLocation (directive.StartPosition.Line, directive.StartPosition.Column);
 
145
                                switch (directive.Cmd) {
 
146
                                case "#if":
 
147
                                        directive.Expression.AcceptVisitor (visitor, null);
 
148
                                        conditionalRegions.Push (new ConditionalRegion (visitor.Text));
 
149
                                        visitor.Reset ();
 
150
                                        ifBlocks.Push (directive);
 
151
                                        ConditionalRegion.Start = loc;
 
152
                                        break;
 
153
                                case "#elif":
 
154
                                        CloseConditionBlock (new DomLocation (directive.LastLineEnd.Line, directive.LastLineEnd.Column));
 
155
                                        directive.Expression.AcceptVisitor (visitor, null);
 
156
                                        if (ConditionalRegion != null)
 
157
                                                ConditionalRegion.ConditionBlocks.Add (new ConditionBlock (visitor.Text, loc));
 
158
                                        visitor.Reset ();
 
159
                                        //                                              elifBlocks.Add (directive);
 
160
                                        break;
 
161
                                case "#else":
 
162
                                        CloseConditionBlock (new DomLocation (directive.LastLineEnd.Line, directive.LastLineEnd.Column));
 
163
                                        if (ConditionalRegion != null)
 
164
                                                ConditionalRegion.ElseBlock = new DomRegion (loc, DomLocation.Empty);
 
165
                                        //                                              elseBlock = directive;
 
166
                                        break;
 
167
                                case "#endif":
 
168
                                        DomLocation endLoc = new DomLocation (directive.LastLineEnd.Line, directive.LastLineEnd.Column);
 
169
                                        CloseConditionBlock (endLoc);
 
170
                                        if (ConditionalRegion != null && !ConditionalRegion.ElseBlock.Start.IsEmpty)
 
171
                                                ConditionalRegion.ElseBlock = new DomRegion (ConditionalRegion.ElseBlock.Start, endLoc);
 
172
                                        AddCurRegion (directive.EndPosition);
 
173
                                        if (ifBlocks.Count > 0) {
 
174
                                                ICSharpCode.NRefactory.PreprocessingDirective ifBlock = ifBlocks.Pop ();
 
175
                                                DomRegion dr = new DomRegion (ifBlock.StartPosition.Line, ifBlock.StartPosition.Column, directive.EndPosition.Line, directive.EndPosition.Column);
 
176
                                                result.Add (new FoldingRegion ("#if " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
 
177
                                                foreach (ICSharpCode.NRefactory.PreprocessingDirective d in elifBlocks) {
 
178
                                                        dr.Start = new DomLocation (d.StartPosition.Line, d.StartPosition.Column);
 
179
                                                        result.Add (new FoldingRegion ("#elif " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
 
180
                                                }
 
181
                                                if (elseBlock != null) {
 
182
                                                        dr.Start = new DomLocation (elseBlock.StartPosition.Line, elseBlock.StartPosition.Column);
 
183
                                                        result.Add (new FoldingRegion ("#else", dr, FoldType.UserRegion, false));
 
184
                                                }
 
185
                                        }
 
186
                                        elseBlock = null;
 
187
                                        break;
 
188
                                case "#define":
 
189
                                        result.Add (new PreProcessorDefine (directive.Arg, loc));
 
190
                                        break;
 
191
                                case "#region":
 
192
                                        regions.Push (directive);
 
193
                                        break;
 
194
                                case "#endregion":
 
195
                                        if (regions.Count > 0) {
 
196
                                                ICSharpCode.NRefactory.PreprocessingDirective start = regions.Pop ();
 
197
                                                DomRegion dr = new DomRegion (start.StartPosition.Line, start.StartPosition.Column, directive.EndPosition.Line, directive.EndPosition.Column);
 
198
                                                result.Add (new FoldingRegion (start.Arg, dr, FoldType.UserRegion, true));
 
199
                                        }
 
200
                                        break;
 
201
                                }
 
202
                                return null;
 
203
                        }
 
204
                }
 
205
 
 
206
                public ICSharpCode.NRefactory.Ast.CompilationUnit LastUnit {
 
207
                        get;
 
208
                        set;
 
209
                }
 
210
 
 
211
                public override ParsedDocument Parse (ProjectDom dom, string fileName, string content)
 
212
                {
 
213
                        using (ICSharpCode.NRefactory.IParser parser = ICSharpCode.NRefactory.ParserFactory.CreateParser (ICSharpCode.NRefactory.SupportedLanguage.CSharp, new StringReader (content))) {
 
214
 
 
215
                                ParsedDocument result = new ParsedDocument (fileName);
 
216
                                result.CompilationUnit = new MonoDevelop.Projects.Dom.CompilationUnit (fileName);
 
217
 
 
218
                                parser.Errors.Error += delegate(int line, int col, string message) { result.Add (new Error (ErrorType.Error, line, col, message)); };
 
219
                                parser.Lexer.SpecialCommentTags = ProjectDomService.SpecialCommentTags.GetNames ();
 
220
                                parser.Lexer.EvaluateConditionalCompilation = true;
 
221
                                if (dom != null && dom.Project != null) {
 
222
                                        DotNetProjectConfiguration conf = dom.Project.DefaultConfiguration as DotNetProjectConfiguration;
 
223
                                        CSharpCompilerParameters par = conf != null ? conf.CompilationParameters as CSharpCompilerParameters : null;
 
224
                                        if (par != null)
 
225
                                                parser.Lexer.SetConditionalCompilationSymbols (par.DefineSymbols);
 
226
                                }
 
227
                                parser.Parse ();
 
228
 
 
229
                                SpecialTracker tracker = new SpecialTracker (result);
 
230
                                foreach (ICSharpCode.NRefactory.ISpecial special in parser.Lexer.SpecialTracker.CurrentSpecials) {
 
231
                                        special.AcceptVisitor (tracker, null);
 
232
                                }
 
233
 
 
234
                                foreach (ICSharpCode.NRefactory.Parser.TagComment tagComment in parser.Lexer.TagComments) {
 
235
                                        result.Add (new Tag (tagComment.Tag, tagComment.CommentText, new DomRegion (tagComment.StartPosition.Y, tagComment.StartPosition.X, tagComment.EndPosition.Y, tagComment.EndPosition.X)));
 
236
                                }
 
237
                                ConversionVisitior visitor = new ConversionVisitior (result, parser.Lexer.SpecialTracker.CurrentSpecials);
 
238
                                visitor.VisitCompilationUnit (parser.CompilationUnit, null);
 
239
                                LastUnit = parser.CompilationUnit;
 
240
                                return result;
 
241
                        }
 
242
                }
 
243
 
 
244
                class ConversionVisitior : ICSharpCode.NRefactory.Visitors.AbstractAstVisitor
 
245
                {
 
246
                        MonoDevelop.Projects.Dom.ParsedDocument result;
 
247
                        int lastSpecial = 0;
 
248
                        List<ISpecial> specials;
 
249
                        
 
250
                        public ConversionVisitior (MonoDevelop.Projects.Dom.ParsedDocument result, List<ISpecial> specials)
 
251
                        {
 
252
                                this.specials = specials;
 
253
                                this.result = result;
 
254
                                namespaceEndLocationStack.Push (new Location (Int32.MaxValue, Int32.MaxValue));
 
255
                        }
 
256
 
 
257
                        string RetrieveDocumentation (int upToLine)
 
258
                        {
 
259
                                StringBuilder result = null;
 
260
                                while (lastSpecial < specials.Count) {
 
261
                                        ISpecial cur = specials[lastSpecial];
 
262
                                        if (cur.StartPosition.Line >= upToLine)
 
263
                                                break;
 
264
                                        ICSharpCode.NRefactory.Comment comment = cur as ICSharpCode.NRefactory.Comment;
 
265
                                        if (comment != null && comment.CommentType == ICSharpCode.NRefactory.CommentType.Documentation) {
 
266
                                                if (result == null)
 
267
                                                        result = new StringBuilder ();
 
268
                                                result.Append (comment.CommentText);
 
269
                                        }
 
270
                                        lastSpecial++;
 
271
                                }
 
272
                                return result == null ? null : result.ToString ();
 
273
                        }
 
274
                        
 
275
                        static DomRegion ConvertRegion (ICSharpCode.NRefactory.Location start, ICSharpCode.NRefactory.Location end)
 
276
                        {
 
277
                                return new DomRegion (start.Line, start.Column, end.Line, end.Column);
 
278
                        }
 
279
 
 
280
                        static DomLocation ConvertLocation (ICSharpCode.NRefactory.Location location)
 
281
                        {
 
282
                                return new DomLocation (location.Line, location.Column);
 
283
                        }
 
284
 
 
285
                        static Modifiers ConvertModifiers (ICSharpCode.NRefactory.Ast.Modifiers modifiers)
 
286
                        {
 
287
                                return (Modifiers)modifiers;
 
288
                        }
 
289
 
 
290
                        static ClassType ConvertClassType (ICSharpCode.NRefactory.Ast.ClassType nrClassType)
 
291
                        {
 
292
                                switch (nrClassType) {
 
293
                                case ICSharpCode.NRefactory.Ast.ClassType.Class:
 
294
                                        return ClassType.Class;
 
295
                                case ICSharpCode.NRefactory.Ast.ClassType.Struct:
 
296
                                        return ClassType.Struct;
 
297
                                case ICSharpCode.NRefactory.Ast.ClassType.Interface:
 
298
                                        return ClassType.Interface;
 
299
                                case ICSharpCode.NRefactory.Ast.ClassType.Enum:
 
300
                                        return ClassType.Enum;
 
301
                                }
 
302
                                return ClassType.Class;
 
303
                        }
 
304
 
 
305
                        static DomReturnType ConvertReturnType (ICSharpCode.NRefactory.Ast.TypeReference typeReference)
 
306
                        {
 
307
                                return typeReference.ConvertToReturnType ();
 
308
                        }
 
309
 
 
310
                        static void AddAttributes (AbstractMember member, IEnumerable<ICSharpCode.NRefactory.Ast.AttributeSection> attributes)
 
311
                        {
 
312
                                CodeDomVisitor domVisitor = new CodeDomVisitor ();
 
313
                                foreach (ICSharpCode.NRefactory.Ast.AttributeSection attributeSection in attributes) {
 
314
                                        foreach (ICSharpCode.NRefactory.Ast.Attribute attribute in attributeSection.Attributes) {
 
315
                                                DomAttribute domAttribute = new DomAttribute ();
 
316
                                                domAttribute.Name = attribute.Name;
 
317
                                                domAttribute.Region = ConvertRegion (attribute.StartLocation, attribute.EndLocation);
 
318
                                                member.Add (domAttribute);
 
319
                                                foreach (ICSharpCode.NRefactory.Ast.Expression exp in attribute.PositionalArguments)
 
320
                                                        domAttribute.AddPositionalArgument ((CodeExpression)exp.AcceptVisitor (domVisitor, null));
 
321
                                                foreach (ICSharpCode.NRefactory.Ast.NamedArgumentExpression nexp in attribute.NamedArguments)
 
322
                                                        domAttribute.AddNamedArgument (nexp.Name, (CodeExpression)nexp.Expression.AcceptVisitor (domVisitor, null));
 
323
                                        }
 
324
                                }
 
325
                        }
 
326
 
 
327
                        static void AddExplicitInterfaces (AbstractMember member, IEnumerable<ICSharpCode.NRefactory.Ast.InterfaceImplementation> interfaceImplementations)
 
328
                        {
 
329
                                if (interfaceImplementations == null)
 
330
                                        return;
 
331
 
 
332
                                foreach (ICSharpCode.NRefactory.Ast.InterfaceImplementation impl in interfaceImplementations) {
 
333
                                        member.AddExplicitInterface (ConvertReturnType (impl.InterfaceType));
 
334
                                }
 
335
                        }
 
336
 
 
337
                        public override object VisitUsingDeclaration (ICSharpCode.NRefactory.Ast.UsingDeclaration usingDeclaration, object data)
 
338
                        {
 
339
                                DomUsing domUsing = new DomUsing ();
 
340
                                domUsing.Region = ConvertRegion (usingDeclaration.StartLocation, usingDeclaration.EndLocation);
 
341
                                domUsing.ValidRegion = ConvertRegion (usingDeclaration.StartLocation, namespaceEndLocationStack.Peek ()); 
 
342
                                foreach (ICSharpCode.NRefactory.Ast.Using u in usingDeclaration.Usings) {
 
343
                                        if (u.IsAlias) {
 
344
                                                domUsing.Add (u.Name, ConvertReturnType (u.Alias));
 
345
                                        } else {
 
346
                                                domUsing.Add (u.Name);
 
347
                                        }
 
348
                                }
 
349
                                ((CompilationUnit)result.CompilationUnit).Add (domUsing);
 
350
                                return data;
 
351
                        }
 
352
 
 
353
                        Stack<string> namespaceStack = new Stack<string> ();
 
354
                        Stack<Location> namespaceEndLocationStack = new Stack<Location> ();
 
355
                        public override object VisitNamespaceDeclaration (ICSharpCode.NRefactory.Ast.NamespaceDeclaration namespaceDeclaration, object data)
 
356
                        {
 
357
                                string[] splittedNamespace = namespaceDeclaration.Name.Split ('.');
 
358
                                for (int i = splittedNamespace.Length; i > 0; i--) {
 
359
                                        DomUsing domUsing = new DomUsing ();
 
360
                                        domUsing.IsFromNamespace = true;
 
361
                                        domUsing.Region = ConvertRegion (namespaceDeclaration.StartLocation, namespaceDeclaration.EndLocation);
 
362
                                        domUsing.ValidRegion = domUsing.Region;
 
363
                                        domUsing.Add (String.Join (".", splittedNamespace, 0, i));
 
364
                                        ((CompilationUnit)result.CompilationUnit).Add (domUsing);
 
365
                                }
 
366
                                namespaceEndLocationStack.Push (namespaceDeclaration.EndLocation);
 
367
                                namespaceStack.Push (namespaceStack.Count == 0 ? namespaceDeclaration.Name : namespaceStack.Peek () + "." + namespaceDeclaration.Name);
 
368
                                namespaceDeclaration.AcceptChildren (this, data);
 
369
                                namespaceStack.Pop ();
 
370
                                namespaceEndLocationStack.Pop ();
 
371
                                return null;
 
372
                        }
 
373
                        
 
374
                        Stack<DomType> typeStack = new Stack<DomType> ();
 
375
                        public override object VisitTypeDeclaration (ICSharpCode.NRefactory.Ast.TypeDeclaration typeDeclaration, object data)
 
376
                        {
 
377
                                DomType newType = new DomType ();
 
378
                                newType.Name = typeDeclaration.Name;
 
379
                                newType.Documentation = RetrieveDocumentation (typeDeclaration.StartLocation.Line);
 
380
                                newType.Location = ConvertLocation (typeDeclaration.StartLocation);
 
381
                                newType.ClassType = ConvertClassType (typeDeclaration.Type);
 
382
                                DomRegion region = ConvertRegion (typeDeclaration.BodyStartLocation, typeDeclaration.EndLocation);
 
383
                                region.End = new DomLocation (region.End.Line, region.End.Column + 1);
 
384
                                newType.BodyRegion = region;
 
385
                                newType.Modifiers = ConvertModifiers (typeDeclaration.Modifier);
 
386
 
 
387
                                AddAttributes (newType, typeDeclaration.Attributes);
 
388
 
 
389
                                foreach (ICSharpCode.NRefactory.Ast.TemplateDefinition template in typeDeclaration.Templates) {
 
390
                                        TypeParameter parameter = ConvertTemplateDefinition (template);
 
391
                                        newType.AddTypeParameter (parameter);
 
392
                                }
 
393
 
 
394
                                if (typeDeclaration.BaseTypes != null) {
 
395
 
 
396
                                        foreach (ICSharpCode.NRefactory.Ast.TypeReference type in typeDeclaration.BaseTypes) {
 
397
                                                if (type == typeDeclaration.BaseTypes[0]) {
 
398
                                                        newType.BaseType = ConvertReturnType (type);
 
399
                                                } else {
 
400
                                                        newType.AddInterfaceImplementation (ConvertReturnType (type));
 
401
                                                }
 
402
                                        }
 
403
                                }
 
404
                                AddType (newType);
 
405
 
 
406
                                // visit members
 
407
                                typeStack.Push (newType);
 
408
                                typeDeclaration.AcceptChildren (this, data);
 
409
                                typeStack.Pop ();
 
410
 
 
411
                                return null;
 
412
                        }
 
413
 
 
414
                        TypeParameter ConvertTemplateDefinition (ICSharpCode.NRefactory.Ast.TemplateDefinition template)
 
415
                        {
 
416
                                TypeParameter parameter = new TypeParameter (template.Name);
 
417
                                foreach (ICSharpCode.NRefactory.Ast.TypeReference typeRef in template.Bases) {
 
418
                                        if (typeRef.Type == "constraint: struct")
 
419
                                                parameter.ValueTypeRequired = true; else if (typeRef.Type == "constraint: class")
 
420
                                                parameter.ClassRequired = true; else if (typeRef.Type == "constraint: new")
 
421
                                                parameter.ConstructorRequired = true; else {
 
422
                                                DomReturnType rt = ConvertReturnType (typeRef);
 
423
                                                parameter.AddConstraint (rt);
 
424
                                        }
 
425
                                }
 
426
                                return parameter;
 
427
                        }
 
428
 
 
429
                        void AddType (DomType type)
 
430
                        {
 
431
                                // add type to compilation unit or outer type
 
432
                                if (typeStack.Count > 0) {
 
433
                                        // Nested types are private by default
 
434
                                        if ((type.Modifiers & Modifiers.VisibilityMask) == 0)
 
435
                                                type.Modifiers |= Modifiers.Private;
 
436
                                        DomType outerType = typeStack.Peek ();
 
437
                                        type.DeclaringType = outerType;
 
438
                                        outerType.Add (type);
 
439
                                } else {
 
440
                                        // Types are internal by default
 
441
                                        if ((type.Modifiers & Modifiers.VisibilityMask) == 0)
 
442
                                                type.Modifiers |= Modifiers.Internal;
 
443
                                        if (namespaceStack.Count > 0)
 
444
                                                type.Namespace = namespaceStack.Peek ();
 
445
                                        ((CompilationUnit)result.CompilationUnit).Add (type);
 
446
                                }
 
447
                        }
 
448
 
 
449
                        static ParameterModifiers ConvertParameterModifiers (ICSharpCode.NRefactory.Ast.ParameterModifiers modifier)
 
450
                        {
 
451
                                if ((modifier & ICSharpCode.NRefactory.Ast.ParameterModifiers.Out) != 0)
 
452
                                        return ParameterModifiers.Out;
 
453
                                if ((modifier & ICSharpCode.NRefactory.Ast.ParameterModifiers.Ref) != 0)
 
454
                                        return ParameterModifiers.Ref;
 
455
                                if ((modifier & ICSharpCode.NRefactory.Ast.ParameterModifiers.Params) != 0)
 
456
                                        return ParameterModifiers.Params;
 
457
                                return ParameterModifiers.None;
 
458
                        }
 
459
 
 
460
                        static DomParameter ConvertParameter (IMember declaringMember, ICSharpCode.NRefactory.Ast.ParameterDeclarationExpression pde)
 
461
                        {
 
462
                                DomParameter result = new DomParameter ();
 
463
                                result.Name = pde.ParameterName;
 
464
                                result.Location = ConvertLocation (pde.StartLocation);
 
465
                                result.DeclaringMember = declaringMember;
 
466
                                result.ReturnType = ConvertReturnType (pde.TypeReference);
 
467
                                result.ParameterModifiers = ConvertParameterModifiers (pde.ParamModifier);
 
468
                                return result;
 
469
                        }
 
470
 
 
471
                        static List<IParameter> ConvertParameterList (IMember declaringMember, IEnumerable<ICSharpCode.NRefactory.Ast.ParameterDeclarationExpression> parameters)
 
472
                        {
 
473
                                List<IParameter> result = new List<IParameter> ();
 
474
                                if (parameters != null) {
 
475
                                        foreach (ICSharpCode.NRefactory.Ast.ParameterDeclarationExpression pde in parameters) {
 
476
                                                result.Add (ConvertParameter (declaringMember, pde));
 
477
                                        }
 
478
                                }
 
479
                                return result;
 
480
                        }
 
481
 
 
482
                        public override object VisitDelegateDeclaration (ICSharpCode.NRefactory.Ast.DelegateDeclaration delegateDeclaration, object data)
 
483
                        {
 
484
                                List<IParameter> parameter = ConvertParameterList (null, delegateDeclaration.Parameters);
 
485
                                DomType delegateType = DomType.CreateDelegate (result.CompilationUnit, delegateDeclaration.Name, ConvertLocation (delegateDeclaration.StartLocation), ConvertReturnType (delegateDeclaration.ReturnType), parameter);
 
486
                                delegateType.Documentation = RetrieveDocumentation (delegateDeclaration.StartLocation.Line);
 
487
                                delegateType.Location = ConvertLocation (delegateDeclaration.StartLocation);
 
488
                                delegateType.Modifiers = ConvertModifiers (delegateDeclaration.Modifier);
 
489
                                AddAttributes (delegateType, delegateDeclaration.Attributes);
 
490
 
 
491
                                foreach (DomParameter p in parameter) {
 
492
                                        p.DeclaringMember = delegateType;
 
493
                                }
 
494
 
 
495
                                AddType (delegateType);
 
496
 
 
497
                                return null;
 
498
                        }
 
499
 
 
500
                        public override object VisitConstructorDeclaration (ICSharpCode.NRefactory.Ast.ConstructorDeclaration constructorDeclaration, object data)
 
501
                        {
 
502
                                DomMethod constructor = new DomMethod ();
 
503
                                constructor.Documentation = RetrieveDocumentation (constructorDeclaration.StartLocation.Line);
 
504
                                constructor.Name = ".ctor";
 
505
                                constructor.MethodModifier |= MethodModifier.IsConstructor;
 
506
                                constructor.Location = ConvertLocation (constructorDeclaration.StartLocation);
 
507
                                constructor.BodyRegion = ConvertRegion (constructorDeclaration.EndLocation, constructorDeclaration.Body != null ? constructorDeclaration.Body.EndLocation : new ICSharpCode.NRefactory.Location (-1, -1));
 
508
                                constructor.Modifiers = ConvertModifiers (constructorDeclaration.Modifier);
 
509
                                AddAttributes (constructor, constructorDeclaration.Attributes);
 
510
                                constructor.Add (ConvertParameterList (constructor, constructorDeclaration.Parameters));
 
511
 
 
512
                                constructor.DeclaringType = typeStack.Peek ();
 
513
                                typeStack.Peek ().Add (constructor);
 
514
                                return null;
 
515
                        }
 
516
 
 
517
                        public override object VisitMethodDeclaration (ICSharpCode.NRefactory.Ast.MethodDeclaration methodDeclaration, object data)
 
518
                        {
 
519
                                DomMethod method = new DomMethod ();
 
520
                                method.Name = methodDeclaration.Name;
 
521
                                method.Documentation = RetrieveDocumentation (methodDeclaration.StartLocation.Line);
 
522
                                method.Location = ConvertLocation (methodDeclaration.StartLocation);
 
523
                                method.BodyRegion = ConvertRegion (methodDeclaration.EndLocation, methodDeclaration.Body != null ? methodDeclaration.Body.EndLocation : new ICSharpCode.NRefactory.Location (-1, -1));
 
524
                                method.Modifiers = ConvertModifiers (methodDeclaration.Modifier);
 
525
                                if (methodDeclaration.IsExtensionMethod)
 
526
                                        method.MethodModifier |= MethodModifier.IsExtension;
 
527
                                method.ReturnType = ConvertReturnType (methodDeclaration.TypeReference);
 
528
                                AddAttributes (method, methodDeclaration.Attributes);
 
529
                                method.Add (ConvertParameterList (method, methodDeclaration.Parameters));
 
530
                                AddExplicitInterfaces (method, methodDeclaration.InterfaceImplementations);
 
531
 
 
532
                                if (methodDeclaration.Templates != null && methodDeclaration.Templates.Count > 0) {
 
533
                                        foreach (ICSharpCode.NRefactory.Ast.TemplateDefinition template in methodDeclaration.Templates) {
 
534
                                                TypeParameter parameter = ConvertTemplateDefinition (template);
 
535
                                                method.AddTypeParameter (parameter);
 
536
                                        }
 
537
                                }
 
538
                                method.DeclaringType = typeStack.Peek ();
 
539
                                typeStack.Peek ().Add (method);
 
540
                                return null;
 
541
                        }
 
542
 
 
543
                        public override object VisitDestructorDeclaration (ICSharpCode.NRefactory.Ast.DestructorDeclaration destructorDeclaration, object data)
 
544
                        {
 
545
                                DomMethod destructor = new DomMethod ();
 
546
                                destructor.Name = ".dtor";
 
547
                                destructor.Documentation = RetrieveDocumentation (destructorDeclaration.StartLocation.Line);
 
548
                                destructor.Location = ConvertLocation (destructorDeclaration.StartLocation);
 
549
                                destructor.BodyRegion = ConvertRegion (destructorDeclaration.EndLocation, destructorDeclaration.Body != null ? destructorDeclaration.Body.EndLocation : new ICSharpCode.NRefactory.Location (-1, -1));
 
550
                                destructor.Modifiers = ConvertModifiers (destructorDeclaration.Modifier);
 
551
                                AddAttributes (destructor, destructorDeclaration.Attributes);
 
552
                                destructor.MethodModifier |= MethodModifier.IsFinalizer;
 
553
 
 
554
                                destructor.DeclaringType = typeStack.Peek ();
 
555
                                typeStack.Peek ().Add (destructor);
 
556
 
 
557
                                return null;
 
558
                        }
 
559
 
 
560
                        static string GetOperatorName (ICSharpCode.NRefactory.Ast.OperatorDeclaration operatorDeclaration)
 
561
                        {
 
562
                                if (operatorDeclaration == null)
 
563
                                        return null;
 
564
                                bool isBinary = operatorDeclaration.Parameters.Count == 2;
 
565
                                switch (operatorDeclaration.OverloadableOperator) {
 
566
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.UnaryMinus:
 
567
                                        return "op_UnaryNegation";
 
568
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.UnaryPlus:
 
569
                                        return "op_UnaryPlus";
 
570
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Add:
 
571
                                        return isBinary ? "op_Addition" : "op_UnaryPlus";
 
572
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Subtract:
 
573
                                        return isBinary ? "op_Subtraction" : "op_UnaryNegation";
 
574
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Multiply:
 
575
                                        return "op_Multiply";
 
576
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Divide:
 
577
                                        return "op_Division";
 
578
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Modulus:
 
579
                                        return "op_Modulus";
 
580
 
 
581
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Not:
 
582
                                        return "op_LogicalNot";
 
583
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.BitNot:
 
584
                                        return "op_OnesComplement";
 
585
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.BitwiseAnd:
 
586
                                        return "op_BitwiseAnd";
 
587
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.BitwiseOr:
 
588
                                        return "op_BitwiseOr";
 
589
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.ExclusiveOr:
 
590
                                        return "op_ExclusiveOr";
 
591
 
 
592
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.ShiftLeft:
 
593
                                        return "op_LeftShift";
 
594
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.ShiftRight:
 
595
                                        return "op_RightShift";
 
596
 
 
597
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.GreaterThan:
 
598
                                        return "op_GreaterThan";
 
599
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.GreaterThanOrEqual:
 
600
                                        return "op_GreaterThanOrEqual";
 
601
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Equality:
 
602
                                        return "op_Equality";
 
603
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.InEquality:
 
604
                                        return "op_Inequality";
 
605
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.LessThan:
 
606
                                        return "op_LessThan";
 
607
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.LessThanOrEqual:
 
608
                                        return "op_LessThanOrEqual";
 
609
 
 
610
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Increment:
 
611
                                        return "op_Increment";
 
612
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.Decrement:
 
613
                                        return "op_Decrement";
 
614
 
 
615
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.IsTrue:
 
616
                                        return "op_True";
 
617
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.IsFalse:
 
618
                                        return "op_False";
 
619
 
 
620
                                case ICSharpCode.NRefactory.Ast.OverloadableOperatorType.None:
 
621
                                        switch (operatorDeclaration.ConversionType) {
 
622
                                        case ICSharpCode.NRefactory.Ast.ConversionType.Implicit:
 
623
                                                return "op_Implicit";
 
624
                                        case ICSharpCode.NRefactory.Ast.ConversionType.Explicit:
 
625
                                                return "op_Explicit";
 
626
                                        }
 
627
                                        break;
 
628
                                }
 
629
                                return null;
 
630
                        }
 
631
 
 
632
                        public override object VisitOperatorDeclaration (ICSharpCode.NRefactory.Ast.OperatorDeclaration operatorDeclaration, object data)
 
633
                        {
 
634
                                DomMethod method = new DomMethod ();
 
635
                                method.Name = GetOperatorName (operatorDeclaration);
 
636
                                method.Documentation = RetrieveDocumentation (operatorDeclaration.StartLocation.Line);
 
637
                                method.Location = ConvertLocation (operatorDeclaration.StartLocation);
 
638
                                method.BodyRegion = ConvertRegion (operatorDeclaration.EndLocation, operatorDeclaration.Body != null ? operatorDeclaration.Body.EndLocation : new ICSharpCode.NRefactory.Location (-1, -1));
 
639
                                method.Modifiers = ConvertModifiers (operatorDeclaration.Modifier) | Modifiers.SpecialName;
 
640
                                if (operatorDeclaration.IsExtensionMethod)
 
641
                                        method.MethodModifier |= MethodModifier.IsExtension;
 
642
                                method.ReturnType = ConvertReturnType (operatorDeclaration.TypeReference);
 
643
                                AddAttributes (method, operatorDeclaration.Attributes);
 
644
                                method.Add (ConvertParameterList (method, operatorDeclaration.Parameters));
 
645
                                AddExplicitInterfaces (method, operatorDeclaration.InterfaceImplementations);
 
646
 
 
647
                                if (operatorDeclaration.Templates != null && operatorDeclaration.Templates.Count > 0) {
 
648
                                        foreach (ICSharpCode.NRefactory.Ast.TemplateDefinition td in operatorDeclaration.Templates) {
 
649
                                                method.AddTypeParameter (ConvertTemplateDefinition (td));
 
650
                                        }
 
651
                                }
 
652
                                method.DeclaringType = typeStack.Peek ();
 
653
                                typeStack.Peek ().Add (method);
 
654
 
 
655
                                return null;
 
656
                        }
 
657
 
 
658
                        public override object VisitFieldDeclaration (ICSharpCode.NRefactory.Ast.FieldDeclaration fieldDeclaration, object data)
 
659
                        {
 
660
                                foreach (ICSharpCode.NRefactory.Ast.VariableDeclaration varDecl in fieldDeclaration.Fields) {
 
661
                                        DomField field = new DomField ();
 
662
                                        field.Name = varDecl.Name;
 
663
                                        field.Documentation = RetrieveDocumentation (fieldDeclaration.StartLocation.Line);
 
664
                                        field.Location = ConvertLocation (fieldDeclaration.StartLocation);
 
665
                                        field.BodyRegion = ConvertRegion (varDecl.StartLocation, varDecl.EndLocation);
 
666
                                        field.Modifiers = ConvertModifiers (fieldDeclaration.Modifier);
 
667
                                        if (typeStack.Peek ().ClassType == ClassType.Enum) {
 
668
                                                field.ReturnType = new DomReturnType (typeStack.Peek ());
 
669
                                        } else {
 
670
                                                field.ReturnType = ConvertReturnType (fieldDeclaration.TypeReference);
 
671
                                        }
 
672
                                        // Enum fields have an empty type.
 
673
                                        if (field.ReturnType != null && string.IsNullOrEmpty (field.ReturnType.FullName))
 
674
                                                field.ReturnType = null;
 
675
                                        AddAttributes (field, fieldDeclaration.Attributes);
 
676
                                        field.DeclaringType = typeStack.Peek ();
 
677
                                        if (field.DeclaringType.ClassType == ClassType.Enum) {
 
678
                                                field.Modifiers |= Modifiers.Const;
 
679
                                                field.Modifiers |= Modifiers.SpecialName;
 
680
                                                field.Modifiers |= Modifiers.Public;
 
681
                                        }
 
682
                                        typeStack.Peek ().Add (field);
 
683
                                }
 
684
                                return null;
 
685
                        }
 
686
 
 
687
                        public override object VisitPropertyDeclaration (ICSharpCode.NRefactory.Ast.PropertyDeclaration propertyDeclaration, object data)
 
688
                        {
 
689
                                DomProperty property = new DomProperty ();
 
690
                                property.Name = propertyDeclaration.Name;
 
691
                                property.Documentation = RetrieveDocumentation (propertyDeclaration.StartLocation.Line);
 
692
                                property.Location = ConvertLocation (propertyDeclaration.StartLocation);
 
693
                                property.BodyRegion = ConvertRegion (propertyDeclaration.EndLocation, propertyDeclaration.BodyEnd);
 
694
                                property.Modifiers = ConvertModifiers (propertyDeclaration.Modifier);
 
695
                                property.ReturnType = ConvertReturnType (propertyDeclaration.TypeReference);
 
696
                                AddAttributes (property, propertyDeclaration.Attributes);
 
697
                                AddExplicitInterfaces (property, propertyDeclaration.InterfaceImplementations);
 
698
                                if (propertyDeclaration.HasGetRegion) {
 
699
                                        property.PropertyModifier |= PropertyModifier.HasGet;
 
700
                                        property.GetRegion = ConvertRegion (propertyDeclaration.GetRegion.StartLocation, propertyDeclaration.GetRegion.EndLocation);
 
701
                                }
 
702
                                if (propertyDeclaration.HasSetRegion) {
 
703
                                        property.PropertyModifier |= PropertyModifier.HasSet;
 
704
                                        property.SetRegion = ConvertRegion (propertyDeclaration.SetRegion.StartLocation, propertyDeclaration.SetRegion.EndLocation);
 
705
                                }
 
706
                                property.DeclaringType = typeStack.Peek ();
 
707
                                typeStack.Peek ().Add (property);
 
708
                                return null;
 
709
                        }
 
710
 
 
711
                        public override object VisitIndexerDeclaration (ICSharpCode.NRefactory.Ast.IndexerDeclaration indexerDeclaration, object data)
 
712
                        {
 
713
                                DomProperty indexer = new DomProperty ();
 
714
                                indexer.Name = "this";
 
715
                                indexer.Documentation = RetrieveDocumentation (indexerDeclaration.StartLocation.Line);
 
716
                                indexer.PropertyModifier |= PropertyModifier.IsIndexer;
 
717
                                indexer.Location = ConvertLocation (indexerDeclaration.StartLocation);
 
718
                                indexer.BodyRegion = ConvertRegion (indexerDeclaration.EndLocation, indexerDeclaration.BodyEnd);
 
719
                                indexer.Modifiers = ConvertModifiers (indexerDeclaration.Modifier);
 
720
                                indexer.ReturnType = ConvertReturnType (indexerDeclaration.TypeReference);
 
721
                                indexer.Add (ConvertParameterList (indexer, indexerDeclaration.Parameters));
 
722
 
 
723
                                AddAttributes (indexer, indexerDeclaration.Attributes);
 
724
                                AddExplicitInterfaces (indexer, indexerDeclaration.InterfaceImplementations);
 
725
 
 
726
                                if (indexerDeclaration.HasGetRegion) {
 
727
                                        indexer.PropertyModifier |= PropertyModifier.HasGet;
 
728
                                        indexer.GetRegion = ConvertRegion (indexerDeclaration.GetRegion.StartLocation, indexerDeclaration.GetRegion.EndLocation);
 
729
                                }
 
730
                                if (indexerDeclaration.HasSetRegion) {
 
731
                                        indexer.PropertyModifier |= PropertyModifier.HasSet;
 
732
                                        indexer.SetRegion = ConvertRegion (indexerDeclaration.SetRegion.StartLocation, indexerDeclaration.SetRegion.EndLocation);
 
733
                                }
 
734
                                indexer.DeclaringType = typeStack.Peek ();
 
735
                                typeStack.Peek ().Add (indexer);
 
736
                                return null;
 
737
                        }
 
738
 
 
739
                        public override object VisitEventDeclaration (ICSharpCode.NRefactory.Ast.EventDeclaration eventDeclaration, object data)
 
740
                        {
 
741
                                DomEvent evt = new DomEvent ();
 
742
                                evt.Name = eventDeclaration.Name;
 
743
                                evt.Documentation = RetrieveDocumentation (eventDeclaration.StartLocation.Line);
 
744
                                evt.Location = ConvertLocation (eventDeclaration.StartLocation);
 
745
                                evt.Modifiers = ConvertModifiers (eventDeclaration.Modifier);
 
746
                                evt.ReturnType = ConvertReturnType (eventDeclaration.TypeReference);
 
747
                                evt.BodyRegion = ConvertRegion (eventDeclaration.BodyStart, eventDeclaration.BodyEnd);
 
748
                                if (eventDeclaration.AddRegion != null && !eventDeclaration.AddRegion.IsNull) {
 
749
                                        DomMethod addMethod = new DomMethod ();
 
750
                                        addMethod.Name = "add";
 
751
                                        addMethod.BodyRegion = ConvertRegion (eventDeclaration.AddRegion.StartLocation, eventDeclaration.AddRegion.EndLocation);
 
752
                                        evt.AddMethod = addMethod;
 
753
                                }
 
754
                                if (eventDeclaration.RemoveRegion != null && !eventDeclaration.RemoveRegion.IsNull) {
 
755
                                        DomMethod removeMethod = new DomMethod ();
 
756
                                        removeMethod.Name = "remove";
 
757
                                        removeMethod.BodyRegion = ConvertRegion (eventDeclaration.RemoveRegion.StartLocation, eventDeclaration.RemoveRegion.EndLocation);
 
758
                                        evt.RemoveMethod = removeMethod;
 
759
                                }
 
760
                                AddAttributes (evt, eventDeclaration.Attributes);
 
761
                                AddExplicitInterfaces (evt, eventDeclaration.InterfaceImplementations);
 
762
                                evt.DeclaringType = typeStack.Peek ();
 
763
                                typeStack.Peek ().Add (evt);
 
764
                                return null;
 
765
                        }
 
766
                }
 
767
        }
 
768
}