Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/HeuristicLab.ExtLibs/HeuristicLab.NRefactory/5.5.0/NRefactory.CSharp-5.5.0/Parser/CSharpParser.cs @ 17578

Last change on this file since 17578 was 11700, checked in by jkarder, 10 years ago

#2077: created branch and added first version

File size: 172.9 KB
Line 
1//
2// CSharpParser.cs
3//
4// Author:
5//       Mike KrÃŒger <mkrueger@novell.com>
6//
7// Copyright (c) 2009 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.
26using System;
27using System.Linq;
28using System.Collections.Generic;
29using System.IO;
30using ICSharpCode.NRefactory.Editor;
31using Mono.CSharp;
32using ICSharpCode.NRefactory.TypeSystem;
33
34namespace ICSharpCode.NRefactory.CSharp
35{
36  public class CSharpParser
37  {
38    CompilerSettings compilerSettings;
39
40    class ConversionVisitor : StructuralVisitor
41    {
42      SyntaxTree unit = new SyntaxTree();
43      internal bool convertTypeSystemMode;
44
45      public SyntaxTree Unit {
46        get {
47          return unit;
48        }
49        set {
50          unit = value;
51        }
52      }
53
54      public LocationsBag LocationsBag {
55        get;
56        private set;
57      }
58
59      public ConversionVisitor(bool convertTypeSystemMode, LocationsBag locationsBag)
60      {
61        this.convertTypeSystemMode = convertTypeSystemMode;
62        this.LocationsBag = locationsBag;
63      }
64
65      public static TextLocation Convert(Location loc)
66      {
67        return new TextLocation(loc.Row, loc.Column);
68      }
69
70      public override void Visit(ModuleContainer mc)
71      {
72        bool first = true;
73        foreach (var container in mc.Containers) {
74          var nspace = container as NamespaceContainer;
75          if (nspace == null) {
76            container.Accept(this);
77            continue;
78          }
79          NamespaceDeclaration nDecl = null;
80          var loc = LocationsBag.GetLocations(nspace);
81         
82          if (nspace.NS != null && !string.IsNullOrEmpty(nspace.NS.Name)) {
83            nDecl = new NamespaceDeclaration();
84            if (loc != null) {
85              nDecl.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.NamespaceKeyword), Roles.NamespaceKeyword);
86            }
87            nDecl.AddChild(ConvertNamespaceName(nspace.RealMemberName), NamespaceDeclaration.NamespaceNameRole);
88            if (loc != null && loc.Count > 1) {
89              nDecl.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.LBrace), Roles.LBrace);
90            }
91            AddToNamespace(nDecl);
92            namespaceStack.Push(nDecl);
93          }
94         
95          if (nspace.Usings != null) {
96            foreach (var us in nspace.Usings) {
97              us.Accept(this);
98            }
99          }
100         
101          if (first) {
102            first = false;
103            if (mc.OptAttributes != null) {
104              foreach (var attr in mc.OptAttributes.Sections) {
105                var section = ConvertAttributeSection(attr);
106                if (section !=  null)
107                  unit.AddChild(section, SyntaxTree.MemberRole);
108              }
109            }
110          }
111         
112          if (nspace.Containers != null) {
113            foreach (var subContainer in nspace.Containers) {
114              subContainer.Accept(this);
115            }
116          }
117          if (nDecl != null) {
118            AddAttributeSection(nDecl, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
119            if (loc != null && loc.Count > 2)
120              nDecl.AddChild(new CSharpTokenNode(Convert(loc [2]), Roles.RBrace), Roles.RBrace);
121            if (loc != null && loc.Count > 3)
122              nDecl.AddChild(new CSharpTokenNode(Convert(loc [3]), Roles.Semicolon), Roles.Semicolon);
123           
124            namespaceStack.Pop();
125          } else {
126            AddAttributeSection(unit, nspace.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
127          }
128        }
129        AddAttributeSection(unit, mc.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
130      }
131
132      #region Global
133
134      readonly Stack<NamespaceDeclaration> namespaceStack = new Stack<NamespaceDeclaration>();
135
136      void AddTypeArguments(ATypeNameExpression texpr, AstType result)
137      {
138        var unbound = texpr.TypeArguments as UnboundTypeArguments;
139        if (unbound != null) {
140          var loc2 = LocationsBag.GetLocations(texpr.TypeArguments);
141          if (loc2 == null)
142            return;
143          int j = 0;
144          if (j < loc2.Count)
145            result.AddChild(new CSharpTokenNode(Convert(loc2 [j++]), Roles.LChevron), Roles.LChevron);
146          while (j < loc2.Count - 1) {
147            result.AddChild (new SimpleType (), Roles.TypeArgument);
148            result.AddChild(new CSharpTokenNode(Convert(loc2 [j++]), Roles.LChevron), Roles.Comma);
149          }
150          if (j < loc2.Count) {
151            result.AddChild (new SimpleType (), Roles.TypeArgument);
152            result.AddChild(new CSharpTokenNode(Convert(loc2 [j++]), Roles.RChevron), Roles.RChevron);
153          }
154          return;
155        }
156        if (texpr.TypeArguments == null || texpr.TypeArguments.Args == null)
157          return;
158        var loc = LocationsBag.GetLocations(texpr.TypeArguments);
159        if (loc != null && loc.Count >= 2)
160          result.AddChild(new CSharpTokenNode(Convert(loc [loc.Count - 2]), Roles.LChevron), Roles.LChevron);
161        int i = 0;
162        foreach (var arg in texpr.TypeArguments.Args) {
163          result.AddChild(ConvertToType(arg), Roles.TypeArgument);
164          if (loc != null && i < loc.Count - 2)
165            result.AddChild(new CSharpTokenNode(Convert(loc [i++]), Roles.Comma), Roles.Comma);
166        }
167        if (loc != null && loc.Count >= 2)
168          result.AddChild(new CSharpTokenNode(Convert(loc [loc.Count - 1]), Roles.RChevron), Roles.RChevron);
169      }
170
171      static AstType ConvertToType(TypeParameter spec)
172      {
173        AstType result;
174        result = new SimpleType { IdentifierToken = Identifier.Create(spec.Name, Convert(spec.Location)) };
175        return result;
176      }
177
178      AstType ConvertToType(MemberName memberName)
179      {
180        AstType result;
181        if (memberName.Left != null) {
182          result = new MemberType();
183          result.AddChild(ConvertToType(memberName.Left), MemberType.TargetRole);
184          var loc = LocationsBag.GetLocations(memberName);
185          if (loc != null)
186            result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot);
187          result.AddChild(Identifier.Create(memberName.Name, Convert(memberName.Location)), Roles.Identifier);
188        } else {
189          result = new SimpleType { IdentifierToken = Identifier.Create(memberName.Name, Convert(memberName.Location)) };
190        }
191        if (memberName.TypeParameters != null) {
192          var chevronLocs = LocationsBag.GetLocations(memberName.TypeParameters);
193          if (chevronLocs != null)
194            result.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron);
195          for (int i = 0; i < memberName.TypeParameters.Count; i++) {
196            var param = memberName.TypeParameters [i];
197            result.AddChild(new SimpleType(Identifier.Create(param.Name, Convert(param.Location))), Roles.TypeArgument);
198            if (chevronLocs != null && i < chevronLocs.Count - 2)
199              result.AddChild(new CSharpTokenNode(Convert(chevronLocs [i]), Roles.Comma), Roles.Comma);
200          }
201          if (chevronLocs != null)
202            result.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron);
203        }
204        return result;
205      }
206
207      AstType ConvertToType(Mono.CSharp.Expression typeName)
208      {
209        if (typeName == null) // may happen in typeof(Generic<,,,,>)
210          return new SimpleType();
211       
212        var typeExpr = typeName as TypeExpression;
213        if (typeExpr != null) {
214          return new PrimitiveType(typeExpr.GetSignatureForError(), Convert(typeExpr.Location));
215        }
216       
217        var qam = typeName as QualifiedAliasMember;
218        if (qam != null) {
219          var loc = LocationsBag.GetLocations(typeName);
220          var memberType = new MemberType();
221          memberType.Target = new SimpleType(qam.alias, Convert(qam.Location));
222          memberType.IsDoubleColon = true;
223
224          if (loc != null && loc.Count > 0)
225            memberType.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.DoubleColon), Roles.DoubleColon);
226
227          memberType.MemberNameToken = Identifier.Create(qam.Name, loc != null ? Convert(loc [1]) : TextLocation.Empty);
228          AddTypeArguments(qam, memberType);
229          return memberType;
230        }
231       
232        var ma = typeName as MemberAccess;
233        if (ma != null) {
234          var memberType = new MemberType();
235          memberType.AddChild(ConvertToType(ma.LeftExpression), MemberType.TargetRole);
236          var loc = LocationsBag.GetLocations(ma);
237          if (loc != null)
238            memberType.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot);
239
240          memberType.MemberNameToken = Identifier.Create(ma.Name, Convert(ma.Location));
241         
242          AddTypeArguments(ma, memberType);
243          return memberType;
244        }
245       
246        var sn = typeName as SimpleName;
247        if (sn != null) {
248          var result = new SimpleType(sn.Name, Convert(sn.Location));
249          AddTypeArguments(sn, result);
250          return result;
251        }
252       
253        var cc = typeName as ComposedCast;
254        if (cc != null) {
255          var baseType = ConvertToType(cc.Left);
256          var result = new ComposedType { BaseType = baseType };
257          var ccSpec = cc.Spec;
258          while (ccSpec != null) {
259            if (ccSpec.IsNullable) {
260              result.AddChild(new CSharpTokenNode(Convert(ccSpec.Location), ComposedType.NullableRole), ComposedType.NullableRole);
261            } else if (ccSpec.IsPointer) {
262              result.AddChild(new CSharpTokenNode(Convert(ccSpec.Location), ComposedType.PointerRole), ComposedType.PointerRole);
263            } else {
264              var location = LocationsBag.GetLocations(ccSpec);
265              var spec = new ArraySpecifier { Dimensions = ccSpec.Dimension };
266              spec.AddChild(new CSharpTokenNode(Convert(ccSpec.Location), Roles.LBracket), Roles.LBracket);
267              if (location != null)
268                spec.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.RBracket), Roles.RBracket);
269             
270              result.ArraySpecifiers.Add(spec);
271            }
272            ccSpec = ccSpec.Next;
273          }
274          return result;
275        }
276       
277        var sce = typeName as SpecialContraintExpr;
278        if (sce != null) {
279          switch (sce.Constraint) {
280            case SpecialConstraint.Class:
281              return new PrimitiveType("class", Convert(sce.Location));
282            case SpecialConstraint.Struct:
283              return new PrimitiveType("struct", Convert(sce.Location));
284            case SpecialConstraint.Constructor:
285              return new PrimitiveType("new", Convert(sce.Location));
286          }
287        }
288        return new SimpleType("unknown");
289      }
290
291      IEnumerable<Attribute> GetAttributes(IEnumerable<Mono.CSharp.Attribute> optAttributes)
292      {
293        if (optAttributes == null)
294          yield break;
295        foreach (var attr in optAttributes) {
296          var result = new Attribute();
297          result.Type = ConvertToType(attr.TypeNameExpression);
298          var loc = LocationsBag.GetLocations(attr);
299          result.HasArgumentList = loc != null;
300          int pos = 0;
301          if (loc != null)
302            result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.LPar), Roles.LPar);
303         
304          if (attr.PositionalArguments != null) {
305            foreach (var arg in attr.PositionalArguments) {
306              if (arg == null)
307                continue;
308              var na = arg as NamedArgument;
309              if (na != null) {
310                var newArg = new NamedArgumentExpression();
311                newArg.AddChild(Identifier.Create(na.Name, Convert(na.Location)), Roles.Identifier);
312               
313                var argLoc = LocationsBag.GetLocations(na);
314                if (argLoc != null)
315                  newArg.AddChild(new CSharpTokenNode(Convert(argLoc [0]), Roles.Colon), Roles.Colon);
316                if (na.Expr != null)
317                  newArg.AddChild((Expression)na.Expr.Accept(this), Roles.Expression);
318                result.AddChild(newArg, Roles.Argument);
319              } else {
320                if (arg.Expr != null)
321                  result.AddChild((Expression)arg.Expr.Accept(this), Roles.Argument);
322              }
323              if (loc != null && pos + 1 < loc.Count)
324                result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma);
325            }
326          }
327          if (attr.NamedArguments != null) {
328            foreach (var arg in attr.NamedArguments) {
329              var na = (NamedArgument)arg;
330              var newArg = new NamedExpression();
331              newArg.AddChild(Identifier.Create(na.Name, Convert(na.Location)), Roles.Identifier);
332             
333              var argLoc = LocationsBag.GetLocations(na);
334              if (argLoc != null)
335                newArg.AddChild(new CSharpTokenNode(Convert(argLoc [0]), Roles.Assign), Roles.Assign);
336              if (na.Expr != null)
337                newArg.AddChild((Expression)na.Expr.Accept(this), Roles.Expression);
338              result.AddChild(newArg, Roles.Argument);
339              if (loc != null && pos + 1 < loc.Count)
340                result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma);
341            }
342          }
343          if (loc != null && pos < loc.Count)
344            result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.RPar), Roles.RPar);
345         
346          yield return result;
347        }
348      }
349
350      AttributeSection ConvertAttributeSection(IEnumerable<Mono.CSharp.Attribute> optAttributes)
351      {
352        if (optAttributes == null)
353          return null;
354        var result = new AttributeSection();
355        var loc = LocationsBag.GetLocations(optAttributes);
356        int pos = 0;
357        if (loc != null)
358          result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.LBracket), Roles.LBracket);
359        var first = optAttributes.FirstOrDefault();
360        string target = first != null ? first.ExplicitTarget : null;
361       
362        if (!string.IsNullOrEmpty(target)) {
363          if (loc != null && pos < loc.Count - 1) {
364            result.AddChild(Identifier.Create(target, Convert(loc [pos++])), Roles.Identifier);
365          } else {
366            result.AddChild(Identifier.Create(target), Roles.Identifier);
367          }
368          if (loc != null && pos < loc.Count)
369            result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Colon), Roles.Colon);
370        }
371
372        int attributeCount = 0;
373        foreach (var attr in GetAttributes (optAttributes)) {
374          result.AddChild(attr, Roles.Attribute);
375          if (loc != null && pos + 1 < loc.Count)
376            result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma);
377
378          attributeCount++;
379        }
380        if (attributeCount == 0)
381          return null;
382        // Left and right bracket + commas between the attributes
383        int locCount = 2 + attributeCount - 1;
384        // optional comma
385        if (loc != null && pos < loc.Count - 1 && loc.Count == locCount + 1)
386          result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.Comma), Roles.Comma);
387        if (loc != null && pos < loc.Count)
388          result.AddChild(new CSharpTokenNode(Convert(loc [pos++]), Roles.RBracket), Roles.RBracket);
389        return result;
390      }
391
392      public override void Visit(NamespaceContainer ns)
393      {
394        NamespaceDeclaration nDecl = null;
395        var loc = LocationsBag.GetLocations(ns);
396        // <invalid> is caused by the parser - see Bug 12383 - [AST] Non existing namespaces generated
397        if (ns.NS != null && !string.IsNullOrEmpty(ns.NS.Name) && !ns.NS.Name.EndsWith("<invalid>", StringComparison.Ordinal)) {
398          nDecl = new NamespaceDeclaration();
399          if (loc != null) {
400            nDecl.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.NamespaceKeyword), Roles.NamespaceKeyword);
401          }
402          nDecl.AddChild(ConvertNamespaceName(ns.RealMemberName), NamespaceDeclaration.NamespaceNameRole);
403          if (loc != null && loc.Count > 1) {
404            nDecl.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.LBrace), Roles.LBrace);
405          }
406
407          AddToNamespace(nDecl);
408          namespaceStack.Push(nDecl);
409        }
410       
411        if (ns.Usings != null) {
412          foreach (var us in ns.Usings) {
413            us.Accept(this);
414          }
415        }
416       
417        if (ns.Containers != null) {
418          foreach (var container in ns.Containers) {
419            container.Accept(this);
420          }
421        }
422       
423        if (nDecl != null) {
424          AddAttributeSection(nDecl, ns.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
425          if (loc != null && loc.Count > 2)
426            nDecl.AddChild(new CSharpTokenNode(Convert(loc [2]), Roles.RBrace), Roles.RBrace);
427          if (loc != null && loc.Count > 3)
428            nDecl.AddChild(new CSharpTokenNode(Convert(loc [3]), Roles.Semicolon), Roles.Semicolon);
429         
430          namespaceStack.Pop();
431        }
432      }
433      //      public override void Visit (UsingsBag.Namespace nspace)
434      //      {
435      //
436      //
437      //        VisitNamespaceUsings (nspace);
438      //        VisitNamespaceBody (nspace);
439      //
440      //      }
441      //
442      AstType ConvertNamespaceName(MemberName memberName)
443      {
444        // HACK for a parser 'bug' - sometimes it generates "<invalid>" identifiers in namespace names (on certain bugs in the input file)
445        if (memberName.Name == "<invalid>")
446          return AstType.Null;
447        return ConvertToType(memberName);
448      }
449
450      public override void Visit(UsingNamespace un)
451      {
452        var ud = new UsingDeclaration();
453        var loc = LocationsBag.GetLocations(un);
454        ud.AddChild(new CSharpTokenNode(Convert(un.Location), UsingDeclaration.UsingKeywordRole), UsingDeclaration.UsingKeywordRole);
455        if (un.NamespaceExpression != null)
456          ud.AddChild(ConvertToType(un.NamespaceExpression), UsingDeclaration.ImportRole);
457        if (loc != null)
458          ud.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Semicolon), Roles.Semicolon);
459        AddToNamespace(ud);
460      }
461
462      public override void Visit(UsingAliasNamespace uan)
463      {
464        var ud = new UsingAliasDeclaration();
465        var loc = LocationsBag.GetLocations(uan);
466       
467        ud.AddChild(new CSharpTokenNode(Convert(uan.Location), UsingAliasDeclaration.UsingKeywordRole), UsingAliasDeclaration.UsingKeywordRole);
468        ud.AddChild(Identifier.Create(uan.Alias.Value, Convert(uan.Alias.Location)), UsingAliasDeclaration.AliasRole);
469        if (loc != null)
470          ud.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Assign), Roles.Assign);
471        if (uan.NamespaceExpression != null)
472          ud.AddChild(ConvertToType(uan.NamespaceExpression), UsingAliasDeclaration.ImportRole);
473        if (loc != null && loc.Count > 1)
474          ud.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Semicolon), Roles.Semicolon);
475        AddToNamespace(ud);
476      }
477
478      public override void Visit(UsingExternAlias uea)
479      {
480        var ud = new ExternAliasDeclaration();
481        var loc = LocationsBag.GetLocations(uea);
482        ud.AddChild(new CSharpTokenNode(Convert(uea.Location), Roles.ExternKeyword), Roles.ExternKeyword);
483        if (loc != null)
484          ud.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.AliasKeyword), Roles.AliasKeyword);
485        ud.AddChild(Identifier.Create(uea.Alias.Value, Convert(uea.Alias.Location)), Roles.Identifier);
486        if (loc != null && loc.Count > 1)
487          ud.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Semicolon), Roles.Semicolon);
488        AddToNamespace(ud);
489      }
490
491      AstType ConvertImport(MemberName memberName)
492      {
493        if (memberName.Left != null) {
494          // left.name
495          var t = new MemberType();
496//          t.IsDoubleColon = memberName.IsDoubleColon;
497          t.AddChild(ConvertImport(memberName.Left), MemberType.TargetRole);
498          var loc = LocationsBag.GetLocations(memberName);
499          if (loc != null)
500            t.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot);
501         
502          t.AddChild(Identifier.Create(memberName.Name, Convert(memberName.Location)), Roles.Identifier);
503          AddTypeArguments(t, memberName);
504          return t;
505        } else {
506          var t = new SimpleType();
507          t.AddChild(Identifier.Create(memberName.Name, Convert(memberName.Location)), Roles.Identifier);
508          AddTypeArguments(t, memberName);
509          return t;
510        }
511      }
512
513      public override void Visit(MemberCore member)
514      {
515        Console.WriteLine("Unknown member:");
516        Console.WriteLine(member.GetType() + "-> Member {0}", member.GetSignatureForError());
517      }
518
519      readonly Stack<TypeDeclaration> typeStack = new Stack<TypeDeclaration>();
520
521      public override void Visit(Class c)
522      {
523        var newType = new TypeDeclaration();
524        newType.ClassType = ClassType.Class;
525        AddAttributeSection(newType, c);
526        var location = LocationsBag.GetMemberLocation(c);
527        AddModifiers(newType, location);
528        int curLoc = 0;
529        if (location != null && location.Count > 0)
530          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.ClassKeyword), Roles.ClassKeyword);
531       
532        newType.AddChild(Identifier.Create(c.MemberName.Name, Convert(c.MemberName.Location)), Roles.Identifier);
533        AddTypeParameters(newType, c.MemberName);
534       
535        if (c.TypeBaseExpressions != null) {
536          if (location != null && curLoc < location.Count)
537            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon);
538         
539          var commaLocations = LocationsBag.GetLocations(c.TypeBaseExpressions);
540          int i = 0;
541          foreach (var baseTypes in c.TypeBaseExpressions) {
542            newType.AddChild(ConvertToType(baseTypes), Roles.BaseType);
543            if (commaLocations != null && i < commaLocations.Count) {
544              newType.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
545              i++;
546            }
547          }
548        }
549       
550        AddConstraints(newType, c.CurrentTypeParameters);
551        if (location != null && curLoc < location.Count)
552          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace);
553        typeStack.Push(newType);
554        base.Visit(c);
555        AddAttributeSection(newType, c.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
556
557        if (location != null && curLoc < location.Count) {
558          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace);
559         
560          if (location != null && curLoc < location.Count)
561            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon);
562         
563        } else {
564          // parser error, set end node to max value.
565          newType.AddChild(new ErrorNode(), Roles.Error);
566        }
567        typeStack.Pop();
568        AddType(newType);
569      }
570
571      public override void Visit(Struct s)
572      {
573        var newType = new TypeDeclaration();
574        newType.ClassType = ClassType.Struct;
575        AddAttributeSection(newType, s);
576        var location = LocationsBag.GetMemberLocation(s);
577        AddModifiers(newType, location);
578        int curLoc = 0;
579        if (location != null && location.Count > 0)
580          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.StructKeyword), Roles.StructKeyword);
581        newType.AddChild(Identifier.Create(s.MemberName.Name, Convert(s.MemberName.Location)), Roles.Identifier);
582        AddTypeParameters(newType, s.MemberName);
583       
584        if (s.TypeBaseExpressions != null) {
585          if (location != null && curLoc < location.Count)
586            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon);
587          var commaLocations = LocationsBag.GetLocations(s.TypeBaseExpressions);
588          int i = 0;
589          foreach (var baseTypes in s.TypeBaseExpressions) {
590            newType.AddChild(ConvertToType(baseTypes), Roles.BaseType);
591            if (commaLocations != null && i < commaLocations.Count) {
592              newType.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
593              i++;
594            }
595          }
596        }
597       
598        AddConstraints(newType, s.CurrentTypeParameters);
599        if (location != null && curLoc < location.Count)
600          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace);
601        typeStack.Push(newType);
602        base.Visit(s);
603        if (location != null && location.Count > 2) {
604          if (location != null && curLoc < location.Count)
605            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace);
606          if (location != null && curLoc < location.Count)
607            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon);
608        } else {
609          // parser error, set end node to max value.
610          newType.AddChild(new ErrorNode(), Roles.Error);
611        }
612        typeStack.Pop();
613        AddType(newType);
614      }
615
616      public override void Visit(Interface i)
617      {
618        var newType = new TypeDeclaration();
619        newType.ClassType = ClassType.Interface;
620        AddAttributeSection(newType, i);
621        var location = LocationsBag.GetMemberLocation(i);
622        AddModifiers(newType, location);
623        int curLoc = 0;
624        if (location != null && location.Count > 0)
625          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.InterfaceKeyword), Roles.InterfaceKeyword);
626        newType.AddChild(Identifier.Create(i.MemberName.Name, Convert(i.MemberName.Location)), Roles.Identifier);
627        AddTypeParameters(newType, i.MemberName);
628       
629        if (i.TypeBaseExpressions != null) {
630          if (location != null && curLoc < location.Count)
631            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon);
632          var commaLocations = LocationsBag.GetLocations(i.TypeBaseExpressions);
633          int j = 0;
634          foreach (var baseTypes in i.TypeBaseExpressions) {
635            newType.AddChild(ConvertToType(baseTypes), Roles.BaseType);
636            if (commaLocations != null && j < commaLocations.Count) {
637              newType.AddChild(new CSharpTokenNode(Convert(commaLocations [j]), Roles.Comma), Roles.Comma);
638              j++;
639            }
640          }
641        }
642       
643        AddConstraints(newType, i.CurrentTypeParameters);
644        if (location != null && curLoc < location.Count)
645          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace);
646        typeStack.Push(newType);
647        base.Visit(i);
648        if (location != null && location.Count > 2) {
649          if (location != null && curLoc < location.Count)
650            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace);
651          if (location != null && curLoc < location.Count)
652            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon);
653        } else {
654          // parser error, set end node to max value.
655          newType.AddChild(new ErrorNode(), Roles.Error);
656        }
657        typeStack.Pop();
658        AddType(newType);
659      }
660
661      public override void Visit(Mono.CSharp.Delegate d)
662      {
663        var newDelegate = new DelegateDeclaration();
664        var location = LocationsBag.GetMemberLocation(d);
665        AddAttributeSection(newDelegate, d);
666        AddModifiers(newDelegate, location);
667        if (location != null && location.Count > 0) {
668          newDelegate.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.DelegateKeyword), Roles.DelegateKeyword);
669        }
670        if (d.ReturnType != null)
671          newDelegate.AddChild(ConvertToType(d.ReturnType), Roles.Type);
672        newDelegate.AddChild(Identifier.Create(d.MemberName.Name, Convert(d.MemberName.Location)), Roles.Identifier);
673        AddTypeParameters(newDelegate, d.MemberName);
674       
675        if (location != null && location.Count > 1)
676          newDelegate.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LPar), Roles.LPar);
677        AddParameter(newDelegate, d.Parameters);
678       
679        if (location != null && location.Count > 2) {
680          newDelegate.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar);
681        }
682        AddConstraints(newDelegate, d.CurrentTypeParameters);
683        if (location != null && location.Count > 3) {
684          newDelegate.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.Semicolon), Roles.Semicolon);
685        }
686        AddType(newDelegate);
687      }
688
689      void AddType(EntityDeclaration child)
690      {
691        if (typeStack.Count > 0) {
692          typeStack.Peek().AddChild(child, Roles.TypeMemberRole);
693        } else {
694          AddToNamespace(child);
695        }
696      }
697
698      void AddToNamespace(AstNode child)
699      {
700        if (namespaceStack.Count > 0) {
701          namespaceStack.Peek().AddChild(child, NamespaceDeclaration.MemberRole);
702        } else {
703          unit.AddChild(child, SyntaxTree.MemberRole);
704        }
705      }
706
707      public override void Visit(Mono.CSharp.Enum e)
708      {
709        var newType = new TypeDeclaration();
710        newType.ClassType = ClassType.Enum;
711        AddAttributeSection(newType, e);
712        var location = LocationsBag.GetMemberLocation(e);
713       
714        AddModifiers(newType, location);
715        int curLoc = 0;
716        if (location != null && location.Count > 0)
717          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.EnumKeyword), Roles.EnumKeyword);
718        newType.AddChild(Identifier.Create(e.MemberName.Name, Convert(e.MemberName.Location)), Roles.Identifier);
719       
720        if (e.BaseTypeExpression != null) {
721          if (location != null && curLoc < location.Count)
722            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Colon), Roles.Colon);
723          newType.AddChild(ConvertToType(e.BaseTypeExpression), Roles.BaseType);
724        }
725
726        if (location != null && curLoc < location.Count)
727          newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.LBrace), Roles.LBrace);
728        typeStack.Push(newType);
729       
730        foreach (var m in e.Members) {
731          var member = m as EnumMember;
732          if (member == null) {
733            Console.WriteLine("WARNING - ENUM MEMBER: " + m);
734            continue;
735          }
736          Visit(member);
737          if (location != null && curLoc < location.Count - 1) //last one is closing brace
738            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Comma), Roles.Comma);
739        }
740       
741        if (location != null && location.Count > 2) {
742          if (location != null && curLoc < location.Count)
743            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.RBrace), Roles.RBrace);
744          if (location != null && curLoc < location.Count)
745            newType.AddChild(new CSharpTokenNode(Convert(location [curLoc++]), Roles.Semicolon), Roles.Semicolon);
746        } else {
747          // parser error, set end node to max value.
748          newType.AddChild(new ErrorNode(), Roles.Error);
749        }
750
751        AddAttributeSection(newType, e.UnattachedAttributes, EntityDeclaration.UnattachedAttributeRole);
752        typeStack.Pop();
753        AddType(newType);
754      }
755
756      public override void Visit(EnumMember em)
757      {
758        var newField = new EnumMemberDeclaration();
759        AddAttributeSection(newField, em);
760        newField.AddChild(Identifier.Create(em.Name, Convert(em.Location)), Roles.Identifier);
761        if (em.Initializer != null) {
762          newField.AddChild(new CSharpTokenNode(Convert(em.Initializer.Location), Roles.Assign), Roles.Assign);
763          newField.AddChild((Expression)em.Initializer.Accept(this), EnumMemberDeclaration.InitializerRole);
764        }
765        //Console.WriteLine (newField.StartLocation +"-" + newField.EndLocation);
766       
767        typeStack.Peek().AddChild(newField, Roles.TypeMemberRole);
768      }
769
770      #endregion
771
772      #region Type members
773
774      public override void Visit(FixedField f)
775      {
776        var location = LocationsBag.GetMemberLocation(f);
777        int locationIdx = 0;
778       
779        var newField = new FixedFieldDeclaration();
780        AddAttributeSection(newField, f);
781        AddModifiers(newField, location);
782        if (location != null && location.Count > 0)
783          newField.AddChild(new CSharpTokenNode(Convert(location [locationIdx++]), FixedFieldDeclaration.FixedKeywordRole), FixedFieldDeclaration.FixedKeywordRole);
784
785        if (f.TypeExpression != null)
786          newField.AddChild(ConvertToType(f.TypeExpression), Roles.Type);
787       
788        var variable = new FixedVariableInitializer();
789        variable.AddChild(Identifier.Create(f.MemberName.Name, Convert(f.MemberName.Location)), Roles.Identifier);
790        if (f.Initializer != null && !f.Initializer.IsNull) {
791          variable.AddChild(new CSharpTokenNode(Convert(f.Initializer.Location), Roles.LBracket), Roles.LBracket);
792         
793          variable.AddChild((Expression)f.Initializer.Accept(this), Roles.Expression);
794          var bracketLocations = LocationsBag.GetLocations(f.Initializer);
795          if (bracketLocations != null)
796            variable.AddChild(new CSharpTokenNode(Convert(bracketLocations [0]), Roles.RBracket), Roles.RBracket);
797        }
798        newField.AddChild(variable, FixedFieldDeclaration.VariableRole);
799       
800        if (f.Declarators != null) {
801          foreach (var decl in f.Declarators) {
802            var declLoc = LocationsBag.GetLocations(decl);
803            if (declLoc != null)
804              newField.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma);
805           
806            variable = new FixedVariableInitializer();
807            variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier);
808            variable.AddChild(new CSharpTokenNode(Convert(decl.Initializer.Location), Roles.LBracket), Roles.LBracket);
809            variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
810            var bracketLocations = LocationsBag.GetLocations(decl.Initializer);
811            if (bracketLocations != null)
812              variable.AddChild(new CSharpTokenNode(Convert(bracketLocations [0]), Roles.RBracket), Roles.RBracket);
813
814            newField.AddChild(variable, FixedFieldDeclaration.VariableRole);
815          }
816        }
817        if (location != null && location.Count > locationIdx)
818          newField.AddChild(new CSharpTokenNode(Convert(location [locationIdx]), Roles.Semicolon), Roles.Semicolon);
819        typeStack.Peek().AddChild(newField, Roles.TypeMemberRole);
820       
821      }
822
823      public override void Visit(Field f)
824      {
825        var location = LocationsBag.GetMemberLocation(f);
826       
827        var newField = new FieldDeclaration();
828        AddAttributeSection(newField, f);
829        AddModifiers(newField, location);
830        newField.AddChild(ConvertToType(f.TypeExpression), Roles.Type);
831       
832        var variable = new VariableInitializer();
833        variable.AddChild(Identifier.Create(f.MemberName.Name, Convert(f.MemberName.Location)), Roles.Identifier);
834        int locationIdx = 0;
835        if (f.Initializer != null) {
836          if (location != null)
837            variable.AddChild(new CSharpTokenNode(Convert(location [locationIdx++]), Roles.Assign), Roles.Assign);
838          variable.AddChild((Expression)f.Initializer.Accept(this), Roles.Expression);
839        }
840        newField.AddChild(variable, Roles.Variable);
841        if (f.Declarators != null) {
842          foreach (var decl in f.Declarators) {
843            var declLoc = LocationsBag.GetLocations(decl);
844            if (declLoc != null)
845              newField.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma);
846           
847            variable = new VariableInitializer();
848            variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier);
849            if (decl.Initializer != null) {
850              if (declLoc != null)
851                variable.AddChild(new CSharpTokenNode(Convert(declLoc [1]), Roles.Assign), Roles.Assign);
852              variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
853            }
854            newField.AddChild(variable, Roles.Variable);
855          }
856        }
857        if (location != null && location.Count > locationIdx)
858          newField.AddChild(new CSharpTokenNode(Convert(location [locationIdx++]), Roles.Semicolon), Roles.Semicolon);
859
860        typeStack.Peek().AddChild(newField, Roles.TypeMemberRole);
861      }
862
863      public override void Visit(Const c)
864      {
865        var location = LocationsBag.GetMemberLocation(c);
866       
867        var newField = new FieldDeclaration();
868        AddAttributeSection(newField, c);
869        AddModifiers(newField, location);
870        if (location != null)
871          newField.AddChild(new CSharpModifierToken(Convert(location [0]), Modifiers.Const), EntityDeclaration.ModifierRole);
872        newField.AddChild(ConvertToType(c.TypeExpression), Roles.Type);
873       
874        var variable = new VariableInitializer();
875        variable.AddChild(Identifier.Create(c.MemberName.Name, Convert(c.MemberName.Location)), Roles.Identifier);
876       
877        if (c.Initializer != null) {
878          variable.AddChild(new CSharpTokenNode(Convert(c.Initializer.Location), Roles.Assign), Roles.Assign);
879          variable.AddChild((Expression)c.Initializer.Accept(this), Roles.Expression);
880        }
881        newField.AddChild(variable, Roles.Variable);
882        if (c.Declarators != null) {
883          foreach (var decl in c.Declarators) {
884            var declLoc = LocationsBag.GetLocations(decl);
885            if (declLoc != null)
886              newField.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma);
887           
888            variable = new VariableInitializer();
889            variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier);
890            if (decl.Initializer != null) {
891              variable.AddChild(new CSharpTokenNode(Convert(decl.Initializer.Location), Roles.Assign), Roles.Assign);
892              variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
893            }
894            newField.AddChild(variable, Roles.Variable);
895          }
896        }
897        if (location != null)
898          newField.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
899       
900        typeStack.Peek().AddChild(newField, Roles.TypeMemberRole);
901
902       
903      }
904
905      public override void Visit(Operator o)
906      {
907        var newOperator = new OperatorDeclaration();
908        newOperator.OperatorType = (OperatorType)o.OperatorType;
909       
910        var location = LocationsBag.GetMemberLocation(o);
911        AddAttributeSection(newOperator, o);
912        AddModifiers(newOperator, location);
913       
914       
915        if (o.OperatorType == Operator.OpType.Implicit) {
916          if (location != null && location.Count > 0) {
917            newOperator.AddChild(new CSharpTokenNode(Convert(location [0]), OperatorDeclaration.ImplicitRole), OperatorDeclaration.ImplicitRole);
918            if (location.Count > 1)
919              newOperator.AddChild(new CSharpTokenNode(Convert(location [1]), OperatorDeclaration.OperatorKeywordRole), OperatorDeclaration.OperatorKeywordRole);
920          }
921          newOperator.AddChild(ConvertToType(o.TypeExpression), Roles.Type);
922        } else if (o.OperatorType == Operator.OpType.Explicit) {
923          if (location != null && location.Count > 0) {
924            newOperator.AddChild(new CSharpTokenNode(Convert(location [0]), OperatorDeclaration.ExplicitRole), OperatorDeclaration.ExplicitRole);
925            if (location.Count > 1)
926              newOperator.AddChild(new CSharpTokenNode(Convert(location [1]), OperatorDeclaration.OperatorKeywordRole), OperatorDeclaration.OperatorKeywordRole);
927          }
928          newOperator.AddChild(ConvertToType(o.TypeExpression), Roles.Type);
929        } else {
930          newOperator.AddChild(ConvertToType(o.TypeExpression), Roles.Type);
931
932          if (location != null && location.Count > 0)
933            newOperator.AddChild(new CSharpTokenNode(Convert(location [0]), OperatorDeclaration.OperatorKeywordRole), OperatorDeclaration.OperatorKeywordRole);
934         
935          if (location != null && location.Count > 1) {
936            var r = OperatorDeclaration.GetRole(newOperator.OperatorType);
937            newOperator.AddChild(new CSharpTokenNode(Convert(location [1]), r), r);
938          }
939        }
940        if (location != null && location.Count > 2)
941          newOperator.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LPar), Roles.LPar);
942        AddParameter(newOperator, o.ParameterInfo);
943        if (location != null && location.Count > 3)
944          newOperator.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RPar), Roles.RPar);
945       
946        if (o.Block != null) {
947          newOperator.AddChild((BlockStatement)o.Block.Accept(this), Roles.Body);
948        } else {
949          if (location != null && location.Count >= 5)
950            newOperator.AddChild(new CSharpTokenNode(Convert(location [4]), Roles.Semicolon), Roles.Semicolon);
951        }
952        typeStack.Peek().AddChild(newOperator, Roles.TypeMemberRole);
953      }
954
955      public void AddAttributeSection(AstNode parent, Attributable a)
956      {
957        if (a == null || a.OptAttributes == null)
958          return;
959        AddAttributeSection(parent, a.OptAttributes);
960      }
961
962      public void AddAttributeSection(AstNode parent, Attributes attrs, Role<AttributeSection> role)
963      {
964        if (attrs == null)
965          return;
966        foreach (var attr in attrs.Sections) {
967          var section = ConvertAttributeSection(attr);
968          if (section == null)
969            continue;
970          parent.AddChild(section, role);
971        }
972      }
973
974      public void AddAttributeSection(AstNode parent, Attributes attrs)
975      {
976        AddAttributeSection(parent, attrs, EntityDeclaration.AttributeRole);
977      }
978
979      public override void Visit(Indexer i)
980      {
981        var newIndexer = new IndexerDeclaration();
982        AddAttributeSection(newIndexer, i);
983        var location = LocationsBag.GetMemberLocation(i);
984        AddModifiers(newIndexer, location);
985        newIndexer.AddChild(ConvertToType(i.TypeExpression), Roles.Type);
986        AddExplicitInterface(newIndexer, i.MemberName);
987        var name = i.MemberName;
988        newIndexer.AddChild(new CSharpTokenNode(Convert(name.Location), IndexerDeclaration.ThisKeywordRole), IndexerDeclaration.ThisKeywordRole);
989       
990        if (location != null && location.Count > 0)
991          newIndexer.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBracket), Roles.LBracket);
992        AddParameter(newIndexer, i.ParameterInfo);
993        if (location != null && location.Count > 1)
994          newIndexer.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBracket), Roles.RBracket);
995       
996        if (location != null && location.Count > 2)
997          newIndexer.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LBrace), Roles.LBrace);
998        if (i.Get != null) {
999          var getAccessor = new Accessor();
1000          var getLocation = LocationsBag.GetMemberLocation(i.Get);
1001          AddAttributeSection(getAccessor, i.Get);
1002          AddModifiers(getAccessor, getLocation);
1003          if (getLocation != null)
1004            getAccessor.AddChild(new CSharpTokenNode(Convert(i.Get.Location), PropertyDeclaration.GetKeywordRole), PropertyDeclaration.GetKeywordRole);
1005          if (i.Get.Block != null) {
1006            getAccessor.AddChild((BlockStatement)i.Get.Block.Accept(this), Roles.Body);
1007          } else {
1008            if (getLocation != null && getLocation.Count > 0)
1009              newIndexer.AddChild(new CSharpTokenNode(Convert(getLocation [0]), Roles.Semicolon), Roles.Semicolon);
1010          }
1011          newIndexer.AddChild(getAccessor, PropertyDeclaration.GetterRole);
1012        }
1013       
1014        if (i.Set != null) {
1015          var setAccessor = new Accessor();
1016          var setLocation = LocationsBag.GetMemberLocation(i.Set);
1017          AddAttributeSection(setAccessor, i.Set);
1018          AddModifiers(setAccessor, setLocation);
1019          if (setLocation != null)
1020            setAccessor.AddChild(new CSharpTokenNode(Convert(i.Set.Location), PropertyDeclaration.SetKeywordRole), PropertyDeclaration.SetKeywordRole);
1021         
1022          if (i.Set.Block != null) {
1023            setAccessor.AddChild((BlockStatement)i.Set.Block.Accept(this), Roles.Body);
1024          } else {
1025            if (setLocation != null && setLocation.Count > 0)
1026              newIndexer.AddChild(new CSharpTokenNode(Convert(setLocation [0]), Roles.Semicolon), Roles.Semicolon);
1027          }
1028          newIndexer.AddChild(setAccessor, PropertyDeclaration.SetterRole);
1029        }
1030       
1031        if (location != null) {
1032          if (location.Count > 3)
1033            newIndexer.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RBrace), Roles.RBrace);
1034        } else {
1035          // parser error, set end node to max value.
1036          newIndexer.AddChild(new ErrorNode(), Roles.Error);
1037        }
1038        typeStack.Peek().AddChild(newIndexer, Roles.TypeMemberRole);
1039      }
1040
1041      public override void Visit(Method m)
1042      {
1043        var newMethod = new MethodDeclaration();
1044        AddAttributeSection(newMethod, m);
1045        var location = LocationsBag.GetMemberLocation(m);
1046        AddModifiers(newMethod, location);
1047        newMethod.AddChild(ConvertToType(m.TypeExpression), Roles.Type);
1048        AddExplicitInterface(newMethod, m.MethodName);
1049        newMethod.AddChild(Identifier.Create(m.MethodName.Name, Convert(m.Location)), Roles.Identifier);
1050       
1051        AddTypeParameters(newMethod, m.MemberName);
1052       
1053        if (location != null && location.Count > 0)
1054          newMethod.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1055        AddParameter(newMethod, m.ParameterInfo);
1056       
1057        if (location != null && location.Count > 1)
1058          newMethod.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1059       
1060        AddConstraints(newMethod, m.CurrentTypeParameters);
1061       
1062        if (m.Block != null) {
1063          var bodyBlock = (BlockStatement)m.Block.Accept(this);
1064//          if (m.Block is ToplevelBlock) {
1065//            newMethod.AddChild (bodyBlock.FirstChild.NextSibling, Roles.Body);
1066//          } else {
1067          newMethod.AddChild(bodyBlock, Roles.Body);
1068//          }
1069        } else if (location != null) {
1070          if (location.Count < 3) {
1071            // parser error, set end node to max value.
1072            newMethod.AddChild(new ErrorNode(), Roles.Error);
1073          } else {
1074            newMethod.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.Semicolon), Roles.Semicolon);
1075          }
1076        }
1077        typeStack.Peek().AddChild(newMethod, Roles.TypeMemberRole);
1078      }
1079
1080      static readonly Dictionary<Mono.CSharp.Modifiers, Modifiers> modifierTable = new Dictionary<Mono.CSharp.Modifiers, Modifiers>();
1081      static readonly string[] keywordTable;
1082
1083      static ConversionVisitor()
1084      {
1085        modifierTable [Mono.CSharp.Modifiers.NEW] = Modifiers.New;
1086        modifierTable [Mono.CSharp.Modifiers.PUBLIC] = Modifiers.Public;
1087        modifierTable [Mono.CSharp.Modifiers.PROTECTED] = Modifiers.Protected;
1088        modifierTable [Mono.CSharp.Modifiers.PRIVATE] = Modifiers.Private;
1089        modifierTable [Mono.CSharp.Modifiers.INTERNAL] = Modifiers.Internal;
1090        modifierTable [Mono.CSharp.Modifiers.ABSTRACT] = Modifiers.Abstract;
1091        modifierTable [Mono.CSharp.Modifiers.VIRTUAL] = Modifiers.Virtual;
1092        modifierTable [Mono.CSharp.Modifiers.SEALED] = Modifiers.Sealed;
1093        modifierTable [Mono.CSharp.Modifiers.STATIC] = Modifiers.Static;
1094        modifierTable [Mono.CSharp.Modifiers.OVERRIDE] = Modifiers.Override;
1095        modifierTable [Mono.CSharp.Modifiers.READONLY] = Modifiers.Readonly;
1096        modifierTable [Mono.CSharp.Modifiers.PARTIAL] = Modifiers.Partial;
1097        modifierTable [Mono.CSharp.Modifiers.EXTERN] = Modifiers.Extern;
1098        modifierTable [Mono.CSharp.Modifiers.VOLATILE] = Modifiers.Volatile;
1099        modifierTable [Mono.CSharp.Modifiers.UNSAFE] = Modifiers.Unsafe;
1100        modifierTable [Mono.CSharp.Modifiers.ASYNC] = Modifiers.Async;
1101       
1102        keywordTable = new string[255];
1103        for (int i = 0; i< keywordTable.Length; i++)
1104          keywordTable [i] = "unknown";
1105       
1106        keywordTable [(int)BuiltinTypeSpec.Type.Other] = "void";
1107        keywordTable [(int)BuiltinTypeSpec.Type.String] = "string";
1108        keywordTable [(int)BuiltinTypeSpec.Type.Int] = "int";
1109        keywordTable [(int)BuiltinTypeSpec.Type.Object] = "object";
1110        keywordTable [(int)BuiltinTypeSpec.Type.Float] = "float";
1111        keywordTable [(int)BuiltinTypeSpec.Type.Double] = "double";
1112        keywordTable [(int)BuiltinTypeSpec.Type.Long] = "long";
1113        keywordTable [(int)BuiltinTypeSpec.Type.Byte] = "byte";
1114        keywordTable [(int)BuiltinTypeSpec.Type.UInt] = "uint";
1115        keywordTable [(int)BuiltinTypeSpec.Type.ULong] = "ulong";
1116        keywordTable [(int)BuiltinTypeSpec.Type.Short] = "short";
1117        keywordTable [(int)BuiltinTypeSpec.Type.UShort] = "ushort";
1118        keywordTable [(int)BuiltinTypeSpec.Type.SByte] = "sbyte";
1119        keywordTable [(int)BuiltinTypeSpec.Type.Decimal] = "decimal";
1120        keywordTable [(int)BuiltinTypeSpec.Type.Char] = "char";
1121        keywordTable [(int)BuiltinTypeSpec.Type.Bool] = "bool";
1122      }
1123
1124      static void AddModifiers(EntityDeclaration parent, LocationsBag.MemberLocations location)
1125      {
1126        if (location == null || location.Modifiers == null)
1127          return;
1128        foreach (var modifier in location.Modifiers) {
1129          Modifiers mod;
1130          if (!modifierTable.TryGetValue(modifier.Item1, out mod)) {
1131            Console.WriteLine("modifier " + modifier.Item1 + " can't be converted,");
1132          }
1133         
1134          parent.AddChild(new CSharpModifierToken(Convert(modifier.Item2), mod), EntityDeclaration.ModifierRole);
1135        }
1136      }
1137
1138      public override void Visit(Property p)
1139      {
1140        var newProperty = new PropertyDeclaration();
1141        AddAttributeSection(newProperty, p);
1142        var location = LocationsBag.GetMemberLocation(p);
1143        AddModifiers(newProperty, location);
1144        newProperty.AddChild(ConvertToType(p.TypeExpression), Roles.Type);
1145        AddExplicitInterface(newProperty, p.MemberName);
1146        newProperty.AddChild(Identifier.Create(p.MemberName.Name, Convert(p.Location)), Roles.Identifier);
1147       
1148        if (location != null && location.Count > 0)
1149          newProperty.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBrace), Roles.LBrace);
1150       
1151        Accessor getAccessor = null;
1152        if (p.Get != null) {
1153          getAccessor = new Accessor();
1154          AddAttributeSection(getAccessor, p.Get);
1155          var getLocation = LocationsBag.GetMemberLocation(p.Get);
1156          AddModifiers(getAccessor, getLocation);
1157          getAccessor.AddChild(new CSharpTokenNode(Convert(p.Get.Location), PropertyDeclaration.GetKeywordRole), PropertyDeclaration.GetKeywordRole);
1158         
1159          if (p.Get.Block != null) {
1160            getAccessor.AddChild((BlockStatement)p.Get.Block.Accept(this), Roles.Body);
1161          } else {
1162            if (getLocation != null && getLocation.Count > 0)
1163              getAccessor.AddChild(new CSharpTokenNode(Convert(getLocation [0]), Roles.Semicolon), Roles.Semicolon);
1164          }
1165        }
1166       
1167        Accessor setAccessor = null;
1168        if (p.Set != null) {
1169          setAccessor = new Accessor();
1170          AddAttributeSection(setAccessor, p.Set);
1171          var setLocation = LocationsBag.GetMemberLocation(p.Set);
1172          AddModifiers(setAccessor, setLocation);
1173          setAccessor.AddChild(new CSharpTokenNode(Convert(p.Set.Location), PropertyDeclaration.SetKeywordRole), PropertyDeclaration.SetKeywordRole);
1174         
1175          if (p.Set.Block != null) {
1176            setAccessor.AddChild((BlockStatement)p.Set.Block.Accept(this), Roles.Body);
1177          } else {
1178            if (setLocation != null && setLocation.Count > 0)
1179              setAccessor.AddChild(new CSharpTokenNode(Convert(setLocation [0]), Roles.Semicolon), Roles.Semicolon);
1180          }
1181        }
1182        if (getAccessor != null && setAccessor != null) {
1183          if (getAccessor.StartLocation < setAccessor.StartLocation) {
1184            newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole);
1185            newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole);
1186          } else {
1187            newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole);
1188            newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole);
1189          }
1190        } else {
1191          if (getAccessor != null)
1192            newProperty.AddChild(getAccessor, PropertyDeclaration.GetterRole);
1193          if (setAccessor != null)
1194            newProperty.AddChild(setAccessor, PropertyDeclaration.SetterRole);
1195        }
1196       
1197        if (location != null && location.Count > 1) {
1198          newProperty.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBrace), Roles.RBrace);
1199        } else {
1200          // parser error, set end node to max value.
1201          newProperty.AddChild(new ErrorNode(), Roles.Error);
1202        }
1203       
1204        typeStack.Peek().AddChild(newProperty, Roles.TypeMemberRole);
1205      }
1206
1207      public override void Visit(Constructor c)
1208      {
1209        var newConstructor = new ConstructorDeclaration();
1210        AddAttributeSection(newConstructor, c);
1211        var location = LocationsBag.GetMemberLocation(c);
1212        AddModifiers(newConstructor, location);
1213        newConstructor.AddChild(Identifier.Create(c.MemberName.Name, Convert(c.MemberName.Location)), Roles.Identifier);
1214        if (location != null && location.Count > 0)
1215          newConstructor.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1216       
1217        AddParameter(newConstructor, c.ParameterInfo);
1218        if (location != null && location.Count > 1)
1219          newConstructor.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1220       
1221        if (c.Initializer != null) {
1222          var initializer = new ConstructorInitializer();
1223          initializer.ConstructorInitializerType = c.Initializer is ConstructorBaseInitializer ? ConstructorInitializerType.Base : ConstructorInitializerType.This;
1224          var initializerLocation = LocationsBag.GetLocations(c.Initializer);
1225         
1226          if (initializerLocation != null)
1227            newConstructor.AddChild(new CSharpTokenNode(Convert(initializerLocation [0]), Roles.Colon), Roles.Colon);
1228         
1229          if (initializerLocation != null && initializerLocation.Count > 1) {
1230            // this and base has the same length
1231            var r = initializer.ConstructorInitializerType == ConstructorInitializerType.This ? ConstructorInitializer.ThisKeywordRole : ConstructorInitializer.BaseKeywordRole;
1232            initializer.AddChild(new CSharpTokenNode(Convert(c.Initializer.Location), r), r);
1233            initializer.AddChild(new CSharpTokenNode(Convert(initializerLocation [1]), Roles.LPar), Roles.LPar);
1234            AddArguments(initializer, c.Initializer.Arguments);
1235            initializer.AddChild(new CSharpTokenNode(Convert(initializerLocation [2]), Roles.RPar), Roles.RPar);
1236            newConstructor.AddChild(initializer, ConstructorDeclaration.InitializerRole);
1237          }
1238        }
1239       
1240        if (c.Block != null)
1241          newConstructor.AddChild((BlockStatement)c.Block.Accept(this), Roles.Body);
1242        typeStack.Peek().AddChild(newConstructor, Roles.TypeMemberRole);
1243      }
1244
1245      public override void Visit(Destructor d)
1246      {
1247        var newDestructor = new DestructorDeclaration();
1248        AddAttributeSection(newDestructor, d);
1249        var location = LocationsBag.GetMemberLocation(d);
1250        AddModifiers(newDestructor, location);
1251        if (location != null && location.Count > 0)
1252          newDestructor.AddChild(new CSharpTokenNode(Convert(location [0]), DestructorDeclaration.TildeRole), DestructorDeclaration.TildeRole);
1253        newDestructor.AddChild(Identifier.Create(d.Identifier, Convert(d.MemberName.Location)), Roles.Identifier);
1254       
1255        if (location != null && location.Count > 1) {
1256          newDestructor.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LPar), Roles.LPar);
1257         
1258          if (location.Count > 2)
1259            newDestructor.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar);
1260        }
1261       
1262        if (d.Block != null)
1263          newDestructor.AddChild((BlockStatement)d.Block.Accept(this), Roles.Body);
1264       
1265        typeStack.Peek().AddChild(newDestructor, Roles.TypeMemberRole);
1266      }
1267
1268      public override void Visit(EventField e)
1269      {
1270        var newEvent = new EventDeclaration();
1271        AddAttributeSection(newEvent, e);
1272        var location = LocationsBag.GetMemberLocation(e);
1273        int l = 0;
1274        AddModifiers(newEvent, location);
1275       
1276        if (location != null && location.Count > 0)
1277          newEvent.AddChild(new CSharpTokenNode(Convert(location [l++]), EventDeclaration.EventKeywordRole), EventDeclaration.EventKeywordRole);
1278        newEvent.AddChild(ConvertToType(e.TypeExpression), Roles.Type);
1279       
1280        var variable = new VariableInitializer();
1281        variable.AddChild(Identifier.Create(e.MemberName.Name, Convert(e.MemberName.Location)), Roles.Identifier);
1282       
1283        if (e.Initializer != null) {
1284          if (location != null && location.Count > l)
1285            variable.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.Assign), Roles.Assign);
1286          variable.AddChild((Expression)e.Initializer.Accept(this), Roles.Expression);
1287        }
1288        newEvent.AddChild(variable, Roles.Variable);
1289        if (e.Declarators != null) {
1290          foreach (var decl in e.Declarators) {
1291            var declLoc = LocationsBag.GetLocations(decl);
1292            if (declLoc != null)
1293              newEvent.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma);
1294           
1295            variable = new VariableInitializer();
1296            variable.AddChild(Identifier.Create(decl.Name.Value, Convert(decl.Name.Location)), Roles.Identifier);
1297
1298            if (decl.Initializer != null) {
1299              if (declLoc != null)
1300                variable.AddChild(new CSharpTokenNode(Convert(declLoc [1]), Roles.Assign), Roles.Assign);
1301              variable.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
1302            }
1303            newEvent.AddChild(variable, Roles.Variable);
1304          }
1305        }
1306       
1307        if (location != null && location.Count > l)
1308          newEvent.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.Semicolon), Roles.Semicolon);
1309       
1310        typeStack.Peek().AddChild(newEvent, Roles.TypeMemberRole);
1311      }
1312
1313      void AddExplicitInterface(AstNode parent, MemberName memberName)
1314      {
1315        if (memberName == null || memberName.ExplicitInterface == null)
1316          return;
1317       
1318        parent.AddChild(ConvertToType(memberName.ExplicitInterface), EntityDeclaration.PrivateImplementationTypeRole);
1319        var privateImplTypeLoc = LocationsBag.GetLocations(memberName.ExplicitInterface);
1320        if (privateImplTypeLoc != null)
1321          parent.AddChild(new CSharpTokenNode(Convert(privateImplTypeLoc [0]), Roles.Dot), Roles.Dot);
1322      }
1323
1324      public override void Visit(EventProperty ep)
1325      {
1326        var newEvent = new CustomEventDeclaration();
1327        AddAttributeSection(newEvent, ep);
1328        var location = LocationsBag.GetMemberLocation(ep);
1329        AddModifiers(newEvent, location);
1330       
1331        if (location != null && location.Count > 0)
1332          newEvent.AddChild(new CSharpTokenNode(Convert(location [0]), CustomEventDeclaration.EventKeywordRole), CustomEventDeclaration.EventKeywordRole);
1333        newEvent.AddChild(ConvertToType(ep.TypeExpression), Roles.Type);
1334       
1335        AddExplicitInterface(newEvent, ep.MemberName);
1336       
1337        newEvent.AddChild(Identifier.Create(ep.MemberName.Name, Convert(ep.Location)), Roles.Identifier);
1338
1339        if (location != null && location.Count >= 2)
1340          newEvent.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LBrace), Roles.LBrace);
1341       
1342        if (ep.Add != null) {
1343          var addAccessor = new Accessor();
1344          AddAttributeSection(addAccessor, ep.Add);
1345          var addLocation = LocationsBag.GetMemberLocation(ep.Add);
1346          AddModifiers(addAccessor, addLocation);
1347          addAccessor.AddChild(new CSharpTokenNode(Convert(ep.Add.Location), CustomEventDeclaration.AddKeywordRole), CustomEventDeclaration.AddKeywordRole);
1348          if (ep.Add.Block != null)
1349            addAccessor.AddChild((BlockStatement)ep.Add.Block.Accept(this), Roles.Body);
1350          newEvent.AddChild(addAccessor, CustomEventDeclaration.AddAccessorRole);
1351        }
1352       
1353        if (ep.Remove != null) {
1354          var removeAccessor = new Accessor();
1355          AddAttributeSection(removeAccessor, ep.Remove);
1356          var removeLocation = LocationsBag.GetMemberLocation(ep.Remove);
1357          AddModifiers(removeAccessor, removeLocation);
1358          removeAccessor.AddChild(new CSharpTokenNode(Convert(ep.Remove.Location), CustomEventDeclaration.RemoveKeywordRole), CustomEventDeclaration.RemoveKeywordRole);
1359         
1360          if (ep.Remove.Block != null)
1361            removeAccessor.AddChild((BlockStatement)ep.Remove.Block.Accept(this), Roles.Body);
1362          newEvent.AddChild(removeAccessor, CustomEventDeclaration.RemoveAccessorRole);
1363        }
1364        if (location != null && location.Count >= 3) {
1365          newEvent.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RBrace), Roles.RBrace);
1366        } else {
1367          // parser error, set end node to max value.
1368          newEvent.AddChild(new ErrorNode(), Roles.Error);
1369        }
1370       
1371        typeStack.Peek().AddChild(newEvent, Roles.TypeMemberRole);
1372      }
1373
1374      #endregion
1375
1376      #region Statements
1377
1378      public override object Visit(Mono.CSharp.Statement stmt)
1379      {
1380        Console.WriteLine("unknown statement:" + stmt);
1381        return null;
1382      }
1383
1384      public override object Visit(BlockVariable blockVariableDeclaration)
1385      {
1386        var result = new VariableDeclarationStatement();
1387        result.AddChild(ConvertToType(blockVariableDeclaration.TypeExpression), Roles.Type);
1388       
1389        var varInit = new VariableInitializer();
1390        var location = LocationsBag.GetLocations(blockVariableDeclaration);
1391        varInit.AddChild(Identifier.Create(blockVariableDeclaration.Variable.Name, Convert(blockVariableDeclaration.Variable.Location)), Roles.Identifier);
1392        if (blockVariableDeclaration.Initializer != null) {
1393          if (location != null && location.Count > 0)
1394            varInit.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Assign), Roles.Assign);
1395          varInit.AddChild((Expression)blockVariableDeclaration.Initializer.Accept(this), Roles.Expression);
1396        }
1397       
1398        result.AddChild(varInit, Roles.Variable);
1399       
1400        if (blockVariableDeclaration.Declarators != null) {
1401          foreach (var decl in blockVariableDeclaration.Declarators) {
1402            var loc = LocationsBag.GetLocations(decl);
1403            var init = new VariableInitializer();
1404            if (loc != null && loc.Count > 0)
1405              result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Comma), Roles.Comma);
1406            init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier);
1407            if (decl.Initializer != null) {
1408              if (loc != null && loc.Count > 1)
1409                init.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Assign), Roles.Assign);
1410              init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
1411            }
1412            result.AddChild(init, Roles.Variable);
1413          }
1414        }
1415        if (location != null && (blockVariableDeclaration.Initializer == null || location.Count > 1))
1416          result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.Semicolon), Roles.Semicolon);
1417        return result;
1418      }
1419
1420      public override object Visit(BlockConstant blockConstantDeclaration)
1421      {
1422        var result = new VariableDeclarationStatement();
1423       
1424        var location = LocationsBag.GetLocations(blockConstantDeclaration);
1425        if (location != null && location.Count > 0)
1426          result.AddChild(new CSharpModifierToken(Convert(location [0]), Modifiers.Const), VariableDeclarationStatement.ModifierRole);
1427       
1428        result.AddChild(ConvertToType(blockConstantDeclaration.TypeExpression), Roles.Type);
1429       
1430        var varInit = new VariableInitializer();
1431        varInit.AddChild(Identifier.Create(blockConstantDeclaration.Variable.Name, Convert(blockConstantDeclaration.Variable.Location)), Roles.Identifier);
1432        if (blockConstantDeclaration.Initializer != null) {
1433          if (location != null && location.Count > 1)
1434            varInit.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Assign), Roles.Assign);
1435          varInit.AddChild((Expression)blockConstantDeclaration.Initializer.Accept(this), Roles.Expression);
1436        }
1437       
1438        result.AddChild(varInit, Roles.Variable);
1439       
1440        if (blockConstantDeclaration.Declarators != null) {
1441          foreach (var decl in blockConstantDeclaration.Declarators) {
1442            var loc = LocationsBag.GetLocations(decl);
1443            var init = new VariableInitializer();
1444            init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier);
1445            if (decl.Initializer != null) {
1446              if (loc != null)
1447                init.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Assign), Roles.Assign);
1448              init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
1449              if (loc != null && loc.Count > 1)
1450                result.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Comma), Roles.Comma);
1451            } else {
1452              if (loc != null && loc.Count > 0)
1453                result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Comma), Roles.Comma);
1454            }
1455            result.AddChild(init, Roles.Variable);
1456          }
1457        }
1458        if (location != null) {
1459          result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.Semicolon), Roles.Semicolon);
1460        } else {
1461          // parser error, set end node to max value.
1462          result.AddChild(new ErrorNode(), Roles.Error);
1463        }
1464        return result;
1465      }
1466
1467      public override object Visit(Mono.CSharp.EmptyStatement emptyStatement)
1468      {
1469        var result = new EmptyStatement();
1470        result.Location = Convert(emptyStatement.loc);
1471        return result;
1472      }
1473
1474      public override object Visit(Mono.CSharp.ErrorExpression errorExpression)
1475      {
1476        return new ErrorExpression(Convert(errorExpression.Location));
1477      }
1478
1479      public override object Visit(EmptyExpressionStatement emptyExpressionStatement)
1480      {
1481        // Should never happen.
1482        throw new NotSupportedException();
1483      }
1484
1485      public override object Visit(If ifStatement)
1486      {
1487        var result = new IfElseStatement();
1488       
1489        var location = LocationsBag.GetLocations(ifStatement);
1490       
1491        result.AddChild(new CSharpTokenNode(Convert(ifStatement.loc), IfElseStatement.IfKeywordRole), IfElseStatement.IfKeywordRole);
1492        if (location != null)
1493          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1494        if (ifStatement.Expr != null)
1495          result.AddChild((Expression)ifStatement.Expr.Accept(this), Roles.Condition);
1496        if (location != null && location.Count > 1)
1497          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1498       
1499        if (ifStatement.TrueStatement != null)
1500          result.AddChild((Statement)ifStatement.TrueStatement.Accept(this), IfElseStatement.TrueRole);
1501       
1502        if (ifStatement.FalseStatement != null) {
1503          if (location != null && location.Count > 2)
1504            result.AddChild(new CSharpTokenNode(Convert(location [2]), IfElseStatement.ElseKeywordRole), IfElseStatement.ElseKeywordRole);
1505          result.AddChild((Statement)ifStatement.FalseStatement.Accept(this), IfElseStatement.FalseRole);
1506        }
1507       
1508        return result;
1509      }
1510
1511      public override object Visit(Do doStatement)
1512      {
1513        var result = new DoWhileStatement();
1514        var location = LocationsBag.GetLocations(doStatement);
1515        result.AddChild(new CSharpTokenNode(Convert(doStatement.loc), DoWhileStatement.DoKeywordRole), DoWhileStatement.DoKeywordRole);
1516        if (doStatement.Statement != null)
1517          result.AddChild((Statement)doStatement.Statement.Accept(this), Roles.EmbeddedStatement);
1518        if (location != null)
1519          result.AddChild(new CSharpTokenNode(Convert(location [0]), DoWhileStatement.WhileKeywordRole), DoWhileStatement.WhileKeywordRole);
1520        if (location != null && location.Count > 1)
1521          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LPar), Roles.LPar);
1522        if (doStatement.expr != null)
1523          result.AddChild((Expression)doStatement.expr.Accept(this), Roles.Condition);
1524        if (location != null && location.Count > 2) {
1525          result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar);
1526          if (location.Count > 3)
1527            result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.Semicolon), Roles.Semicolon);
1528        }
1529       
1530        return result;
1531      }
1532
1533      public override object Visit(While whileStatement)
1534      {
1535        var result = new WhileStatement();
1536        var location = LocationsBag.GetLocations(whileStatement);
1537        result.AddChild(new CSharpTokenNode(Convert(whileStatement.loc), WhileStatement.WhileKeywordRole), WhileStatement.WhileKeywordRole);
1538       
1539        if (location != null)
1540          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1541        if (whileStatement.expr != null)
1542          result.AddChild((Expression)whileStatement.expr.Accept(this), Roles.Condition);
1543        if (location != null && location.Count > 1)
1544          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1545        if (whileStatement.Statement != null)
1546          result.AddChild((Statement)whileStatement.Statement.Accept(this), Roles.EmbeddedStatement);
1547        return result;
1548      }
1549
1550      void AddStatementOrList(ForStatement forStatement, Mono.CSharp.Statement init, Role<Statement> role)
1551      {
1552        if (init == null)
1553          return;
1554        var stmtList = init as StatementList;
1555        if (stmtList != null) {
1556          foreach (var stmt in stmtList.Statements) {
1557            forStatement.AddChild((Statement)stmt.Accept(this), role);
1558          }
1559        } else if (init is Mono.CSharp.EmptyStatement) {
1560         
1561        } else {
1562          forStatement.AddChild((Statement)init.Accept(this), role);
1563        }
1564      }
1565
1566      public override object Visit(For forStatement)
1567      {
1568        var result = new ForStatement();
1569       
1570        var location = LocationsBag.GetLocations(forStatement);
1571       
1572        result.AddChild(new CSharpTokenNode(Convert(forStatement.loc), ForStatement.ForKeywordRole), ForStatement.ForKeywordRole);
1573        if (location != null)
1574          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1575       
1576        AddStatementOrList(result, forStatement.Initializer, ForStatement.InitializerRole);
1577       
1578        if (location != null && location.Count > 1)
1579          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
1580        if (forStatement.Condition != null)
1581          result.AddChild((Expression)forStatement.Condition.Accept(this), Roles.Condition);
1582        if (location != null && location.Count >= 3)
1583          result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.Semicolon), Roles.Semicolon);
1584       
1585        AddStatementOrList(result, forStatement.Iterator, ForStatement.IteratorRole);
1586       
1587        if (location != null && location.Count >= 4)
1588          result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RPar), Roles.RPar);
1589       
1590        if (forStatement.Statement != null)
1591          result.AddChild((Statement)forStatement.Statement.Accept(this), Roles.EmbeddedStatement);
1592       
1593        return result;
1594      }
1595
1596      public override object Visit(StatementExpression statementExpression)
1597      {
1598        var result = new ExpressionStatement();
1599        var expr = statementExpression.Expr.Accept(this) as Expression;
1600        if (expr != null)
1601          result.AddChild(expr, Roles.Expression);
1602        var location = LocationsBag.GetLocations(statementExpression);
1603        if (location != null)
1604          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1605        return result;
1606      }
1607
1608      public override object Visit(StatementErrorExpression errorStatement)
1609      {
1610        var result = new ExpressionStatement();
1611        var expr = errorStatement.Expr.Accept(this) as Expression;
1612        if (expr != null)
1613          result.AddChild(expr, Roles.Expression);
1614        var location = LocationsBag.GetLocations(errorStatement);
1615        if (location != null)
1616          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1617        return result;
1618      }
1619
1620      public override object Visit(InvalidStatementExpression invalidStatementExpression)
1621      {
1622        var result = new ExpressionStatement();
1623        if (invalidStatementExpression.Expression == null)
1624          return result;
1625        var expr = invalidStatementExpression.Expression.Accept(this) as Expression;
1626        if (expr != null)
1627          result.AddChild(expr, Roles.Expression);
1628        var location = LocationsBag.GetLocations(invalidStatementExpression);
1629        if (location != null)
1630          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1631        return result;
1632      }
1633
1634      public override object Visit(Return returnStatement)
1635      {
1636        var result = new ReturnStatement();
1637       
1638        result.AddChild(new CSharpTokenNode(Convert(returnStatement.loc), ReturnStatement.ReturnKeywordRole), ReturnStatement.ReturnKeywordRole);
1639        if (returnStatement.Expr != null)
1640          result.AddChild((Expression)returnStatement.Expr.Accept(this), Roles.Expression);
1641       
1642        var location = LocationsBag.GetLocations(returnStatement);
1643        if (location != null)
1644          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1645       
1646        return result;
1647      }
1648
1649      public override object Visit(Goto gotoStatement)
1650      {
1651        var result = new GotoStatement();
1652        var location = LocationsBag.GetLocations(gotoStatement);
1653        result.AddChild(new CSharpTokenNode(Convert(gotoStatement.loc), GotoStatement.GotoKeywordRole), GotoStatement.GotoKeywordRole);
1654        var loc = location != null ? Convert(location [0]) : TextLocation.Empty;
1655        result.AddChild(Identifier.Create(gotoStatement.Target, loc), Roles.Identifier);
1656        if (location != null && location.Count > 1)
1657          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
1658       
1659        return result;
1660      }
1661
1662      public override object Visit(LabeledStatement labeledStatement)
1663      {
1664        var result = new LabelStatement();
1665        result.AddChild(Identifier.Create(labeledStatement.Name, Convert(labeledStatement.loc)), Roles.Identifier);
1666        var location = LocationsBag.GetLocations(labeledStatement);
1667        if (location != null)
1668          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Colon), Roles.Colon);
1669        return result;
1670      }
1671
1672      public override object Visit(GotoDefault gotoDefault)
1673      {
1674        var result = new GotoDefaultStatement();
1675        result.AddChild(new CSharpTokenNode(Convert(gotoDefault.loc), GotoDefaultStatement.GotoKeywordRole), GotoDefaultStatement.GotoKeywordRole);
1676        var location = LocationsBag.GetLocations(gotoDefault);
1677        if (location != null) {
1678          result.AddChild(new CSharpTokenNode(Convert(location [0]), GotoDefaultStatement.DefaultKeywordRole), GotoDefaultStatement.DefaultKeywordRole);
1679          if (location.Count > 1)
1680            result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
1681        }
1682       
1683        return result;
1684      }
1685
1686      public override object Visit(GotoCase gotoCase)
1687      {
1688        var result = new GotoCaseStatement();
1689        result.AddChild(new CSharpTokenNode(Convert(gotoCase.loc), GotoCaseStatement.GotoKeywordRole), GotoCaseStatement.GotoKeywordRole);
1690       
1691        var location = LocationsBag.GetLocations(gotoCase);
1692        if (location != null)
1693          result.AddChild(new CSharpTokenNode(Convert(location [0]), GotoCaseStatement.CaseKeywordRole), GotoCaseStatement.CaseKeywordRole);
1694        if (gotoCase.Expr != null)
1695          result.AddChild((Expression)gotoCase.Expr.Accept(this), Roles.Expression);
1696        if (location != null && location.Count > 1)
1697          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
1698        return result;
1699      }
1700
1701      public override object Visit(Throw throwStatement)
1702      {
1703        var result = new ThrowStatement();
1704        var location = LocationsBag.GetLocations(throwStatement);
1705       
1706        result.AddChild(new CSharpTokenNode(Convert(throwStatement.loc), ThrowStatement.ThrowKeywordRole), ThrowStatement.ThrowKeywordRole);
1707        if (throwStatement.Expr != null)
1708          result.AddChild((Expression)throwStatement.Expr.Accept(this), Roles.Expression);
1709        if (location != null)
1710          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1711        return result;
1712      }
1713
1714      public override object Visit(Break breakStatement)
1715      {
1716        var result = new BreakStatement();
1717        var location = LocationsBag.GetLocations(breakStatement);
1718       
1719        result.AddChild(new CSharpTokenNode(Convert(breakStatement.loc), BreakStatement.BreakKeywordRole), BreakStatement.BreakKeywordRole);
1720        if (location != null)
1721          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1722        return result;
1723      }
1724
1725      public override object Visit(Continue continueStatement)
1726      {
1727        var result = new ContinueStatement();
1728        var location = LocationsBag.GetLocations(continueStatement);
1729        result.AddChild(new CSharpTokenNode(Convert(continueStatement.loc), ContinueStatement.ContinueKeywordRole), ContinueStatement.ContinueKeywordRole);
1730        if (location != null)
1731          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Semicolon), Roles.Semicolon);
1732        return result;
1733      }
1734
1735      public static bool IsLower(Location left, Location right)
1736      {
1737        return left.Row < right.Row || left.Row == right.Row && left.Column < right.Column;
1738      }
1739
1740      public UsingStatement CreateUsingStatement(Block blockStatement)
1741      {
1742        var usingResult = new UsingStatement();
1743        Mono.CSharp.Statement cur = blockStatement.Statements [0];
1744        var u = cur as Using;
1745        if (u != null) {
1746          usingResult.AddChild(new CSharpTokenNode(Convert(u.loc), UsingStatement.UsingKeywordRole), UsingStatement.UsingKeywordRole);
1747          usingResult.AddChild(new CSharpTokenNode(Convert(blockStatement.StartLocation), Roles.LPar), Roles.LPar);
1748          if (u.Variables != null) {
1749            var initializer = new VariableInitializer {
1750              NameToken = Identifier.Create(u.Variables.Variable.Name, Convert(u.Variables.Variable.Location)),
1751            };
1752           
1753            var loc = LocationsBag.GetLocations(u.Variables);
1754            if (loc != null)
1755              initializer.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Assign), Roles.Assign);
1756            if (u.Variables.Initializer != null)
1757              initializer.Initializer = u.Variables.Initializer.Accept(this) as Expression;
1758           
1759           
1760            var varDec = new VariableDeclarationStatement {
1761              Type = ConvertToType(u.Variables.TypeExpression),
1762              Variables = { initializer }
1763            };
1764           
1765            if (u.Variables.Declarators != null) {
1766              foreach (var decl in u.Variables.Declarators) {
1767                var declLoc = LocationsBag.GetLocations(decl);
1768                var init = new VariableInitializer();
1769                if (declLoc != null && declLoc.Count > 0)
1770                  varDec.AddChild(new CSharpTokenNode(Convert(declLoc [0]), Roles.Comma), Roles.Comma);
1771                init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier);
1772                if (decl.Initializer != null) {
1773                  if (declLoc != null && declLoc.Count > 1)
1774                    init.AddChild(new CSharpTokenNode(Convert(declLoc [1]), Roles.Assign), Roles.Assign);
1775                  init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
1776                }
1777                varDec.AddChild(init, Roles.Variable);
1778              }
1779            }
1780            usingResult.AddChild(varDec, UsingStatement.ResourceAcquisitionRole);
1781          }
1782          cur = u.Statement;
1783          usingResult.AddChild(new CSharpTokenNode(Convert(blockStatement.EndLocation), Roles.RPar), Roles.RPar);
1784          if (cur != null)
1785            usingResult.AddChild((Statement)cur.Accept(this), Roles.EmbeddedStatement);
1786        }
1787        return usingResult;
1788      }
1789
1790      void AddBlockChildren(BlockStatement result, Block blockStatement, ref int curLocal)
1791      {
1792        if (convertTypeSystemMode) {
1793          return;
1794        }
1795        foreach (Mono.CSharp.Statement stmt in blockStatement.Statements) {
1796          if (stmt == null)
1797            continue;
1798          /*          if (curLocal < localVariables.Count && IsLower (localVariables[curLocal].Location, stmt.loc)) {
1799            result.AddChild (CreateVariableDeclaration (localVariables[curLocal]), Roles.Statement);
1800            curLocal++;
1801          }*/
1802          if (stmt is Block && !(stmt is ToplevelBlock || stmt is ExplicitBlock)) {
1803            AddBlockChildren(result, (Block)stmt, ref curLocal);
1804          } else {
1805            result.AddChild((Statement)stmt.Accept(this), BlockStatement.StatementRole);
1806          }
1807        }
1808      }
1809
1810      public override object Visit(Block blockStatement)
1811      {
1812        if (blockStatement.IsCompilerGenerated && blockStatement.Statements.Any()) {
1813          if (blockStatement.Statements.First() is Using)
1814            return CreateUsingStatement(blockStatement);
1815          return blockStatement.Statements.Last().Accept(this);
1816        }
1817        var result = new BlockStatement();
1818        result.AddChild(new CSharpTokenNode(Convert(blockStatement.StartLocation), Roles.LBrace), Roles.LBrace);
1819        int curLocal = 0;
1820        AddBlockChildren(result, blockStatement, ref curLocal);
1821       
1822        result.AddChild(new CSharpTokenNode(Convert(blockStatement.EndLocation), Roles.RBrace), Roles.RBrace);
1823        return result;
1824      }
1825
1826      public override object Visit(Switch switchStatement)
1827      {
1828        var result = new SwitchStatement();
1829       
1830        var location = LocationsBag.GetLocations(switchStatement);
1831        result.AddChild(new CSharpTokenNode(Convert(switchStatement.loc), SwitchStatement.SwitchKeywordRole), SwitchStatement.SwitchKeywordRole);
1832        if (location != null)
1833          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1834        if (switchStatement.Expr != null)
1835          result.AddChild((Expression)switchStatement.Expr.Accept(this), Roles.Expression);
1836        if (location != null && location.Count > 1)
1837          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1838        if (location != null && location.Count > 2)
1839          result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.LBrace), Roles.LBrace);
1840        SwitchSection newSection = null;
1841        bool lastWasCase = false, added = true;
1842        if (switchStatement.Block != null) {
1843          foreach (var child in switchStatement.Block.Statements) {
1844            var statement = child.Accept(this);
1845            var caseLabel = statement as CaseLabel;
1846            if (caseLabel != null) {
1847              if (!lastWasCase) {
1848                newSection = new SwitchSection();
1849                added = false;
1850              }
1851              newSection.AddChild(caseLabel, SwitchSection.CaseLabelRole);
1852              lastWasCase = true;
1853            } else {
1854              if (lastWasCase) {
1855                result.AddChild(newSection, SwitchStatement.SwitchSectionRole);
1856                lastWasCase = false;
1857                added = true;
1858              }
1859              newSection.AddChild((Statement)statement, Roles.EmbeddedStatement);
1860            }
1861          }
1862        }
1863        if (!added)
1864          result.AddChild(newSection, SwitchStatement.SwitchSectionRole);
1865
1866        if (location != null && location.Count > 3) {
1867          result.AddChild(new CSharpTokenNode(Convert(location [3]), Roles.RBrace), Roles.RBrace);
1868        } else {
1869          // parser error, set end node to max value.
1870          result.AddChild(new ErrorNode(), Roles.Error);
1871        }
1872       
1873        return result;
1874      }
1875
1876      public override object Visit(SwitchLabel switchLabel)
1877      {
1878        var newLabel = new CaseLabel();
1879        if (!switchLabel.IsDefault) {
1880          newLabel.AddChild(new CSharpTokenNode(Convert(switchLabel.Location), CaseLabel.CaseKeywordRole), CaseLabel.CaseKeywordRole);
1881          if (switchLabel.Label != null)
1882            newLabel.AddChild((Expression)switchLabel.Label.Accept(this), Roles.Expression);
1883          var colonLocation = LocationsBag.GetLocations(switchLabel);
1884          if (colonLocation != null)
1885            newLabel.AddChild(new CSharpTokenNode(Convert(colonLocation [0]), Roles.Colon), Roles.Colon);
1886        } else {
1887          newLabel.AddChild(new CSharpTokenNode(Convert(switchLabel.Location), CaseLabel.DefaultKeywordRole), CaseLabel.DefaultKeywordRole);
1888          newLabel.AddChild(new CSharpTokenNode(new TextLocation(switchLabel.Location.Row, switchLabel.Location.Column + "default".Length), Roles.Colon), Roles.Colon);
1889        }
1890        return newLabel;
1891      }
1892
1893      public override object Visit(Lock lockStatement)
1894      {
1895        var result = new LockStatement();
1896        var location = LocationsBag.GetLocations(lockStatement);
1897        result.AddChild(new CSharpTokenNode(Convert(lockStatement.loc), LockStatement.LockKeywordRole), LockStatement.LockKeywordRole);
1898       
1899        if (location != null)
1900          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1901        if (lockStatement.Expr != null)
1902          result.AddChild((Expression)lockStatement.Expr.Accept(this), Roles.Expression);
1903       
1904        if (location != null && location.Count > 1)
1905          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1906        if (lockStatement.Statement != null)
1907          result.AddChild((Statement)lockStatement.Statement.Accept(this), Roles.EmbeddedStatement);
1908       
1909        return result;
1910      }
1911
1912      public override object Visit(Unchecked uncheckedStatement)
1913      {
1914        var result = new UncheckedStatement();
1915        result.AddChild(new CSharpTokenNode(Convert(uncheckedStatement.loc), UncheckedStatement.UncheckedKeywordRole), UncheckedStatement.UncheckedKeywordRole);
1916        if (uncheckedStatement.Block != null)
1917          result.AddChild((BlockStatement)uncheckedStatement.Block.Accept(this), Roles.Body);
1918        return result;
1919      }
1920
1921      public override object Visit(Checked checkedStatement)
1922      {
1923        var result = new CheckedStatement();
1924        result.AddChild(new CSharpTokenNode(Convert(checkedStatement.loc), CheckedStatement.CheckedKeywordRole), CheckedStatement.CheckedKeywordRole);
1925        if (checkedStatement.Block != null)
1926          result.AddChild((BlockStatement)checkedStatement.Block.Accept(this), Roles.Body);
1927        return result;
1928      }
1929
1930      public override object Visit(Unsafe unsafeStatement)
1931      {
1932        var result = new UnsafeStatement();
1933        result.AddChild(new CSharpTokenNode(Convert(unsafeStatement.loc), UnsafeStatement.UnsafeKeywordRole), UnsafeStatement.UnsafeKeywordRole);
1934        if (unsafeStatement.Block != null)
1935          result.AddChild((BlockStatement)unsafeStatement.Block.Accept(this), Roles.Body);
1936        return result;
1937      }
1938
1939      public override object Visit(Fixed fixedStatement)
1940      {
1941        var result = new FixedStatement();
1942        var location = LocationsBag.GetLocations(fixedStatement);
1943       
1944        result.AddChild(new CSharpTokenNode(Convert(fixedStatement.loc), FixedStatement.FixedKeywordRole), FixedStatement.FixedKeywordRole);
1945        if (location != null)
1946          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
1947       
1948        if (fixedStatement.Variables != null) {
1949          var blockVariableDeclaration = fixedStatement.Variables;
1950          result.AddChild(ConvertToType(blockVariableDeclaration.TypeExpression), Roles.Type);
1951          var varInit = new VariableInitializer();
1952          var initLocation = LocationsBag.GetLocations(blockVariableDeclaration);
1953          varInit.AddChild(Identifier.Create(blockVariableDeclaration.Variable.Name, Convert(blockVariableDeclaration.Variable.Location)), Roles.Identifier);
1954          if (blockVariableDeclaration.Initializer != null) {
1955            if (initLocation != null)
1956              varInit.AddChild(new CSharpTokenNode(Convert(initLocation [0]), Roles.Assign), Roles.Assign);
1957            varInit.AddChild((Expression)blockVariableDeclaration.Initializer.Accept(this), Roles.Expression);
1958          }
1959         
1960          result.AddChild(varInit, Roles.Variable);
1961         
1962          if (blockVariableDeclaration.Declarators != null) {
1963            foreach (var decl in blockVariableDeclaration.Declarators) {
1964              var loc = LocationsBag.GetLocations(decl);
1965              var init = new VariableInitializer();
1966              if (loc != null && loc.Count > 0)
1967                result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Comma), Roles.Comma);
1968              init.AddChild(Identifier.Create(decl.Variable.Name, Convert(decl.Variable.Location)), Roles.Identifier);
1969              if (decl.Initializer != null) {
1970                if (loc != null && loc.Count > 1)
1971                  init.AddChild(new CSharpTokenNode(Convert(loc [1]), Roles.Assign), Roles.Assign);
1972                init.AddChild((Expression)decl.Initializer.Accept(this), Roles.Expression);
1973              }
1974              result.AddChild(init, Roles.Variable);
1975            }
1976          }
1977        }
1978       
1979        if (location != null && location.Count > 1)
1980          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
1981        if (fixedStatement.Statement != null)
1982          result.AddChild((Statement)fixedStatement.Statement.Accept(this), Roles.EmbeddedStatement);
1983        return result;
1984      }
1985
1986      public override object Visit(TryFinally tryFinallyStatement)
1987      {
1988        TryCatchStatement result;
1989        var location = LocationsBag.GetLocations(tryFinallyStatement);
1990       
1991        if (tryFinallyStatement.Stmt is TryCatch) {
1992          result = (TryCatchStatement)tryFinallyStatement.Stmt.Accept(this);
1993        } else {
1994          result = new TryCatchStatement();
1995          result.AddChild(new CSharpTokenNode(Convert(tryFinallyStatement.loc), TryCatchStatement.TryKeywordRole), TryCatchStatement.TryKeywordRole);
1996          if (tryFinallyStatement.Stmt != null)
1997            result.AddChild((BlockStatement)tryFinallyStatement.Stmt.Accept(this), TryCatchStatement.TryBlockRole);
1998        }
1999        if (location != null)
2000          result.AddChild(new CSharpTokenNode(Convert(location [0]), TryCatchStatement.FinallyKeywordRole), TryCatchStatement.FinallyKeywordRole);
2001        if (tryFinallyStatement.Fini != null)
2002          result.AddChild((BlockStatement)tryFinallyStatement.Fini.Accept(this), TryCatchStatement.FinallyBlockRole);
2003       
2004        return result;
2005      }
2006
2007      CatchClause ConvertCatch(Catch ctch)
2008      {
2009        var result = new CatchClause();
2010        var location = LocationsBag.GetLocations(ctch);
2011        result.AddChild(new CSharpTokenNode(Convert(ctch.loc), CatchClause.CatchKeywordRole), CatchClause.CatchKeywordRole);
2012        if (ctch.TypeExpression != null) {
2013          if (location != null)
2014            result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2015         
2016          if (ctch.TypeExpression != null)
2017            result.AddChild(ConvertToType(ctch.TypeExpression), Roles.Type);
2018          if (ctch.Variable != null && !string.IsNullOrEmpty(ctch.Variable.Name))
2019            result.AddChild(Identifier.Create(ctch.Variable.Name, Convert(ctch.Variable.Location)), Roles.Identifier);
2020         
2021          if (location != null && location.Count > 1)
2022            result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2023        }
2024
2025        if (ctch.Block != null)
2026          result.AddChild((BlockStatement)ctch.Block.Accept(this), Roles.Body);
2027       
2028        return result;
2029      }
2030
2031      public override object Visit(TryCatch tryCatchStatement)
2032      {
2033        var result = new TryCatchStatement();
2034        result.AddChild(new CSharpTokenNode(Convert(tryCatchStatement.loc), TryCatchStatement.TryKeywordRole), TryCatchStatement.TryKeywordRole);
2035        if (tryCatchStatement.Block != null)
2036          result.AddChild((BlockStatement)tryCatchStatement.Block.Accept(this), TryCatchStatement.TryBlockRole);
2037        if (tryCatchStatement.Clauses != null) {
2038          foreach (var ctch in tryCatchStatement.Clauses) {
2039            result.AddChild(ConvertCatch(ctch), TryCatchStatement.CatchClauseRole);
2040          }
2041        }
2042//        if (tryCatchStatement.General != null)
2043//          result.AddChild (ConvertCatch (tryCatchStatement.General), TryCatchStatement.CatchClauseRole);
2044       
2045        return result;
2046      }
2047
2048      public override object Visit(Using usingStatement)
2049      {
2050        var result = new UsingStatement();
2051        var location = LocationsBag.GetLocations(usingStatement);
2052       
2053        result.AddChild(new CSharpTokenNode(Convert(usingStatement.loc), UsingStatement.UsingKeywordRole), UsingStatement.UsingKeywordRole);
2054        if (location != null)
2055          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2056        if (usingStatement.Expr != null)
2057          result.AddChild((AstNode)usingStatement.Expr.Accept(this), UsingStatement.ResourceAcquisitionRole);
2058       
2059        if (location != null && location.Count > 1)
2060          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2061       
2062        if (usingStatement.Statement != null)
2063          result.AddChild((Statement)usingStatement.Statement.Accept(this), Roles.EmbeddedStatement);
2064        return result;
2065      }
2066
2067      public override object Visit(Foreach foreachStatement)
2068      {
2069        var result = new ForeachStatement();
2070       
2071        var location = LocationsBag.GetLocations(foreachStatement);
2072       
2073        result.AddChild(new CSharpTokenNode(Convert(foreachStatement.loc), ForeachStatement.ForeachKeywordRole), ForeachStatement.ForeachKeywordRole);
2074        if (location != null)
2075          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2076       
2077        if (foreachStatement.TypeExpression != null)
2078          result.AddChild(ConvertToType(foreachStatement.TypeExpression), Roles.Type);
2079       
2080        if (foreachStatement.Variable != null)
2081          result.AddChild(Identifier.Create(foreachStatement.Variable.Name, Convert(foreachStatement.Variable.Location)), Roles.Identifier);
2082       
2083        if (location != null && location.Count > 1)
2084          result.AddChild(new CSharpTokenNode(Convert(location [1]), ForeachStatement.InKeywordRole), ForeachStatement.InKeywordRole);
2085       
2086        if (foreachStatement.Expr != null)
2087          result.AddChild((Expression)foreachStatement.Expr.Accept(this), Roles.Expression);
2088       
2089        if (location != null && location.Count > 2)
2090          result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RPar), Roles.RPar);
2091       
2092        if (foreachStatement.Statement != null)
2093          result.AddChild((Statement)foreachStatement.Statement.Accept(this), Roles.EmbeddedStatement);
2094       
2095        return result;
2096      }
2097
2098      public override object Visit(Yield yieldStatement)
2099      {
2100        var result = new YieldReturnStatement();
2101        var location = LocationsBag.GetLocations(yieldStatement);
2102       
2103        result.AddChild(new CSharpTokenNode(Convert(yieldStatement.loc), YieldReturnStatement.YieldKeywordRole), YieldReturnStatement.YieldKeywordRole);
2104        if (location != null)
2105          result.AddChild(new CSharpTokenNode(Convert(location [0]), YieldReturnStatement.ReturnKeywordRole), YieldReturnStatement.ReturnKeywordRole);
2106        if (yieldStatement.Expr != null)
2107          result.AddChild((Expression)yieldStatement.Expr.Accept(this), Roles.Expression);
2108        if (location != null && location.Count > 1)
2109          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
2110       
2111        return result;
2112      }
2113
2114      public override object Visit(YieldBreak yieldBreakStatement)
2115      {
2116        var result = new YieldBreakStatement();
2117        var location = LocationsBag.GetLocations(yieldBreakStatement);
2118        result.AddChild(new CSharpTokenNode(Convert(yieldBreakStatement.loc), YieldBreakStatement.YieldKeywordRole), YieldBreakStatement.YieldKeywordRole);
2119        if (location != null) {
2120          result.AddChild(new CSharpTokenNode(Convert(location [0]), YieldBreakStatement.BreakKeywordRole), YieldBreakStatement.BreakKeywordRole);
2121          if (location.Count > 1)
2122            result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Semicolon), Roles.Semicolon);
2123        }
2124        return result;
2125      }
2126
2127      #endregion
2128
2129      #region Expression
2130
2131      public override object Visit(Mono.CSharp.Expression expression)
2132      {
2133        Console.WriteLine("Visit unknown expression:" + expression);
2134        Console.WriteLine(Environment.StackTrace);
2135        return null;
2136      }
2137
2138      public override object Visit(DefaultParameterValueExpression defaultParameterValueExpression)
2139      {
2140        return defaultParameterValueExpression.Child.Accept(this);
2141      }
2142
2143      public override object Visit(TypeExpression typeExpression)
2144      {
2145        return new TypeReferenceExpression(new PrimitiveType(keywordTable [(int)typeExpression.Type.BuiltinType], Convert(typeExpression.Location)));
2146      }
2147
2148      public override object Visit(LocalVariableReference localVariableReference)
2149      {
2150        return Identifier.Create(localVariableReference.Name, Convert(localVariableReference.Location));
2151      }
2152
2153      public override object Visit(MemberAccess memberAccess)
2154      {
2155        Expression result;
2156        var ind = memberAccess.LeftExpression as Indirection;
2157        if (ind != null) {
2158          result = new PointerReferenceExpression();
2159          result.AddChild((Expression)ind.Expr.Accept(this), Roles.TargetExpression);
2160          result.AddChild(new CSharpTokenNode(Convert(ind.Location), PointerReferenceExpression.ArrowRole), PointerReferenceExpression.ArrowRole);
2161        } else {
2162          result = new MemberReferenceExpression();
2163          if (memberAccess.LeftExpression != null) {
2164            var leftExpr = memberAccess.LeftExpression.Accept(this);
2165            result.AddChild((Expression)leftExpr, Roles.TargetExpression);
2166          }
2167          var loc = LocationsBag.GetLocations(memberAccess);
2168
2169          if (loc != null) {
2170            result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Dot), Roles.Dot);
2171          }
2172        }
2173       
2174        result.AddChild(Identifier.Create(memberAccess.Name, Convert(memberAccess.Location)), Roles.Identifier);
2175       
2176        AddTypeArguments(result, memberAccess);
2177        return result;
2178      }
2179
2180      public override object Visit(QualifiedAliasMember qualifiedAliasMember)
2181      {
2182        var result = new MemberType();
2183        result.Target = new SimpleType(qualifiedAliasMember.alias, Convert(qualifiedAliasMember.Location));
2184        result.IsDoubleColon = true;
2185        var location = LocationsBag.GetLocations(qualifiedAliasMember);
2186        if (location != null && location.Count > 0)
2187          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.DoubleColon), Roles.DoubleColon);
2188
2189        AddTypeArguments(result, qualifiedAliasMember);
2190        result.AddChild(Identifier.Create(qualifiedAliasMember.Name, location != null && location.Count > 1 ? Convert(location [1]) : TextLocation.Empty), Roles.Identifier);
2191        return  new TypeReferenceExpression { Type = result };
2192      }
2193
2194      public override object Visit(Constant constant)
2195      {
2196        if (constant.GetValue() == null)
2197          return new NullReferenceExpression(Convert(constant.Location));
2198        string literalValue;
2199        var literalConstant = constant as ILiteralConstant;
2200        literalValue = literalConstant != null ? new string(literalConstant.ParsedValue) : constant.GetValueAsLiteral();
2201        object val = constant.GetValue();
2202        if (val is bool)
2203          literalValue = (bool)val ? "true" : "false";
2204        var result = new PrimitiveExpression(val, Convert(constant.Location), literalValue);
2205        return result;
2206      }
2207
2208      public override object Visit(SimpleName simpleName)
2209      {
2210        var result = new IdentifierExpression();
2211        result.AddChild(Identifier.Create(simpleName.Name, Convert(simpleName.Location)), Roles.Identifier);
2212        AddTypeArguments(result, simpleName);
2213        return result;
2214      }
2215
2216      public override object Visit(BooleanExpression booleanExpression)
2217      {
2218        return booleanExpression.Expr.Accept(this);
2219      }
2220
2221      public override object Visit(Mono.CSharp.ParenthesizedExpression parenthesizedExpression)
2222      {
2223        var result = new ParenthesizedExpression();
2224        var location = LocationsBag.GetLocations(parenthesizedExpression);
2225        if (location != null)
2226          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2227        if (parenthesizedExpression.Expr != null)
2228          result.AddChild((Expression)parenthesizedExpression.Expr.Accept(this), Roles.Expression);
2229        if (location != null && location.Count > 1)
2230          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2231        return result;
2232      }
2233
2234      public override object Visit(Unary unaryExpression)
2235      {
2236        var result = new UnaryOperatorExpression();
2237        switch (unaryExpression.Oper) {
2238          case Unary.Operator.UnaryPlus:
2239            result.Operator = UnaryOperatorType.Plus;
2240            break;
2241          case Unary.Operator.UnaryNegation:
2242            result.Operator = UnaryOperatorType.Minus;
2243            break;
2244          case Unary.Operator.LogicalNot:
2245            result.Operator = UnaryOperatorType.Not;
2246            break;
2247          case Unary.Operator.OnesComplement:
2248            result.Operator = UnaryOperatorType.BitNot;
2249            break;
2250          case Unary.Operator.AddressOf:
2251            result.Operator = UnaryOperatorType.AddressOf;
2252            break;
2253        }
2254        var r = UnaryOperatorExpression.GetOperatorRole(result.Operator);
2255        result.AddChild(new CSharpTokenNode(Convert(unaryExpression.Location), r), r);
2256        if (unaryExpression.Expr != null)
2257          result.AddChild((Expression)unaryExpression.Expr.Accept(this), Roles.Expression);
2258        return result;
2259      }
2260
2261      public override object Visit(UnaryMutator unaryMutatorExpression)
2262      {
2263        var result = new UnaryOperatorExpression();
2264        if (unaryMutatorExpression.Expr == null)
2265          return result;
2266        var expression = (Expression)unaryMutatorExpression.Expr.Accept(this);
2267        switch (unaryMutatorExpression.UnaryMutatorMode) {
2268          case UnaryMutator.Mode.PostDecrement:
2269            result.Operator = UnaryOperatorType.PostDecrement;
2270            result.AddChild(expression, Roles.Expression);
2271            result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.DecrementRole), UnaryOperatorExpression.DecrementRole);
2272            break;
2273          case UnaryMutator.Mode.PostIncrement:
2274            result.Operator = UnaryOperatorType.PostIncrement;
2275            result.AddChild(expression, Roles.Expression);
2276            result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.IncrementRole), UnaryOperatorExpression.IncrementRole);
2277            break;
2278           
2279          case UnaryMutator.Mode.PreIncrement:
2280            result.Operator = UnaryOperatorType.Increment;
2281            result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.IncrementRole), UnaryOperatorExpression.IncrementRole);
2282            result.AddChild(expression, Roles.Expression);
2283            break;
2284          case UnaryMutator.Mode.PreDecrement:
2285            result.Operator = UnaryOperatorType.Decrement;
2286            result.AddChild(new CSharpTokenNode(Convert(unaryMutatorExpression.Location), UnaryOperatorExpression.DecrementRole), UnaryOperatorExpression.DecrementRole);
2287            result.AddChild(expression, Roles.Expression);
2288            break;
2289        }
2290       
2291        return result;
2292      }
2293
2294      public override object Visit(Indirection indirectionExpression)
2295      {
2296        var result = new UnaryOperatorExpression();
2297        result.Operator = UnaryOperatorType.Dereference;
2298        result.AddChild(new CSharpTokenNode(Convert(indirectionExpression.Location), UnaryOperatorExpression.DereferenceRole), UnaryOperatorExpression.DereferenceRole);
2299        if (indirectionExpression.Expr != null)
2300          result.AddChild((Expression)indirectionExpression.Expr.Accept(this), Roles.Expression);
2301        return result;
2302      }
2303
2304      public override object Visit(Is isExpression)
2305      {
2306        var result = new IsExpression();
2307        if (isExpression.Expr != null)
2308          result.AddChild((Expression)isExpression.Expr.Accept(this), Roles.Expression);
2309        result.AddChild(new CSharpTokenNode(Convert(isExpression.Location), IsExpression.IsKeywordRole), IsExpression.IsKeywordRole);
2310       
2311        if (isExpression.ProbeType != null)
2312          result.AddChild(ConvertToType(isExpression.ProbeType), Roles.Type);
2313        return result;
2314      }
2315
2316      public override object Visit(As asExpression)
2317      {
2318        var result = new AsExpression();
2319        if (asExpression.Expr != null)
2320          result.AddChild((Expression)asExpression.Expr.Accept(this), Roles.Expression);
2321        result.AddChild(new CSharpTokenNode(Convert(asExpression.Location), AsExpression.AsKeywordRole), AsExpression.AsKeywordRole);
2322        if (asExpression.ProbeType != null)
2323          result.AddChild(ConvertToType(asExpression.ProbeType), Roles.Type);
2324        return result;
2325      }
2326
2327      public override object Visit(Cast castExpression)
2328      {
2329        var result = new CastExpression();
2330        var location = LocationsBag.GetLocations(castExpression);
2331       
2332        result.AddChild(new CSharpTokenNode(Convert(castExpression.Location), Roles.LPar), Roles.LPar);
2333        if (castExpression.TargetType != null)
2334          result.AddChild(ConvertToType(castExpression.TargetType), Roles.Type);
2335        if (location != null)
2336          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.RPar), Roles.RPar);
2337        if (castExpression.Expr != null)
2338          result.AddChild((Expression)castExpression.Expr.Accept(this), Roles.Expression);
2339        return result;
2340      }
2341
2342      public override object Visit(ComposedCast composedCast)
2343      {
2344        var result = new ComposedType();
2345        result.AddChild(ConvertToType(composedCast.Left), Roles.Type);
2346       
2347        var spec = composedCast.Spec;
2348        while (spec != null) {
2349          if (spec.IsNullable) {
2350            result.AddChild(new CSharpTokenNode(Convert(spec.Location), ComposedType.NullableRole), ComposedType.NullableRole);
2351          } else if (spec.IsPointer) {
2352            result.AddChild(new CSharpTokenNode(Convert(spec.Location), ComposedType.PointerRole), ComposedType.PointerRole);
2353          } else {
2354            var aSpec = new ArraySpecifier();
2355            aSpec.AddChild(new CSharpTokenNode(Convert(spec.Location), Roles.LBracket), Roles.LBracket);
2356            var location = LocationsBag.GetLocations(spec);
2357            if (location != null)
2358              aSpec.AddChild(new CSharpTokenNode(Convert(spec.Location), Roles.RBracket), Roles.RBracket);
2359            result.AddChild(aSpec, ComposedType.ArraySpecifierRole);
2360          }
2361          spec = spec.Next;
2362        }
2363       
2364        return result;
2365      }
2366
2367      public override object Visit(Mono.CSharp.DefaultValueExpression defaultValueExpression)
2368      {
2369        var result = new DefaultValueExpression();
2370        result.AddChild(new CSharpTokenNode(Convert(defaultValueExpression.Location), DefaultValueExpression.DefaultKeywordRole), DefaultValueExpression.DefaultKeywordRole);
2371        var location = LocationsBag.GetLocations(defaultValueExpression);
2372        if (location != null)
2373          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2374        result.AddChild(ConvertToType(defaultValueExpression.Expr), Roles.Type);
2375        if (location != null && location.Count > 1)
2376          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2377        return result;
2378      }
2379
2380      public override object Visit(Binary binaryExpression)
2381      {
2382        var result = new BinaryOperatorExpression();
2383        switch (binaryExpression.Oper) {
2384          case Binary.Operator.Multiply:
2385            result.Operator = BinaryOperatorType.Multiply;
2386            break;
2387          case Binary.Operator.Division:
2388            result.Operator = BinaryOperatorType.Divide;
2389            break;
2390          case Binary.Operator.Modulus:
2391            result.Operator = BinaryOperatorType.Modulus;
2392            break;
2393          case Binary.Operator.Addition:
2394            result.Operator = BinaryOperatorType.Add;
2395            break;
2396          case Binary.Operator.Subtraction:
2397            result.Operator = BinaryOperatorType.Subtract;
2398            break;
2399          case Binary.Operator.LeftShift:
2400            result.Operator = BinaryOperatorType.ShiftLeft;
2401            break;
2402          case Binary.Operator.RightShift:
2403            result.Operator = BinaryOperatorType.ShiftRight;
2404            break;
2405          case Binary.Operator.LessThan:
2406            result.Operator = BinaryOperatorType.LessThan;
2407            break;
2408          case Binary.Operator.GreaterThan:
2409            result.Operator = BinaryOperatorType.GreaterThan;
2410            break;
2411          case Binary.Operator.LessThanOrEqual:
2412            result.Operator = BinaryOperatorType.LessThanOrEqual;
2413            break;
2414          case Binary.Operator.GreaterThanOrEqual:
2415            result.Operator = BinaryOperatorType.GreaterThanOrEqual;
2416            break;
2417          case Binary.Operator.Equality:
2418            result.Operator = BinaryOperatorType.Equality;
2419            break;
2420          case Binary.Operator.Inequality:
2421            result.Operator = BinaryOperatorType.InEquality;
2422            break;
2423          case Binary.Operator.BitwiseAnd:
2424            result.Operator = BinaryOperatorType.BitwiseAnd;
2425            break;
2426          case Binary.Operator.ExclusiveOr:
2427            result.Operator = BinaryOperatorType.ExclusiveOr;
2428            break;
2429          case Binary.Operator.BitwiseOr:
2430            result.Operator = BinaryOperatorType.BitwiseOr;
2431            break;
2432          case Binary.Operator.LogicalAnd:
2433            result.Operator = BinaryOperatorType.ConditionalAnd;
2434            break;
2435          case Binary.Operator.LogicalOr:
2436            result.Operator = BinaryOperatorType.ConditionalOr;
2437            break;
2438        }
2439       
2440        if (binaryExpression.Left != null)
2441          result.AddChild((Expression)binaryExpression.Left.Accept(this), BinaryOperatorExpression.LeftRole);
2442        var location = LocationsBag.GetLocations(binaryExpression);
2443        if (location != null) {
2444          var r = BinaryOperatorExpression.GetOperatorRole(result.Operator);
2445          result.AddChild(new CSharpTokenNode(Convert(location [0]), r), r);
2446        }
2447        if (binaryExpression.Right != null)
2448          result.AddChild((Expression)binaryExpression.Right.Accept(this), BinaryOperatorExpression.RightRole);
2449        return result;
2450      }
2451
2452      public override object Visit(Mono.CSharp.Nullable.NullCoalescingOperator nullCoalescingOperator)
2453      {
2454        var result = new BinaryOperatorExpression();
2455        result.Operator = BinaryOperatorType.NullCoalescing;
2456        if (nullCoalescingOperator.LeftExpression != null)
2457          result.AddChild((Expression)nullCoalescingOperator.LeftExpression.Accept(this), BinaryOperatorExpression.LeftRole);
2458        var location = LocationsBag.GetLocations(nullCoalescingOperator);
2459        if (location != null)
2460          result.AddChild(new CSharpTokenNode(Convert(location [0]), BinaryOperatorExpression.NullCoalescingRole), BinaryOperatorExpression.NullCoalescingRole);
2461        if (nullCoalescingOperator.RightExpression != null)
2462          result.AddChild((Expression)nullCoalescingOperator.RightExpression.Accept(this), BinaryOperatorExpression.RightRole);
2463        return result;
2464      }
2465
2466      public override object Visit(Conditional conditionalExpression)
2467      {
2468        var result = new ConditionalExpression();
2469       
2470        if (conditionalExpression.Expr != null)
2471          result.AddChild((Expression)conditionalExpression.Expr.Accept(this), Roles.Condition);
2472        var location = LocationsBag.GetLocations(conditionalExpression);
2473       
2474        result.AddChild(new CSharpTokenNode(Convert(conditionalExpression.Location), ConditionalExpression.QuestionMarkRole), ConditionalExpression.QuestionMarkRole);
2475        if (conditionalExpression.TrueExpr != null)
2476          result.AddChild((Expression)conditionalExpression.TrueExpr.Accept(this), ConditionalExpression.TrueRole);
2477        if (location != null)
2478          result.AddChild(new CSharpTokenNode(Convert(location [0]), ConditionalExpression.ColonRole), ConditionalExpression.ColonRole);
2479        if (conditionalExpression.FalseExpr != null)
2480          result.AddChild((Expression)conditionalExpression.FalseExpr.Accept(this), ConditionalExpression.FalseRole);
2481        return result;
2482      }
2483
2484      void AddParameter(AstNode parent, AParametersCollection parameters)
2485      {
2486        if (parameters == null)
2487          return;
2488        var paramLocation = LocationsBag.GetLocations(parameters);
2489       
2490        for (int i = 0; i < parameters.Count; i++) {
2491          var p = (Parameter)parameters.FixedParameters [i];
2492          if (p == null)
2493            continue;
2494          var location = LocationsBag.GetLocations(p);
2495          var parameterDeclarationExpression = new ParameterDeclaration();
2496          AddAttributeSection(parameterDeclarationExpression, p);
2497          switch (p.ModFlags) {
2498            case Parameter.Modifier.OUT:
2499              parameterDeclarationExpression.ParameterModifier = ParameterModifier.Out;
2500              if (location != null)
2501                parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.OutModifierRole), ParameterDeclaration.OutModifierRole);
2502              break;
2503            case Parameter.Modifier.REF:
2504              parameterDeclarationExpression.ParameterModifier = ParameterModifier.Ref;
2505              if (location != null)
2506                parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.RefModifierRole), ParameterDeclaration.RefModifierRole);
2507              break;
2508            case Parameter.Modifier.PARAMS:
2509              parameterDeclarationExpression.ParameterModifier = ParameterModifier.Params;
2510              if (location != null)
2511                parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.ParamsModifierRole), ParameterDeclaration.ParamsModifierRole);
2512              break;
2513            default:
2514              if (p.HasExtensionMethodModifier) {
2515                parameterDeclarationExpression.ParameterModifier = ParameterModifier.This;
2516                if (location != null) {
2517                  parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [0]), ParameterDeclaration.ThisModifierRole), ParameterDeclaration.ThisModifierRole);
2518                }
2519              }
2520              break;
2521          }
2522          if (p.TypeExpression != null) // lambdas may have no types (a, b) => ...
2523            parameterDeclarationExpression.AddChild(ConvertToType(p.TypeExpression), Roles.Type);
2524          if (p.Name != null)
2525            parameterDeclarationExpression.AddChild(Identifier.Create(p.Name, Convert(p.Location)), Roles.Identifier);
2526          if (p.HasDefaultValue) {
2527            if (location != null && location.Count > 1)
2528              parameterDeclarationExpression.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.Assign), Roles.Assign);
2529            parameterDeclarationExpression.AddChild((Expression)p.DefaultValue.Accept(this), Roles.Expression);
2530          }
2531          parent.AddChild(parameterDeclarationExpression, Roles.Parameter);
2532          if (paramLocation != null && i < paramLocation.Count) {
2533            parent.AddChild(new CSharpTokenNode(Convert(paramLocation [i]), Roles.Comma), Roles.Comma);
2534          }
2535        }
2536      }
2537
2538      void AddTypeParameters(AstNode parent, MemberName memberName)
2539      {
2540        if (memberName == null || memberName.TypeParameters == null)
2541          return;
2542        var chevronLocs = LocationsBag.GetLocations(memberName.TypeParameters);
2543        if (chevronLocs != null)
2544          parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron);
2545        for (int i = 0; i < memberName.TypeParameters.Count; i++) {
2546          if (chevronLocs != null && i > 0 && i - 1 < chevronLocs.Count)
2547            parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [i - 1]), Roles.Comma), Roles.Comma);
2548          var arg = memberName.TypeParameters [i];
2549          if (arg == null)
2550            continue;
2551          var tp = new TypeParameterDeclaration();
2552         
2553          List<Location> varianceLocation;
2554          switch (arg.Variance) {
2555            case Variance.Contravariant:
2556              tp.Variance = VarianceModifier.Contravariant;
2557              varianceLocation = LocationsBag.GetLocations(arg);
2558              if (varianceLocation != null)
2559                tp.AddChild(new CSharpTokenNode(Convert(varianceLocation [0]), TypeParameterDeclaration.InVarianceKeywordRole), TypeParameterDeclaration.InVarianceKeywordRole);
2560              break;
2561            case Variance.Covariant:
2562              tp.Variance = VarianceModifier.Covariant;
2563              varianceLocation = LocationsBag.GetLocations(arg);
2564              if (varianceLocation != null)
2565                tp.AddChild(new CSharpTokenNode(Convert(varianceLocation [0]), TypeParameterDeclaration.OutVarianceKeywordRole), TypeParameterDeclaration.OutVarianceKeywordRole);
2566              break;
2567            default:
2568              tp.Variance = VarianceModifier.Invariant;
2569              break;
2570             
2571          }
2572         
2573          AddAttributeSection(tp, arg.OptAttributes);
2574
2575          switch (arg.Variance) {
2576            case Variance.Covariant:
2577              tp.Variance = VarianceModifier.Covariant;
2578              break;
2579            case Variance.Contravariant:
2580              tp.Variance = VarianceModifier.Contravariant;
2581              break;
2582          }
2583          tp.AddChild(Identifier.Create(arg.Name, Convert(arg.Location)), Roles.Identifier);
2584          parent.AddChild(tp, Roles.TypeParameter);
2585        }
2586        if (chevronLocs != null)
2587          parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron);
2588      }
2589
2590      void AddTypeArguments(AstNode parent, MemberName memberName)
2591      {
2592        if (memberName == null || memberName.TypeParameters == null)
2593          return;
2594        var chevronLocs = LocationsBag.GetLocations(memberName.TypeParameters);
2595        if (chevronLocs != null)
2596          parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron);
2597       
2598        for (int i = 0; i < memberName.TypeParameters.Count; i++) {
2599          var arg = memberName.TypeParameters [i];
2600          if (arg == null)
2601            continue;
2602          parent.AddChild(ConvertToType(arg), Roles.TypeArgument);
2603          if (chevronLocs != null && i < chevronLocs.Count - 2)
2604            parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [i]), Roles.Comma), Roles.Comma);
2605        }
2606       
2607        if (chevronLocs != null)
2608          parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron);
2609      }
2610
2611      void AddTypeArguments(AstNode parent, ATypeNameExpression memberName)
2612      {
2613        if (memberName == null || !memberName.HasTypeArguments)
2614          return;
2615        var chevronLocs = LocationsBag.GetLocations(memberName.TypeArguments);
2616        if (chevronLocs != null)
2617          parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 2]), Roles.LChevron), Roles.LChevron);
2618       
2619        for (int i = 0; i < memberName.TypeArguments.Count; i++) {
2620          var arg = memberName.TypeArguments.Args [i];
2621          if (arg == null)
2622            continue;
2623          parent.AddChild(ConvertToType(arg), Roles.TypeArgument);
2624          if (chevronLocs != null && i < chevronLocs.Count - 2)
2625            parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [i]), Roles.Comma), Roles.Comma);
2626        }
2627       
2628        if (chevronLocs != null)
2629          parent.AddChild(new CSharpTokenNode(Convert(chevronLocs [chevronLocs.Count - 1]), Roles.RChevron), Roles.RChevron);
2630      }
2631
2632      void AddConstraints(AstNode parent, TypeParameters d)
2633      {
2634        if (d == null)
2635          return;
2636        for (int i = 0; i < d.Count; i++) {
2637          var typeParameter = d [i];
2638          if (typeParameter == null)
2639            continue;
2640          var c = typeParameter.Constraints;
2641          if (c == null)
2642            continue;
2643          var location = LocationsBag.GetLocations(c);
2644          var constraint = new Constraint();
2645          constraint.AddChild(new CSharpTokenNode(Convert(c.Location), Roles.WhereKeyword), Roles.WhereKeyword);
2646          constraint.AddChild(new SimpleType(Identifier.Create(c.TypeParameter.Value, Convert(c.TypeParameter.Location))), Roles.ConstraintTypeParameter);
2647          if (location != null)
2648            constraint.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Colon), Roles.Colon);
2649          var commaLocs = LocationsBag.GetLocations(c.ConstraintExpressions);
2650          int curComma = 0;
2651          if (c.ConstraintExpressions != null) {
2652            foreach (var expr in c.ConstraintExpressions) {
2653              constraint.AddChild(ConvertToType(expr), Roles.BaseType);
2654              var sce = expr as SpecialContraintExpr;
2655              if (sce != null) {
2656                switch (sce.Constraint) {
2657                  case SpecialConstraint.Class:
2658                    break;
2659                  case SpecialConstraint.Struct:
2660                    break;
2661                  case SpecialConstraint.Constructor:
2662                    var bl = LocationsBag.GetLocations(expr);
2663                    if (bl != null) {
2664                      constraint.AddChild(new CSharpTokenNode(Convert(bl [0]), Roles.LPar), Roles.LPar);
2665                      constraint.AddChild(new CSharpTokenNode(Convert(bl [1]), Roles.RPar), Roles.RPar);
2666                    }
2667                    break;
2668                }
2669              }
2670
2671              if (commaLocs != null && curComma < commaLocs.Count)
2672                constraint.AddChild(new CSharpTokenNode(Convert(commaLocs [curComma++]), Roles.Comma), Roles.Comma);
2673            }
2674          }
2675         
2676          // We need to sort the constraints by position; as they might be in a different order than the type parameters
2677          AstNode prevSibling = parent.LastChild;
2678          while (prevSibling.StartLocation > constraint.StartLocation && prevSibling.PrevSibling != null)
2679            prevSibling = prevSibling.PrevSibling;
2680          parent.InsertChildAfter(prevSibling, constraint, Roles.Constraint);
2681        }
2682      }
2683
2684      Expression ConvertArgument(Argument arg)
2685      {
2686        var na = arg as NamedArgument;
2687        if (na != null) {
2688          var newArg = new NamedArgumentExpression();
2689          newArg.AddChild(Identifier.Create(na.Name, Convert(na.Location)), Roles.Identifier);
2690         
2691          var loc = LocationsBag.GetLocations(na);
2692          if (loc != null)
2693            newArg.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.Colon), Roles.Colon);
2694         
2695          if (arg.ArgType == Argument.AType.Out || arg.ArgType == Argument.AType.Ref) {
2696            var direction = new DirectionExpression();
2697            direction.FieldDirection = arg.ArgType == Argument.AType.Out ? FieldDirection.Out : FieldDirection.Ref;
2698            var argLocation = LocationsBag.GetLocations(arg);
2699            if (argLocation != null) {
2700              var r = arg.ArgType == Argument.AType.Out ? DirectionExpression.OutKeywordRole : DirectionExpression.RefKeywordRole;
2701              direction.AddChild(new CSharpTokenNode(Convert(argLocation [0]), r), r);
2702            }
2703            direction.AddChild((Expression)arg.Expr.Accept(this), Roles.Expression);
2704            newArg.AddChild(direction, Roles.Expression);
2705          } else {
2706            newArg.AddChild(na.Expr != null ? (Expression)na.Expr.Accept(this) : new ErrorExpression("Named argument expression parse error"), Roles.Expression);
2707          }
2708          return newArg;
2709        }
2710       
2711        if (arg.ArgType == Argument.AType.Out || arg.ArgType == Argument.AType.Ref) {
2712          var direction = new DirectionExpression();
2713          direction.FieldDirection = arg.ArgType == Argument.AType.Out ? FieldDirection.Out : FieldDirection.Ref;
2714          var argLocation = LocationsBag.GetLocations(arg);
2715          if (argLocation != null) {
2716            var r = arg.ArgType == Argument.AType.Out ? DirectionExpression.OutKeywordRole : DirectionExpression.RefKeywordRole;
2717            direction.AddChild(new CSharpTokenNode(Convert(argLocation [0]), r), r);
2718          }
2719          direction.AddChild((Expression)arg.Expr.Accept(this), Roles.Expression);
2720          return direction;
2721        }
2722       
2723        return (Expression)arg.Expr.Accept(this);
2724      }
2725
2726      void AddArguments(AstNode parent, Arguments args)
2727      {
2728        if (args == null)
2729          return;
2730       
2731        var commaLocations = LocationsBag.GetLocations(args);
2732        for (int i = 0; i < args.Count; i++) {
2733          parent.AddChild(ConvertArgument(args [i]), Roles.Argument);
2734          if (commaLocations != null && i < commaLocations.Count) {
2735            parent.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
2736          }
2737        }
2738        if (commaLocations != null && commaLocations.Count > args.Count)
2739          parent.AddChild(new CSharpTokenNode(Convert(commaLocations [args.Count]), Roles.Comma), Roles.Comma);
2740      }
2741
2742      public override object Visit(Invocation invocationExpression)
2743      {
2744        var result = new InvocationExpression();
2745        var location = LocationsBag.GetLocations(invocationExpression);
2746        if (invocationExpression.Exp != null)
2747          result.AddChild((Expression)invocationExpression.Exp.Accept(this), Roles.TargetExpression);
2748        if (location != null)
2749          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2750        AddArguments(result, invocationExpression.Arguments);
2751       
2752        if (location != null && location.Count > 1)
2753          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2754        return result;
2755      }
2756
2757      public override object Visit(New newExpression)
2758      {
2759        var result = new ObjectCreateExpression();
2760        var location = LocationsBag.GetLocations(newExpression);
2761        result.AddChild(new CSharpTokenNode(Convert(newExpression.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole);
2762       
2763        if (newExpression.TypeRequested != null)
2764          result.AddChild(ConvertToType(newExpression.TypeRequested), Roles.Type);
2765        if (location != null)
2766          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2767        AddArguments(result, newExpression.Arguments);
2768       
2769        if (location != null && location.Count > 1)
2770          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2771       
2772        return result;
2773      }
2774
2775      public override object Visit(NewAnonymousType newAnonymousType)
2776      {
2777        var result = new AnonymousTypeCreateExpression();
2778        var location = LocationsBag.GetLocations(newAnonymousType);
2779        result.AddChild(new CSharpTokenNode(Convert(newAnonymousType.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole);
2780        if (location != null)
2781          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBrace), Roles.LBrace);
2782        if (newAnonymousType.Parameters != null) {
2783          foreach (var par in newAnonymousType.Parameters) {
2784            if (par == null)
2785              continue;
2786            var parLocation = LocationsBag.GetLocations(par);
2787           
2788            if (parLocation == null) {
2789              if (par.Expr != null)
2790                result.AddChild((Expression)par.Expr.Accept(this), Roles.Expression);
2791            } else {
2792              var namedExpression = new NamedExpression();
2793              namedExpression.AddChild(Identifier.Create(par.Name, Convert(par.Location)), Roles.Identifier);
2794              namedExpression.AddChild(new CSharpTokenNode(Convert(parLocation [0]), Roles.Assign), Roles.Assign);
2795              if (par.Expr != null)
2796                namedExpression.AddChild((Expression)par.Expr.Accept(this), Roles.Expression);
2797              result.AddChild(namedExpression, Roles.Expression);
2798            }
2799          }
2800        }
2801        if (location != null && location.Count > 1)
2802          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBrace), Roles.RBrace);
2803        return result;
2804      }
2805
2806      ArrayInitializerExpression ConvertCollectionOrObjectInitializers(CollectionOrObjectInitializers minit)
2807      {
2808        if (minit == null)
2809          return null;
2810        var init = new ArrayInitializerExpression();
2811        AddConvertCollectionOrObjectInitializers(init, minit);
2812        return init;
2813      }
2814
2815      void AddConvertCollectionOrObjectInitializers(Expression init, CollectionOrObjectInitializers minit)
2816      {
2817        var initLoc = LocationsBag.GetLocations(minit);
2818        var commaLoc = LocationsBag.GetLocations(minit.Initializers);
2819        int curComma = 0;
2820        init.AddChild(new CSharpTokenNode(Convert(minit.Location), Roles.LBrace), Roles.LBrace);
2821        foreach (var expr in minit.Initializers) {
2822          var collectionInit = expr as CollectionElementInitializer;
2823          if (collectionInit != null) {
2824            AstNode parent;
2825            // For ease of use purposes in the resolver the ast representation
2826            // of { a, b, c }  is { {a}, {b}, {c} } - but the generated ArrayInitializerExpression
2827            // can be identified by expr.IsSingleElement.
2828            if (!collectionInit.IsSingle) {
2829              parent = new ArrayInitializerExpression();
2830              parent.AddChild(new CSharpTokenNode(Convert(collectionInit.Location), Roles.LBrace), Roles.LBrace);
2831            } else {
2832              parent = ArrayInitializerExpression.CreateSingleElementInitializer();
2833            }
2834
2835            if (collectionInit.Arguments != null) {
2836              for (int i = 0; i < collectionInit.Arguments.Count; i++) {
2837                var arg = collectionInit.Arguments [i] as CollectionElementInitializer.ElementInitializerArgument;
2838                if (arg == null || arg.Expr == null)
2839                  continue;
2840                parent.AddChild(
2841                  (Expression)arg.Expr.Accept(this),
2842                  Roles.Expression
2843                );
2844              }
2845            }
2846
2847            if (!collectionInit.IsSingle) {
2848              var braceLocs = LocationsBag.GetLocations(expr);
2849              if (braceLocs != null)
2850                parent.AddChild(new CSharpTokenNode(Convert(braceLocs [0]), Roles.RBrace), Roles.RBrace);
2851            }
2852            init.AddChild((ArrayInitializerExpression)parent, Roles.Expression);
2853          } else {
2854            var eleInit = expr as ElementInitializer;
2855            if (eleInit != null) {
2856              var nexpr = new NamedExpression();
2857              nexpr.AddChild(
2858                Identifier.Create(eleInit.Name, Convert(eleInit.Location)),
2859                Roles.Identifier
2860              );
2861              var assignLoc = LocationsBag.GetLocations(eleInit);
2862              if (assignLoc != null)
2863                nexpr.AddChild(new CSharpTokenNode(Convert(assignLoc [0]), Roles.Assign), Roles.Assign);
2864              if (eleInit.Source != null) {
2865                var colInit = eleInit.Source as CollectionOrObjectInitializers;
2866                if (colInit != null) {
2867                  var arrInit = new ArrayInitializerExpression();
2868                  AddConvertCollectionOrObjectInitializers(
2869                    arrInit,
2870                    colInit
2871                  );
2872                  nexpr.AddChild(arrInit, Roles.Expression);
2873                } else {
2874                  nexpr.AddChild((Expression)eleInit.Source.Accept(this), Roles.Expression);
2875                }
2876              }
2877
2878              init.AddChild(nexpr, Roles.Expression);
2879            }
2880          }
2881          if (commaLoc != null && curComma < commaLoc.Count)
2882            init.AddChild(new CSharpTokenNode(Convert(commaLoc [curComma++]), Roles.Comma), Roles.Comma);
2883        }
2884
2885        if (initLoc != null) {
2886          if (initLoc.Count == 2) // optional comma
2887            init.AddChild(new CSharpTokenNode(Convert(initLoc [0]), Roles.Comma), Roles.Comma);
2888          init.AddChild(new CSharpTokenNode(Convert(initLoc [initLoc.Count - 1]), Roles.RBrace), Roles.RBrace);
2889        }
2890      }
2891
2892      public override object Visit(NewInitialize newInitializeExpression)
2893      {
2894        var result = new ObjectCreateExpression();
2895        result.AddChild(new CSharpTokenNode(Convert(newInitializeExpression.Location), ObjectCreateExpression.NewKeywordRole), ObjectCreateExpression.NewKeywordRole);
2896       
2897        if (newInitializeExpression.TypeRequested != null)
2898          result.AddChild(ConvertToType(newInitializeExpression.TypeRequested), Roles.Type);
2899       
2900        var location = LocationsBag.GetLocations(newInitializeExpression);
2901        if (location != null)
2902          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
2903        AddArguments(result, newInitializeExpression.Arguments);
2904        if (location != null && location.Count > 1)
2905          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
2906       
2907        var init = ConvertCollectionOrObjectInitializers(newInitializeExpression.Initializers);
2908        if (init != null)
2909          result.AddChild(init, ObjectCreateExpression.InitializerRole);
2910       
2911        return result;
2912      }
2913
2914      public override object Visit(ArrayCreation arrayCreationExpression)
2915      {
2916        var result = new ArrayCreateExpression();
2917       
2918        var location = LocationsBag.GetLocations(arrayCreationExpression);
2919        result.AddChild(new CSharpTokenNode(Convert(arrayCreationExpression.Location), ArrayCreateExpression.NewKeywordRole), ArrayCreateExpression.NewKeywordRole);
2920        if (arrayCreationExpression.TypeExpression != null)
2921          result.AddChild(ConvertToType(arrayCreationExpression.TypeExpression), Roles.Type);
2922       
2923        var next = arrayCreationExpression.Rank;
2924        if (arrayCreationExpression.Arguments != null) {
2925          // skip first array rank.
2926          next = next.Next;
2927         
2928          if (location != null)
2929            result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LBracket), Roles.LBracket);
2930         
2931          var commaLocations = LocationsBag.GetLocations(arrayCreationExpression.Arguments);
2932          for (int i = 0; i < arrayCreationExpression.Arguments.Count; i++) {
2933            var arg = arrayCreationExpression.Arguments [i];
2934            if (arg != null)
2935              result.AddChild((Expression)arg.Accept(this), Roles.Argument);
2936            if (commaLocations != null && i < commaLocations.Count)
2937              result.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
2938          }
2939          if (location != null && location.Count > 1)
2940            result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RBracket), Roles.RBracket);
2941         
2942        }
2943       
2944        while (next != null) {
2945          var spec = new ArraySpecifier(next.Dimension);
2946          var loc = LocationsBag.GetLocations(next);
2947          spec.AddChild(new CSharpTokenNode(Convert(next.Location), Roles.LBracket), Roles.LBracket);
2948          result.AddChild(spec, ArrayCreateExpression.AdditionalArraySpecifierRole);
2949          if (loc != null)
2950            result.AddChild(new CSharpTokenNode(Convert(loc [0]), Roles.RBracket), Roles.RBracket);
2951          next = next.Next;
2952        }
2953       
2954        if (arrayCreationExpression.Initializers != null) {
2955          var initLocation = LocationsBag.GetLocations(arrayCreationExpression.Initializers);
2956          var initializer = new ArrayInitializerExpression();
2957         
2958          initializer.AddChild(new CSharpTokenNode(Convert(arrayCreationExpression.Initializers.Location), Roles.LBrace), Roles.LBrace);
2959          var commaLocations = LocationsBag.GetLocations(arrayCreationExpression.Initializers.Elements);
2960          for (int i = 0; i < arrayCreationExpression.Initializers.Count; i++) {
2961            var init = arrayCreationExpression.Initializers [i];
2962            if (init == null)
2963              continue;
2964            initializer.AddChild((Expression)init.Accept(this), Roles.Expression);
2965            if (commaLocations != null && i < commaLocations.Count) {
2966              initializer.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
2967            }
2968          }
2969          if (initLocation != null) {
2970            if (initLocation.Count == 2) // optional comma
2971              initializer.AddChild(new CSharpTokenNode(Convert(initLocation [0]), Roles.Comma), Roles.Comma);
2972            initializer.AddChild(new CSharpTokenNode(Convert(initLocation [initLocation.Count - 1]), Roles.RBrace), Roles.RBrace);
2973          }
2974          result.AddChild(initializer, ArrayCreateExpression.InitializerRole);
2975        }
2976       
2977        return result;
2978      }
2979
2980      public override object Visit(This thisExpression)
2981      {
2982        var result = new ThisReferenceExpression();
2983        result.Location = Convert(thisExpression.Location);
2984        return result;
2985      }
2986
2987      public override object Visit(ArglistAccess argListAccessExpression)
2988      {
2989        var result = new UndocumentedExpression {
2990          UndocumentedExpressionType = UndocumentedExpressionType.ArgListAccess
2991        };
2992        result.AddChild(new CSharpTokenNode(Convert(argListAccessExpression.Location), UndocumentedExpression.ArglistKeywordRole), UndocumentedExpression.ArglistKeywordRole);
2993        return result;
2994      }
2995
2996      #region Undocumented expressions
2997
2998      public override object Visit(Arglist argListExpression)
2999      {
3000        var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.ArgList };
3001        result.AddChild(new CSharpTokenNode(Convert(argListExpression.Location), UndocumentedExpression.ArglistKeywordRole), UndocumentedExpression.ArglistKeywordRole);
3002        var location = LocationsBag.GetLocations(argListExpression);
3003        if (location != null)
3004          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3005       
3006        AddArguments(result, argListExpression.Arguments);
3007       
3008        if (location != null && location.Count > 1)
3009          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3010        return result;
3011      }
3012
3013      public override object Visit(MakeRefExpr makeRefExpr)
3014      {
3015        var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.MakeRef };
3016        result.AddChild(new CSharpTokenNode(Convert(makeRefExpr.Location), UndocumentedExpression.MakerefKeywordRole), UndocumentedExpression.MakerefKeywordRole);
3017        var location = LocationsBag.GetLocations(makeRefExpr);
3018        if (location != null)
3019          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3020        if (makeRefExpr.Expr != null)
3021          result.AddChild((Expression)makeRefExpr.Expr.Accept(this), Roles.Argument);
3022        if (location != null && location.Count > 1)
3023          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3024        return result;
3025      }
3026
3027      public override object Visit(RefTypeExpr refTypeExpr)
3028      {
3029        var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefType };
3030        result.AddChild(new CSharpTokenNode(Convert(refTypeExpr.Location), UndocumentedExpression.ReftypeKeywordRole), UndocumentedExpression.ReftypeKeywordRole);
3031        var location = LocationsBag.GetLocations(refTypeExpr);
3032        if (location != null)
3033          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3034       
3035        if (refTypeExpr.Expr != null)
3036          result.AddChild((Expression)refTypeExpr.Expr.Accept(this), Roles.Argument);
3037       
3038        if (location != null && location.Count > 1)
3039          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3040        return result;
3041      }
3042
3043      public override object Visit(RefValueExpr refValueExpr)
3044      {
3045        var result = new UndocumentedExpression { UndocumentedExpressionType = UndocumentedExpressionType.RefValue };
3046        result.AddChild(new CSharpTokenNode(Convert(refValueExpr.Location), UndocumentedExpression.RefvalueKeywordRole), UndocumentedExpression.RefvalueKeywordRole);
3047        var location = LocationsBag.GetLocations(refValueExpr);
3048        if (location != null)
3049          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3050       
3051       
3052        if (refValueExpr.Expr != null)
3053          result.AddChild((Expression)refValueExpr.Expr.Accept(this), Roles.Argument);
3054
3055        if (refValueExpr.FullNamedExpression != null)
3056          result.AddChild((Expression)refValueExpr.FullNamedExpression.Accept(this), Roles.Argument);
3057       
3058        if (location != null && location.Count > 1)
3059          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3060        return result;
3061      }
3062
3063      #endregion
3064
3065      public override object Visit(TypeOf typeOfExpression)
3066      {
3067        var result = new TypeOfExpression();
3068        var location = LocationsBag.GetLocations(typeOfExpression);
3069        result.AddChild(new CSharpTokenNode(Convert(typeOfExpression.Location), TypeOfExpression.TypeofKeywordRole), TypeOfExpression.TypeofKeywordRole);
3070        if (location != null)
3071          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3072        if (typeOfExpression.TypeExpression != null)
3073          result.AddChild(ConvertToType(typeOfExpression.TypeExpression), Roles.Type);
3074        if (location != null && location.Count > 1)
3075          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3076        return result;
3077      }
3078
3079      public override object Visit(SizeOf sizeOfExpression)
3080      {
3081        var result = new SizeOfExpression();
3082        var location = LocationsBag.GetLocations(sizeOfExpression);
3083        result.AddChild(new CSharpTokenNode(Convert(sizeOfExpression.Location), SizeOfExpression.SizeofKeywordRole), SizeOfExpression.SizeofKeywordRole);
3084        if (location != null)
3085          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3086        if (sizeOfExpression.TypeExpression != null)
3087          result.AddChild(ConvertToType(sizeOfExpression.TypeExpression), Roles.Type);
3088        if (location != null && location.Count > 1)
3089          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3090        return result;
3091      }
3092
3093      public override object Visit(CheckedExpr checkedExpression)
3094      {
3095        var result = new CheckedExpression();
3096        var location = LocationsBag.GetLocations(checkedExpression);
3097        result.AddChild(new CSharpTokenNode(Convert(checkedExpression.Location), CheckedExpression.CheckedKeywordRole), CheckedExpression.CheckedKeywordRole);
3098        if (location != null)
3099          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3100        if (checkedExpression.Expr != null)
3101          result.AddChild((Expression)checkedExpression.Expr.Accept(this), Roles.Expression);
3102        if (location != null && location.Count > 1)
3103          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3104        return result;
3105      }
3106
3107      public override object Visit(UnCheckedExpr uncheckedExpression)
3108      {
3109        var result = new UncheckedExpression();
3110        var location = LocationsBag.GetLocations(uncheckedExpression);
3111        result.AddChild(new CSharpTokenNode(Convert(uncheckedExpression.Location), UncheckedExpression.UncheckedKeywordRole), UncheckedExpression.UncheckedKeywordRole);
3112        if (location != null)
3113          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.LPar), Roles.LPar);
3114        if (uncheckedExpression.Expr != null)
3115          result.AddChild((Expression)uncheckedExpression.Expr.Accept(this), Roles.Expression);
3116        if (location != null && location.Count > 1)
3117          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.RPar), Roles.RPar);
3118        return result;
3119      }
3120
3121      public override object Visit(ElementAccess elementAccessExpression)
3122      {
3123        var result = new IndexerExpression();
3124        var location = LocationsBag.GetLocations(elementAccessExpression);
3125       
3126        if (elementAccessExpression.Expr != null)
3127          result.AddChild((Expression)elementAccessExpression.Expr.Accept(this), Roles.TargetExpression);
3128        result.AddChild(new CSharpTokenNode(Convert(elementAccessExpression.Location), Roles.LBracket), Roles.LBracket);
3129        AddArguments(result, elementAccessExpression.Arguments);
3130        if (location != null)
3131          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.RBracket), Roles.RBracket);
3132        return result;
3133      }
3134
3135      public override object Visit(BaseThis baseAccessExpression)
3136      {
3137        var result = new BaseReferenceExpression();
3138        result.Location = Convert(baseAccessExpression.Location);
3139        return result;
3140      }
3141
3142      public override object Visit(StackAlloc stackAllocExpression)
3143      {
3144        var result = new StackAllocExpression();
3145       
3146        var location = LocationsBag.GetLocations(stackAllocExpression);
3147        if (location != null)
3148          result.AddChild(new CSharpTokenNode(Convert(location [0]), StackAllocExpression.StackallocKeywordRole), StackAllocExpression.StackallocKeywordRole);
3149        if (stackAllocExpression.TypeExpression != null)
3150          result.AddChild(ConvertToType(stackAllocExpression.TypeExpression), Roles.Type);
3151        if (location != null && location.Count > 1)
3152          result.AddChild(new CSharpTokenNode(Convert(location [1]), Roles.LBracket), Roles.LBracket);
3153        if (stackAllocExpression.CountExpression != null)
3154          result.AddChild((Expression)stackAllocExpression.CountExpression.Accept(this), Roles.Expression);
3155        if (location != null && location.Count > 2)
3156          result.AddChild(new CSharpTokenNode(Convert(location [2]), Roles.RBracket), Roles.RBracket);
3157        return result;
3158      }
3159
3160      public override object Visit(SimpleAssign simpleAssign)
3161      {
3162        var result = new AssignmentExpression();
3163       
3164        result.Operator = AssignmentOperatorType.Assign;
3165        if (simpleAssign.Target != null)
3166          result.AddChild((Expression)simpleAssign.Target.Accept(this), AssignmentExpression.LeftRole);
3167        var location = LocationsBag.GetLocations(simpleAssign);
3168        if (location != null)
3169          result.AddChild(new CSharpTokenNode(Convert(location [0]), AssignmentExpression.AssignRole), AssignmentExpression.AssignRole);
3170        if (simpleAssign.Source != null) {
3171          result.AddChild((Expression)simpleAssign.Source.Accept(this), AssignmentExpression.RightRole);
3172        }
3173        return result;
3174      }
3175
3176      public override object Visit(CompoundAssign compoundAssign)
3177      {
3178        var result = new AssignmentExpression();
3179        switch (compoundAssign.Op) {
3180          case Binary.Operator.Multiply:
3181            result.Operator = AssignmentOperatorType.Multiply;
3182            break;
3183          case Binary.Operator.Division:
3184            result.Operator = AssignmentOperatorType.Divide;
3185            break;
3186          case Binary.Operator.Modulus:
3187            result.Operator = AssignmentOperatorType.Modulus;
3188            break;
3189          case Binary.Operator.Addition:
3190            result.Operator = AssignmentOperatorType.Add;
3191            break;
3192          case Binary.Operator.Subtraction:
3193            result.Operator = AssignmentOperatorType.Subtract;
3194            break;
3195          case Binary.Operator.LeftShift:
3196            result.Operator = AssignmentOperatorType.ShiftLeft;
3197            break;
3198          case Binary.Operator.RightShift:
3199            result.Operator = AssignmentOperatorType.ShiftRight;
3200            break;
3201          case Binary.Operator.BitwiseAnd:
3202            result.Operator = AssignmentOperatorType.BitwiseAnd;
3203            break;
3204          case Binary.Operator.BitwiseOr:
3205            result.Operator = AssignmentOperatorType.BitwiseOr;
3206            break;
3207          case Binary.Operator.ExclusiveOr:
3208            result.Operator = AssignmentOperatorType.ExclusiveOr;
3209            break;
3210        }
3211       
3212        if (compoundAssign.Target != null)
3213          result.AddChild((Expression)compoundAssign.Target.Accept(this), AssignmentExpression.LeftRole);
3214        var location = LocationsBag.GetLocations(compoundAssign);
3215        if (location != null) {
3216          var r = AssignmentExpression.GetOperatorRole(result.Operator);
3217          result.AddChild(new CSharpTokenNode(Convert(location [0]), r), r);
3218        }
3219        if (compoundAssign.Source != null)
3220          result.AddChild((Expression)compoundAssign.Source.Accept(this), AssignmentExpression.RightRole);
3221        return result;
3222      }
3223
3224      public override object Visit(Mono.CSharp.AnonymousMethodExpression anonymousMethodExpression)
3225      {
3226        var result = new AnonymousMethodExpression();
3227        var location = LocationsBag.GetLocations(anonymousMethodExpression);
3228        int l = 0;
3229        if (anonymousMethodExpression.IsAsync) {
3230          result.IsAsync = true;
3231          result.AddChild(new CSharpTokenNode(Convert(location [l++]), AnonymousMethodExpression.AsyncModifierRole), AnonymousMethodExpression.AsyncModifierRole);
3232        }
3233        if (location != null) {
3234          result.AddChild(new CSharpTokenNode(Convert(location [l++]), AnonymousMethodExpression.DelegateKeywordRole), AnonymousMethodExpression.DelegateKeywordRole);
3235         
3236          if (location.Count > l) {
3237            result.HasParameterList = true;
3238            result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.LPar), Roles.LPar);
3239            AddParameter(result, anonymousMethodExpression.Parameters);
3240            result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.RPar), Roles.RPar);
3241          }
3242        }
3243        if (anonymousMethodExpression.Block != null)
3244          result.AddChild((BlockStatement)anonymousMethodExpression.Block.Accept(this), Roles.Body);
3245        return result;
3246      }
3247
3248      public override object Visit(Mono.CSharp.LambdaExpression lambdaExpression)
3249      {
3250        var result = new LambdaExpression();
3251        var location = LocationsBag.GetLocations(lambdaExpression);
3252        int l = 0;
3253        if (lambdaExpression.IsAsync) {
3254          result.IsAsync = true;
3255          result.AddChild(new CSharpTokenNode(Convert(location [l++]), LambdaExpression.AsyncModifierRole), LambdaExpression.AsyncModifierRole);
3256        }
3257        if (location == null || location.Count == l + 1) {
3258          if (lambdaExpression.Block != null)
3259            AddParameter(result, lambdaExpression.Parameters);
3260          if (location != null)
3261            result.AddChild(new CSharpTokenNode(Convert(location [l++]), LambdaExpression.ArrowRole), LambdaExpression.ArrowRole);
3262        } else {
3263          result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.LPar), Roles.LPar);
3264          if (lambdaExpression.Block != null)
3265            AddParameter(result, lambdaExpression.Parameters);
3266          if (location != null) {
3267            result.AddChild(new CSharpTokenNode(Convert(location [l++]), Roles.RPar), Roles.RPar);
3268            result.AddChild(new CSharpTokenNode(Convert(location [l++]), LambdaExpression.ArrowRole), LambdaExpression.ArrowRole);
3269          }
3270        }
3271        if (lambdaExpression.Block != null) {
3272          if (lambdaExpression.Block.IsCompilerGenerated) {
3273            var generatedReturn = (ContextualReturn)lambdaExpression.Block.Statements [0];
3274            result.AddChild((AstNode)generatedReturn.Expr.Accept(this), LambdaExpression.BodyRole);
3275          } else {
3276            result.AddChild((AstNode)lambdaExpression.Block.Accept(this), LambdaExpression.BodyRole);
3277          }
3278        }
3279        return result;
3280      }
3281
3282      public override object Visit(ConstInitializer constInitializer)
3283      {
3284        return constInitializer.Expr.Accept(this);
3285      }
3286
3287      public override object Visit(ArrayInitializer arrayInitializer)
3288      {
3289        var result = new ArrayInitializerExpression();
3290        var location = LocationsBag.GetLocations(arrayInitializer);
3291        result.AddChild(new CSharpTokenNode(Convert(arrayInitializer.Location), Roles.LBrace), Roles.LBrace);
3292        var commaLocations = LocationsBag.GetLocations(arrayInitializer.Elements);
3293        for (int i = 0; i < arrayInitializer.Count; i++) {
3294          var init = arrayInitializer [i];
3295          if (init == null)
3296            continue;
3297          result.AddChild((Expression)init.Accept(this), Roles.Expression);
3298          if (commaLocations != null && i < commaLocations.Count)
3299            result.AddChild(new CSharpTokenNode(Convert(commaLocations [i]), Roles.Comma), Roles.Comma);
3300        }
3301       
3302        if (location != null) {
3303          if (location.Count == 2) // optional comma
3304            result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Comma), Roles.Comma);
3305          result.AddChild(new CSharpTokenNode(Convert(location [location.Count - 1]), Roles.RBrace), Roles.RBrace);
3306        }
3307        return result;
3308      }
3309
3310      #endregion
3311
3312      #region LINQ expressions
3313
3314      QueryOrderClause currentQueryOrderClause;
3315
3316      public override object Visit(Mono.CSharp.Linq.QueryExpression queryExpression)
3317      {
3318        var oldQueryOrderClause = currentQueryOrderClause;
3319        try {
3320          currentQueryOrderClause = null;
3321          var result = new QueryExpression();
3322         
3323          var currentClause = queryExpression.next;
3324         
3325          while (currentClause != null) {
3326            var clause = (QueryClause)currentClause.Accept(this);
3327            if (clause is QueryContinuationClause) {
3328              // insert preceding query at beginning of QueryContinuationClause
3329              clause.InsertChildAfter(null, result, QueryContinuationClause.PrecedingQueryRole);
3330              // create a new QueryExpression for the remaining query
3331              result = new QueryExpression();
3332            }
3333            if (clause != null) {
3334              result.AddChild(clause, QueryExpression.ClauseRole);
3335            }
3336            currentClause = currentClause.next;
3337          }
3338         
3339          return result;
3340        } finally {
3341          currentQueryOrderClause = oldQueryOrderClause;
3342        }
3343      }
3344
3345      public override object Visit(Mono.CSharp.Linq.QueryStartClause queryExpression)
3346      {
3347        if (queryExpression.Expr == null) {
3348          var intoClause = new QueryContinuationClause();
3349          intoClause.AddChild(new CSharpTokenNode(Convert(queryExpression.Location), QueryContinuationClause.IntoKeywordRole), QueryContinuationClause.IntoKeywordRole);
3350          intoClause.AddChild(Identifier.Create(queryExpression.IntoVariable.Name, Convert(queryExpression.IntoVariable.Location)), Roles.Identifier);
3351          return intoClause;
3352        }
3353       
3354        var fromClause = new QueryFromClause();
3355
3356        fromClause.AddChild(new CSharpTokenNode(Convert(queryExpression.Location), QueryFromClause.FromKeywordRole), QueryFromClause.FromKeywordRole);
3357       
3358        if (queryExpression.IdentifierType != null)
3359          fromClause.AddChild(ConvertToType(queryExpression.IdentifierType), Roles.Type);
3360       
3361        fromClause.AddChild(Identifier.Create(queryExpression.IntoVariable.Name, Convert(queryExpression.IntoVariable.Location)), Roles.Identifier);
3362       
3363        var location = LocationsBag.GetLocations(queryExpression);
3364        if (location != null)
3365          fromClause.AddChild(new CSharpTokenNode(Convert(location [0]), QueryFromClause.InKeywordRole), QueryFromClause.InKeywordRole);
3366
3367        if (queryExpression.Expr != null)
3368          fromClause.AddChild((Expression)queryExpression.Expr.Accept(this), Roles.Expression);
3369        return fromClause;
3370      }
3371
3372      public override object Visit(Mono.CSharp.Linq.SelectMany selectMany)
3373      {
3374        var fromClause = new QueryFromClause();
3375
3376        fromClause.AddChild(new CSharpTokenNode(Convert(selectMany.Location), QueryFromClause.FromKeywordRole), QueryFromClause.FromKeywordRole);
3377       
3378        if (selectMany.IdentifierType != null)
3379          fromClause.AddChild(ConvertToType(selectMany.IdentifierType), Roles.Type);
3380       
3381        fromClause.AddChild(Identifier.Create(selectMany.IntoVariable.Name, Convert(selectMany.IntoVariable.Location)), Roles.Identifier);
3382       
3383        var location = LocationsBag.GetLocations(selectMany);
3384        if (location != null)
3385          fromClause.AddChild(new CSharpTokenNode(Convert(location [0]), QueryFromClause.InKeywordRole), QueryFromClause.InKeywordRole);
3386
3387        if (selectMany.Expr != null)
3388          fromClause.AddChild((Expression)selectMany.Expr.Accept(this), Roles.Expression);
3389        return fromClause;
3390      }
3391
3392      public override object Visit(Mono.CSharp.Linq.Select select)
3393      {
3394        var result = new QuerySelectClause();
3395        result.AddChild(new CSharpTokenNode(Convert(select.Location), QuerySelectClause.SelectKeywordRole), QuerySelectClause.SelectKeywordRole);
3396        if (select.Expr != null)
3397          result.AddChild((Expression)select.Expr.Accept(this), Roles.Expression);
3398        return result;
3399      }
3400
3401      public override object Visit(Mono.CSharp.Linq.GroupBy groupBy)
3402      {
3403        var result = new QueryGroupClause();
3404        var location = LocationsBag.GetLocations(groupBy);
3405        result.AddChild(new CSharpTokenNode(Convert(groupBy.Location), QueryGroupClause.GroupKeywordRole), QueryGroupClause.GroupKeywordRole);
3406        if (groupBy.ElementSelector != null)
3407          result.AddChild((Expression)groupBy.ElementSelector.Accept(this), QueryGroupClause.ProjectionRole);
3408        if (location != null) {
3409          var byLoc = Convert(location[0]);
3410          if (byLoc.Line > 1 || byLoc.Column > 1)
3411            result.AddChild(new CSharpTokenNode(byLoc, QueryGroupClause.ByKeywordRole), QueryGroupClause.ByKeywordRole);
3412        }
3413        if (groupBy.Expr != null)
3414          result.AddChild((Expression)groupBy.Expr.Accept(this), QueryGroupClause.KeyRole);
3415        return result;
3416      }
3417
3418      public override object Visit(Mono.CSharp.Linq.Let let)
3419      {
3420        var result = new QueryLetClause();
3421        var location = LocationsBag.GetLocations(let);
3422       
3423        result.AddChild(new CSharpTokenNode(Convert(let.Location), QueryLetClause.LetKeywordRole), QueryLetClause.LetKeywordRole);
3424        result.AddChild(Identifier.Create(let.IntoVariable.Name, Convert(let.IntoVariable.Location)), Roles.Identifier);
3425        if (location != null)
3426          result.AddChild(new CSharpTokenNode(Convert(location [0]), Roles.Assign), Roles.Assign);
3427        if (let.Expr != null)
3428          result.AddChild((Expression)let.Expr.Accept(this), Roles.Expression);
3429        return result;
3430      }
3431
3432      public override object Visit(Mono.CSharp.Linq.Where where)
3433      {
3434        var result = new QueryWhereClause();
3435        result.AddChild(new CSharpTokenNode(Convert(where.Location), QueryWhereClause.WhereKeywordRole), QueryWhereClause.WhereKeywordRole);
3436        if (where.Expr != null)
3437          result.AddChild((Expression)where.Expr.Accept(this), Roles.Condition);
3438        return result;
3439      }
3440
3441      public override object Visit(Mono.CSharp.Linq.Join join)
3442      {
3443        var result = new QueryJoinClause();
3444        var location = LocationsBag.GetLocations(join);
3445        result.AddChild(new CSharpTokenNode(Convert(join.Location), QueryJoinClause.JoinKeywordRole), QueryJoinClause.JoinKeywordRole);
3446
3447        if (join.IdentifierType != null)
3448          result.AddChild(ConvertToType(join.IdentifierType), QueryJoinClause.TypeRole);
3449
3450        result.AddChild(Identifier.Create(join.JoinVariable.Name, Convert(join.JoinVariable.Location)), QueryJoinClause.JoinIdentifierRole);
3451
3452        if (join.IdentifierType != null)
3453          result.AddChild(ConvertToType(join.IdentifierType), QueryJoinClause.TypeRole);
3454
3455        if (location != null)
3456          result.AddChild(new CSharpTokenNode(Convert(location [0]), QueryJoinClause.InKeywordRole), QueryJoinClause.InKeywordRole);
3457
3458        if (join.Expr != null)
3459          result.AddChild((Expression)join.Expr.Accept(this), QueryJoinClause.InExpressionRole);
3460       
3461        if (location != null && location.Count > 1)
3462          result.AddChild(new CSharpTokenNode(Convert(location [1]), QueryJoinClause.OnKeywordRole), QueryJoinClause.OnKeywordRole);
3463       
3464        var outer = join.OuterSelector.Statements.FirstOrDefault() as ContextualReturn;
3465        if (outer != null)
3466          result.AddChild((Expression)outer.Expr.Accept(this), QueryJoinClause.OnExpressionRole);
3467       
3468        if (location != null && location.Count > 2)
3469          result.AddChild(new CSharpTokenNode(Convert(location [2]), QueryJoinClause.EqualsKeywordRole), QueryJoinClause.EqualsKeywordRole);
3470       
3471        var inner = join.InnerSelector.Statements.FirstOrDefault() as ContextualReturn;
3472        if (inner != null)
3473          result.AddChild((Expression)inner.Expr.Accept(this), QueryJoinClause.EqualsExpressionRole);
3474       
3475        return result;
3476      }
3477
3478      public override object Visit(Mono.CSharp.Linq.GroupJoin groupJoin)
3479      {
3480        var result = new QueryJoinClause();
3481        var location = LocationsBag.GetLocations(groupJoin);
3482        result.AddChild(new CSharpTokenNode(Convert(groupJoin.Location), QueryJoinClause.JoinKeywordRole), QueryJoinClause.JoinKeywordRole);
3483       
3484        // mcs seems to have swapped IntoVariable with JoinVariable, so we'll swap it back here
3485        result.AddChild(Identifier.Create(groupJoin.IntoVariable.Name, Convert(groupJoin.IntoVariable.Location)), QueryJoinClause.JoinIdentifierRole);
3486       
3487        if (location != null)
3488          result.AddChild(new CSharpTokenNode(Convert(location [0]), QueryJoinClause.InKeywordRole), QueryJoinClause.InKeywordRole);
3489
3490        if (groupJoin.Expr != null)
3491          result.AddChild((Expression)groupJoin.Expr.Accept(this), QueryJoinClause.InExpressionRole);
3492
3493        if (location != null && location.Count > 1)
3494          result.AddChild(new CSharpTokenNode(Convert(location [1]), QueryJoinClause.OnKeywordRole), QueryJoinClause.OnKeywordRole);
3495
3496        var outer = groupJoin.OuterSelector.Statements.FirstOrDefault() as ContextualReturn;
3497        if (outer != null)
3498          result.AddChild((Expression)outer.Expr.Accept(this), QueryJoinClause.OnExpressionRole);
3499       
3500
3501        if (location != null && location.Count > 2)
3502          result.AddChild(new CSharpTokenNode(Convert(location [2]), QueryJoinClause.EqualsKeywordRole), QueryJoinClause.EqualsKeywordRole);
3503        var inner = groupJoin.InnerSelector.Statements.FirstOrDefault() as ContextualReturn;
3504        if (inner != null)
3505          result.AddChild((Expression)inner.Expr.Accept(this), QueryJoinClause.EqualsExpressionRole);
3506       
3507        if (location != null && location.Count > 3)
3508          result.AddChild(new CSharpTokenNode(Convert(location [3]), QueryJoinClause.IntoKeywordRole), QueryJoinClause.IntoKeywordRole);
3509       
3510        result.AddChild(Identifier.Create(groupJoin.JoinVariable.Name, Convert(groupJoin.JoinVariable.Location)), QueryJoinClause.IntoIdentifierRole);
3511        return result;
3512      }
3513
3514      public override object Visit(Mono.CSharp.Linq.OrderByAscending orderByAscending)
3515      {
3516        currentQueryOrderClause = new QueryOrderClause();
3517        var location2 = LocationsBag.GetLocations(orderByAscending.block);
3518        if (location2 != null)
3519          currentQueryOrderClause.AddChild(new CSharpTokenNode(Convert(location2 [0]), QueryOrderClause.OrderbyKeywordRole), QueryOrderClause.OrderbyKeywordRole);
3520        var ordering = new QueryOrdering();
3521        if (orderByAscending.Expr != null)
3522          ordering.AddChild((Expression)orderByAscending.Expr.Accept(this), Roles.Expression);
3523        var location = LocationsBag.GetLocations(orderByAscending);
3524        if (location != null) {
3525          ordering.Direction = QueryOrderingDirection.Ascending;
3526          ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.AscendingKeywordRole), QueryOrdering.AscendingKeywordRole);
3527        }
3528        currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole);
3529        return currentQueryOrderClause;
3530      }
3531
3532      public override object Visit(Mono.CSharp.Linq.OrderByDescending orderByDescending)
3533      {
3534        currentQueryOrderClause = new QueryOrderClause();
3535       
3536        var ordering = new QueryOrdering();
3537        if (orderByDescending.Expr != null)
3538          ordering.AddChild((Expression)orderByDescending.Expr.Accept(this), Roles.Expression);
3539        var location = LocationsBag.GetLocations(orderByDescending);
3540        if (location != null) {
3541          ordering.Direction = QueryOrderingDirection.Descending;
3542          ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.DescendingKeywordRole), QueryOrdering.DescendingKeywordRole);
3543        }
3544        currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole);
3545        return currentQueryOrderClause;
3546      }
3547
3548      public override object Visit(Mono.CSharp.Linq.ThenByAscending thenByAscending)
3549      {
3550        var ordering = new QueryOrdering();
3551        if (thenByAscending.Expr != null)
3552          ordering.AddChild((Expression)thenByAscending.Expr.Accept(this), Roles.Expression);
3553        var location = LocationsBag.GetLocations(thenByAscending);
3554        if (location != null) {
3555          ordering.Direction = QueryOrderingDirection.Ascending;
3556          ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.AscendingKeywordRole), QueryOrdering.AscendingKeywordRole);
3557        }
3558        currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole);
3559        return null;
3560      }
3561
3562      public override object Visit(Mono.CSharp.Linq.ThenByDescending thenByDescending)
3563      {
3564        var ordering = new QueryOrdering();
3565        if (thenByDescending.Expr != null)
3566          ordering.AddChild((Expression)thenByDescending.Expr.Accept(this), Roles.Expression);
3567        var location = LocationsBag.GetLocations(thenByDescending);
3568        if (location != null) {
3569          ordering.Direction = QueryOrderingDirection.Descending;
3570          ordering.AddChild(new CSharpTokenNode(Convert(location [0]), QueryOrdering.DescendingKeywordRole), QueryOrdering.DescendingKeywordRole);
3571        }
3572        currentQueryOrderClause.AddChild(ordering, QueryOrderClause.OrderingRole);
3573        return null;
3574      }
3575
3576      public override object Visit(Await awaitExpr)
3577      {
3578        var result = new UnaryOperatorExpression();
3579        result.Operator = UnaryOperatorType.Await;
3580        result.AddChild(new CSharpTokenNode(Convert(awaitExpr.Location), UnaryOperatorExpression.AwaitRole), UnaryOperatorExpression.AwaitRole);
3581        if (awaitExpr.Expression != null)
3582          result.AddChild((Expression)awaitExpr.Expression.Accept(this), Roles.Expression);
3583        return result;
3584      }
3585
3586      #endregion
3587
3588      #region XmlDoc
3589
3590      public DocumentationReference ConvertXmlDoc(DocumentationBuilder doc)
3591      {
3592        var result = new DocumentationReference();
3593        if (doc.ParsedName != null) {
3594          if (doc.ParsedName.Name == "<this>") {
3595            result.SymbolKind = SymbolKind.Indexer;
3596          } else {
3597            result.MemberName = doc.ParsedName.Name;
3598          }
3599          if (doc.ParsedName.Left != null) {
3600            result.DeclaringType = ConvertToType(doc.ParsedName.Left);
3601          } else if (doc.ParsedBuiltinType != null) {
3602            result.DeclaringType = ConvertToType(doc.ParsedBuiltinType);
3603          }
3604          if (doc.ParsedName.TypeParameters != null) {
3605            for (int i = 0; i < doc.ParsedName.TypeParameters.Count; i++) {
3606              result.TypeArguments.Add(ConvertToType(doc.ParsedName.TypeParameters [i]));
3607            }
3608          }
3609        } else if (doc.ParsedBuiltinType != null) {
3610          result.SymbolKind = SymbolKind.TypeDefinition;
3611          result.DeclaringType = ConvertToType(doc.ParsedBuiltinType);
3612        }
3613        if (doc.ParsedParameters != null) {
3614          result.HasParameterList = true;
3615          result.Parameters.AddRange(doc.ParsedParameters.Select(ConvertXmlDocParameter));
3616        }
3617        if (doc.ParsedOperator != null) {
3618          result.SymbolKind = SymbolKind.Operator;
3619          result.OperatorType = (OperatorType)doc.ParsedOperator;
3620          if (result.OperatorType == OperatorType.Implicit || result.OperatorType == OperatorType.Explicit) {
3621            var returnTypeParam = result.Parameters.LastOrNullObject();
3622            returnTypeParam.Remove(); // detach from parameter list
3623            var returnType = returnTypeParam.Type;
3624            returnType.Remove();
3625            result.ConversionOperatorReturnType = returnType;
3626          }
3627          if (result.Parameters.Count == 0) {
3628            // reset HasParameterList if necessary
3629            result.HasParameterList = false;
3630          }
3631        }
3632        return result;
3633      }
3634
3635      ParameterDeclaration ConvertXmlDocParameter(DocumentationParameter p)
3636      {
3637        var result = new ParameterDeclaration();
3638        switch (p.Modifier) {
3639          case Parameter.Modifier.OUT:
3640            result.ParameterModifier = ParameterModifier.Out;
3641            break;
3642          case Parameter.Modifier.REF:
3643            result.ParameterModifier = ParameterModifier.Ref;
3644            break;
3645          case Parameter.Modifier.PARAMS:
3646            result.ParameterModifier = ParameterModifier.Params;
3647            break;
3648        }
3649        if (p.Type != null) {
3650          result.Type = ConvertToType(p.Type);
3651        }
3652        return result;
3653      }
3654
3655      #endregion
3656
3657    }
3658
3659    public CSharpParser()
3660    {
3661      compilerSettings = new CompilerSettings();
3662    }
3663
3664    public CSharpParser(CompilerSettings args)
3665    {
3666      compilerSettings = args ?? new CompilerSettings();
3667    }
3668
3669    void InsertComments(CompilerCompilationUnit top, ConversionVisitor conversionVisitor)
3670    {
3671      AstNode insertionPoint = conversionVisitor.Unit.FirstChild;
3672      foreach (var special in top.SpecialsBag.Specials) {
3673        AstNode newLeaf = null;
3674        Role role = null;
3675        bool isDocumentationComment = false;
3676        var comment = special as SpecialsBag.Comment;
3677        if (comment != null) {
3678          // HACK: multiline documentation comment detection; better move this logic into the mcs tokenizer
3679          bool isMultilineDocumentationComment = (comment.CommentType == SpecialsBag.CommentType.Multi && comment.Content.StartsWith("*", StringComparison.Ordinal) && !comment.Content.StartsWith("**", StringComparison.Ordinal));
3680          isDocumentationComment = comment.CommentType == SpecialsBag.CommentType.Documentation || isMultilineDocumentationComment;
3681          if (conversionVisitor.convertTypeSystemMode && !isDocumentationComment)
3682            continue;
3683          var type = isMultilineDocumentationComment ? CommentType.MultiLineDocumentation : (CommentType)comment.CommentType;
3684          var start = new TextLocation(comment.Line, comment.Col);
3685          var end = new TextLocation(comment.EndLine, comment.EndCol);
3686          newLeaf = new Comment(type, start, end) {
3687            StartsLine = comment.StartsLine,
3688            Content = isMultilineDocumentationComment ? comment.Content.Substring(1) : comment.Content
3689          };
3690          role = Roles.Comment;
3691        } else if (!GenerateTypeSystemMode) {
3692          var pragmaDirective = special as SpecialsBag.PragmaPreProcessorDirective;
3693          if (pragmaDirective != null) {
3694            var pragma = new PragmaWarningPreprocessorDirective(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), new TextLocation(pragmaDirective.EndLine, pragmaDirective.EndCol));
3695            pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.Col), PragmaWarningPreprocessorDirective.PragmaKeywordRole), PragmaWarningPreprocessorDirective.PragmaKeywordRole);
3696            pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.WarningColumn), PragmaWarningPreprocessorDirective.WarningKeywordRole), PragmaWarningPreprocessorDirective.WarningKeywordRole);
3697            var pragmaRole = pragmaDirective.Disalbe ? PragmaWarningPreprocessorDirective.DisableKeywordRole : PragmaWarningPreprocessorDirective.RestoreKeywordRole;
3698            pragma.AddChild(new CSharpTokenNode(new TextLocation(pragmaDirective.Line, pragmaDirective.DisableRestoreColumn), pragmaRole), pragmaRole);
3699            foreach (var code in pragmaDirective.Codes) {
3700              pragma.AddChild((PrimitiveExpression)conversionVisitor.Visit(code), PragmaWarningPreprocessorDirective.WarningRole);
3701            }
3702            newLeaf = pragma;
3703            role = Roles.PreProcessorDirective;
3704            goto end;
3705          }
3706          var lineDirective = special as SpecialsBag.LineProcessorDirective;
3707          if (lineDirective != null) {
3708            var pragma = new LinePreprocessorDirective(new TextLocation(lineDirective.Line, lineDirective.Col), new TextLocation(lineDirective.EndLine, lineDirective.EndCol));
3709            pragma.LineNumber = lineDirective.LineNumber;
3710            pragma.FileName = lineDirective.FileName;
3711            newLeaf = pragma;
3712            role = Roles.PreProcessorDirective;
3713            goto end;
3714          }
3715          var directive = special as SpecialsBag.PreProcessorDirective;
3716          if (directive != null) {
3717            newLeaf = new PreProcessorDirective((PreProcessorDirectiveType)((int)directive.Cmd & 0xF), new TextLocation(directive.Line, directive.Col), new TextLocation(directive.EndLine, directive.EndCol)) {
3718              Argument = directive.Arg,
3719              Take = directive.Take
3720            };
3721            role = Roles.PreProcessorDirective;
3722          }
3723          end:
3724          ;
3725        }
3726        if (newLeaf != null) {
3727          InsertComment(ref insertionPoint, newLeaf, role, isDocumentationComment, conversionVisitor.Unit);
3728        }
3729      }
3730      if (!GenerateTypeSystemMode) {
3731        // We cannot insert newlines in the same loop as comments/preprocessor directives
3732        // because they are not correctly ordered in the specials bag
3733        insertionPoint = conversionVisitor.Unit.FirstChild;
3734        for (int i = 0; i < top.SpecialsBag.Specials.Count; i++) {
3735          var newLine = top.SpecialsBag.Specials [i] as SpecialsBag.NewLineToken;
3736          if (newLine != null) {
3737            var newLeaf = new NewLineNode(new TextLocation(newLine.Line, newLine.Col + 1));
3738            newLeaf.NewLineType = newLine.NewLine == SpecialsBag.NewLine.Unix ? UnicodeNewline.LF : UnicodeNewline.CRLF;
3739            InsertComment(ref insertionPoint, newLeaf, Roles.NewLine, false, conversionVisitor.Unit);
3740          }
3741        }
3742      }
3743    }
3744
3745    static void InsertComment(ref AstNode insertionPoint, AstNode newNode, Role role, bool isDocumentationComment, AstNode rootNode)
3746    {
3747      TextLocation insertAt = newNode.StartLocation;
3748      // Advance insertionPoint to the first node that has a start location >= insertAt
3749      while (insertionPoint != null && insertionPoint.StartLocation < insertAt) {
3750        // Enter the current node if insertAt is within
3751        while (insertAt < insertionPoint.EndLocation && insertionPoint.FirstChild != null) {
3752          insertionPoint = insertionPoint.FirstChild;
3753        }
3754        // Go to next node (insertionPoint.NextSibling if it exists; otherwise the next sibling of the parent node etc.)
3755        insertionPoint = insertionPoint.GetNextNode();
3756      }
3757      // As a special case, XmlDoc gets inserted at the beginning of the entity declaration
3758      if (isDocumentationComment && insertionPoint is EntityDeclaration && insertionPoint.FirstChild != null) {
3759        insertionPoint = insertionPoint.FirstChild;
3760      }
3761      if (insertionPoint == null) {
3762        // we're at the end of the compilation unit
3763        rootNode.AddChildUnsafe(newNode, role);
3764      } else {
3765        insertionPoint.Parent.InsertChildBeforeUnsafe(insertionPoint, newNode, role);
3766      }
3767    }
3768
3769    public class ErrorReportPrinter : ReportPrinter
3770    {
3771      readonly string fileName;
3772      public readonly List<Error> Errors = new List<Error>();
3773
3774      public ErrorReportPrinter(string fileName)
3775      {
3776        this.fileName = fileName;
3777      }
3778
3779      public override void Print(AbstractMessage msg, bool showFullPath)
3780      {
3781        base.Print(msg, showFullPath);
3782        var newError = new Error(msg.IsWarning ? ErrorType.Warning : ErrorType.Error, msg.Text, new DomRegion(fileName, msg.Location.Row, msg.Location.Column));
3783        Errors.Add(newError);
3784      }
3785    }
3786
3787    ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter(null);
3788
3789    [Obsolete("Use the Errors/Warnings/ErrorsAndWarnings properties instead")]
3790    public ErrorReportPrinter ErrorPrinter {
3791      get {
3792        return errorReportPrinter;
3793      }
3794    }
3795
3796    public bool HasErrors {
3797      get {
3798        return errorReportPrinter.ErrorsCount > 0;
3799      }
3800    }
3801
3802    public bool HasWarnings {
3803      get {
3804        return errorReportPrinter.WarningsCount > 0;
3805      }
3806    }
3807
3808    public IEnumerable<Error> Errors {
3809      get {
3810        return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Error);
3811      }
3812    }
3813
3814    public IEnumerable<Error> Warnings {
3815      get {
3816        return errorReportPrinter.Errors.Where(e => e.ErrorType == ErrorType.Warning);
3817      }
3818    }
3819
3820    public IEnumerable<Error> ErrorsAndWarnings {
3821      get { return errorReportPrinter.Errors; }
3822    }
3823
3824    /// <summary>
3825    /// Parses a C# code file.
3826    /// </summary>
3827    /// <param name="program">The source code to parse.</param>
3828    /// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
3829    /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
3830    /// <returns>Returns the syntax tree.</returns>
3831    public SyntaxTree Parse(string program, string fileName = "")
3832    {
3833      return Parse(new StringTextSource(program), fileName);
3834    }
3835
3836    /// <summary>
3837    /// Parses a C# code file.
3838    /// </summary>
3839    /// <param name="reader">The text reader containing the source code to parse.</param>
3840    /// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
3841    /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
3842    /// <returns>Returns the syntax tree.</returns>
3843    public SyntaxTree Parse(TextReader reader, string fileName = "")
3844    {
3845      return Parse(new StringTextSource(reader.ReadToEnd()), fileName);
3846    }
3847
3848    /// <summary>
3849    /// Converts a Mono.CSharp syntax tree into an NRefactory syntax tree.
3850    /// </summary>
3851    public SyntaxTree Parse(CompilerCompilationUnit top, string fileName)
3852    {
3853      if (top == null) {
3854        return null;
3855      }
3856      CSharpParser.ConversionVisitor conversionVisitor = new ConversionVisitor(GenerateTypeSystemMode, top.LocationsBag);
3857      top.ModuleCompiled.Accept(conversionVisitor);
3858      InsertComments(top, conversionVisitor);
3859      if (CompilationUnitCallback != null) {
3860        CompilationUnitCallback(top);
3861      }
3862      var expr = top.LastYYValue as Mono.CSharp.Expression;
3863      if (expr != null)
3864        conversionVisitor.Unit.TopExpression = expr.Accept(conversionVisitor) as AstNode;
3865
3866      conversionVisitor.Unit.FileName = fileName;
3867      var conditionals = new List<string>();
3868      foreach (var settings in compilerSettings.ConditionalSymbols) {
3869        if (top.Conditionals.ContainsKey(settings) && !top.Conditionals [settings])
3870          continue;
3871        conditionals.Add(settings);
3872      }
3873      foreach (var kv in top.Conditionals) {
3874        if (!kv.Value || compilerSettings.ConditionalSymbols.Contains(kv.Key))
3875          continue;
3876        conditionals.Add(kv.Key);
3877      }
3878      conversionVisitor.Unit.ConditionalSymbols = conditionals;
3879      return conversionVisitor.Unit;
3880    }
3881
3882    public CompilerSettings CompilerSettings {
3883      get { return compilerSettings; }
3884      set {
3885        if (value == null)
3886          throw new ArgumentNullException();
3887        compilerSettings = value;
3888      }
3889    }
3890
3891    /// <summary>
3892    /// Callback that gets called with the Mono.CSharp syntax tree whenever some code is parsed.
3893    /// </summary>
3894    public Action<CompilerCompilationUnit> CompilationUnitCallback {
3895      get;
3896      set;
3897    }
3898
3899    /// <summary>
3900    /// Specifies whether to run the parser in a special mode for generating the type system.
3901    /// If this property is true, the syntax tree will only contain nodes relevant for the
3902    /// <see cref="SyntaxTree.ToTypeSystem()"/> call and might be missing other nodes (e.g. method bodies).
3903    /// The default is false.
3904    /// </summary>
3905    public bool GenerateTypeSystemMode {
3906      get;
3907      set;
3908    }
3909
3910    TextLocation initialLocation = new TextLocation(1, 1);
3911
3912    /// <summary>
3913    /// Specifies the text location where parsing starts.
3914    /// This property can be used when parsing a part of a file to make the locations of the AstNodes
3915    /// refer to the position in the whole file.
3916    /// The default is (1,1).
3917    /// </summary>
3918    public TextLocation InitialLocation {
3919      get { return initialLocation; }
3920      set { initialLocation = value; }
3921    }
3922
3923    internal static object parseLock = new object();
3924
3925    /// <summary>
3926    /// Parses a C# code file.
3927    /// </summary>
3928    /// <param name="stream">The stream containing the source code to parse.</param>
3929    /// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
3930    /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
3931    /// <returns>Returns the syntax tree.</returns>
3932    public SyntaxTree Parse(Stream stream, string fileName = "")
3933    {
3934      return Parse(new StreamReader(stream), fileName);
3935    }
3936
3937    /// <summary>
3938    /// Parses a C# code file.
3939    /// </summary>
3940    /// <param name="program">The source code to parse.</param>
3941    /// <param name="fileName">The file name. Used to identify the file (e.g. when building a type system).
3942    /// This can be an arbitrary identifier, NRefactory never tries to access the file on disk.</param>
3943    /// <returns>Returns the syntax tree.</returns>
3944    public SyntaxTree Parse(ITextSource program, string fileName = "")
3945    {
3946      return Parse(program, fileName, initialLocation.Line, initialLocation.Column);
3947    }
3948
3949    SyntaxTree Parse(ITextSource program, string fileName, int initialLine, int initialColumn)
3950    {
3951      lock (parseLock) {
3952        errorReportPrinter = new ErrorReportPrinter("");
3953        var ctx = new CompilerContext(compilerSettings.ToMono(), errorReportPrinter);
3954        ctx.Settings.TabSize = 1;
3955        var reader = new SeekableStreamReader(program);
3956        var file = new SourceFile(fileName, fileName, 0);
3957        Location.Initialize(new List<SourceFile>(new [] { file }));
3958        var module = new ModuleContainer(ctx);
3959        var session = new ParserSession();
3960        session.LocationsBag = new LocationsBag();
3961        var report = new Report(ctx, errorReportPrinter);
3962        var parser = Driver.Parse(reader, file, module, session, report, initialLine - 1, initialColumn - 1);
3963        var top = new CompilerCompilationUnit {
3964          ModuleCompiled = module,
3965          LocationsBag = session.LocationsBag,
3966          SpecialsBag = parser.Lexer.sbag,
3967          Conditionals = parser.Lexer.SourceFile.Conditionals
3968        };
3969        var unit = Parse(top, fileName);
3970        unit.Errors.AddRange(errorReportPrinter.Errors);
3971        CompilerCallableEntryPoint.Reset();
3972        return unit;
3973      }
3974    }
3975
3976    public IEnumerable<EntityDeclaration> ParseTypeMembers(string code)
3977    {
3978      return ParseTypeMembers(code, initialLocation.Line, initialLocation.Column);
3979    }
3980
3981    IEnumerable<EntityDeclaration> ParseTypeMembers(string code, int initialLine, int initialColumn)
3982    {
3983      const string prefix = "unsafe partial class MyClass { ";
3984      var syntaxTree = Parse(new StringTextSource(prefix + code + "}"), "parsed.cs", initialLine, initialColumn - prefix.Length);
3985      if (syntaxTree == null)
3986        return Enumerable.Empty<EntityDeclaration>();
3987      var td = syntaxTree.FirstChild as TypeDeclaration;
3988      if (td != null) {
3989        var members = td.Members.ToArray();
3990        // detach members from parent
3991        foreach (var m in members)
3992          m.Remove();
3993        return members;
3994      }
3995      return Enumerable.Empty<EntityDeclaration>();
3996    }
3997
3998    public IEnumerable<Statement> ParseStatements(string code)
3999    {
4000      return ParseStatements(code, initialLocation.Line, initialLocation.Column);
4001    }
4002
4003    IEnumerable<Statement> ParseStatements(string code, int initialLine, int initialColumn)
4004    {
4005      // the dummy method is async so that 'await' expressions are parsed as expected
4006      const string prefix = "async void M() { ";
4007      var members = ParseTypeMembers(prefix + code + "}", initialLine, initialColumn - prefix.Length);
4008      var method = members.FirstOrDefault() as MethodDeclaration;
4009      if (method != null && method.Body != null) {
4010        var statements = method.Body.Statements.ToArray();
4011        // detach statements from parent
4012        foreach (var st in statements)
4013          st.Remove();
4014        return statements;
4015      }
4016      return Enumerable.Empty<Statement>();
4017    }
4018
4019    public AstType ParseTypeReference(string code)
4020    {
4021      var members = ParseTypeMembers(code + " a;");
4022      var field = members.FirstOrDefault() as FieldDeclaration;
4023      if (field != null) {
4024        AstType type = field.ReturnType;
4025        type.Remove();
4026        return type;
4027      }
4028      return AstType.Null;
4029    }
4030
4031    public Expression ParseExpression(string code)
4032    {
4033      const string prefix = "tmp = ";
4034      var statements = ParseStatements(prefix + code + ";", initialLocation.Line, initialLocation.Column - prefix.Length);
4035      var es = statements.FirstOrDefault() as ExpressionStatement;
4036      if (es != null) {
4037        var ae = es.Expression as AssignmentExpression;
4038        if (ae != null) {
4039          Expression expr = ae.Right;
4040          expr.Remove();
4041          return expr;
4042        }
4043      }
4044      return Expression.Null;
4045    }
4046    /*
4047    /// <summary>
4048    /// Parses a file snippet; guessing what the code snippet represents (whole file, type members, block, type reference, expression).
4049    /// </summary>
4050    public AstNode ParseSnippet (string code)
4051    {
4052      // TODO: add support for parsing a part of a file
4053      throw new NotImplementedException ();
4054    }
4055     */
4056    public DocumentationReference ParseDocumentationReference(string cref)
4057    {
4058      // see Mono.CSharp.DocumentationBuilder.HandleXrefCommon
4059      if (cref == null)
4060        throw new ArgumentNullException("cref");
4061     
4062      // Additional symbols for < and > are allowed for easier XML typing
4063      cref = cref.Replace('{', '<').Replace('}', '>');
4064     
4065      lock (parseLock) {
4066        errorReportPrinter = new ErrorReportPrinter("");
4067        var ctx = new CompilerContext(compilerSettings.ToMono(), errorReportPrinter);
4068        ctx.Settings.TabSize = 1;
4069        var reader = new SeekableStreamReader(new StringTextSource(cref));
4070        var file = new SourceFile("", "", 0);
4071        Location.Initialize(new List<SourceFile>(new [] { file }));
4072        var module = new ModuleContainer(ctx);
4073        module.DocumentationBuilder = new DocumentationBuilder(module);
4074        var source_file = new CompilationSourceFile(module);
4075        var report = new Report(ctx, errorReportPrinter);
4076        var session = new ParserSession();
4077        session.LocationsBag = new LocationsBag();
4078        var parser = new Mono.CSharp.CSharpParser(reader, source_file, report, session);
4079        parser.Lexer.Line += initialLocation.Line - 1;
4080        parser.Lexer.Column += initialLocation.Column - 1;
4081        parser.Lexer.putback_char = Tokenizer.DocumentationXref;
4082        parser.Lexer.parsing_generic_declaration_doc = true;
4083        parser.parse();
4084        if (report.Errors > 0) {
4085//          Report.Warning (1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
4086//                          mc.GetSignatureForError (), cref);
4087        }
4088       
4089        var conversionVisitor = new ConversionVisitor(false, session.LocationsBag);
4090        var docRef = conversionVisitor.ConvertXmlDoc(module.DocumentationBuilder);
4091        CompilerCallableEntryPoint.Reset();
4092        return docRef;
4093      }
4094    }
4095  }
4096}
Note: See TracBrowser for help on using the repository browser.