5
// Mike KrĆ¼ger <mkrueger@novell.com>
7
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
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:
16
// The above copyright notice and this permission notice shall be included in
17
// all copies or substantial portions of the Software.
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
29
using System.Collections.Generic;
33
using Mono.TextEditor;
34
using MonoDevelop.CSharp.Ast;
35
using MonoDevelop.Projects.Dom;
36
using MonoDevelop.Projects.Dom.Parser;
37
using MonoDevelop.CSharp.Resolver;
38
using MonoDevelop.Projects;
39
using MonoDevelop.CSharp.Project;
42
namespace MonoDevelop.CSharp.Parser
44
public class McsParser : AbstractParser
46
public override IExpressionFinder CreateExpressionFinder (ProjectDom dom)
48
return new NewCSharpExpressionFinder (dom);
51
public override IResolver CreateResolver (ProjectDom dom, object editor, string fileName)
53
MonoDevelop.Ide.Gui.Document doc = (MonoDevelop.Ide.Gui.Document)editor;
54
return new NRefactoryResolver (dom, doc.CompilationUnit, ICSharpCode.NRefactory.SupportedLanguage.CSharp, doc.Editor, fileName);
57
public class ErrorReportPrinter : ReportPrinter
59
public readonly List<Error> Errors = new List<Error> ();
61
public override void Print (AbstractMessage msg)
64
Error newError = new Error (msg.IsWarning ? ErrorType.Warning : ErrorType.Error, msg.Location.Row, msg.Location.Column, msg.Text);
65
Errors.Add (newError);
69
static string GetLangString (LangVersion ver)
72
case LangVersion.Default:
74
case LangVersion.ISO_1:
76
case LangVersion.ISO_2:
82
public override ParsedDocument Parse (ProjectDom dom, string fileName, string content)
84
lock (CompilerCallableEntryPoint.parseLock) {
85
if (string.IsNullOrEmpty (content))
87
var tagComments = ProjectDomService.SpecialCommentTags.GetNames ();
88
List<string> compilerArguments = new List<string> ();
89
if (dom != null && dom.Project != null && MonoDevelop.Ide.IdeApp.Workspace != null) {
90
DotNetProjectConfiguration configuration = dom.Project.GetConfiguration (MonoDevelop.Ide.IdeApp.Workspace.ActiveConfiguration) as DotNetProjectConfiguration;
91
CSharpCompilerParameters par = configuration != null ? configuration.CompilationParameters as CSharpCompilerParameters : null;
93
if (!string.IsNullOrEmpty (par.DefineSymbols)) {
94
compilerArguments.Add ("-define:" + string.Join (";", par.DefineSymbols.Split (';', ',', ' ', '\t')));
97
compilerArguments.Add ("-unsafe");
98
if (par.TreatWarningsAsErrors)
99
compilerArguments.Add ("-warnaserror");
100
if (!string.IsNullOrEmpty (par.NoWarnings))
101
compilerArguments.Add ("-nowarn:"+ string.Join (",", par.NoWarnings.Split (';', ',', ' ', '\t')));
102
compilerArguments.Add ("-warn:" + par.WarningLevel);
103
compilerArguments.Add ("-langversion:" + GetLangString (par.LangVersion));
104
if (par.GenerateOverflowChecks)
105
compilerArguments.Add ("-checked");
109
var unit = new MonoDevelop.Projects.Dom.CompilationUnit (fileName);
110
var result = new ParsedDocument (fileName);
111
result.CompilationUnit = unit;
113
CompilerCompilationUnit top;
114
ErrorReportPrinter errorReportPrinter = new ErrorReportPrinter ();
115
using (var stream = new MemoryStream (Encoding.Default.GetBytes (content))) {
116
top = CompilerCallableEntryPoint.ParseFile (compilerArguments.ToArray (), stream, fileName, errorReportPrinter);
121
foreach (var special in top.SpecialsBag.Specials) {
122
var comment = special as SpecialsBag.Comment;
123
if (comment != null) {
124
VisitComment (result, comment, tagComments);
126
VisitPreprocessorDirective (result, special as SpecialsBag.PreProcessorDirective);
131
var conversionVisitor = new ConversionVisitor (top.LocationsBag);
132
conversionVisitor.Dom = dom;
133
conversionVisitor.ParsedDocument = result;
134
conversionVisitor.Unit = unit;
135
top.UsingsBag.Global.Accept (conversionVisitor);
136
top.ModuleCompiled.Accept (conversionVisitor);
139
unit.Tag = CSharpParser.Parse (top);
140
} catch (Exception ex) {
141
System.Console.WriteLine (ex);
145
errorReportPrinter.Errors.ForEach (e => conversionVisitor.ParsedDocument.Add (e));
150
void VisitComment (ParsedDocument result, SpecialsBag.Comment comment, string[] tagComments)
152
var cmt = new MonoDevelop.Projects.Dom.Comment (comment.Content);
153
cmt.CommentStartsLine = comment.StartsLine;
154
switch (comment.CommentType) {
155
case SpecialsBag.CommentType.Multi:
156
cmt.CommentType = MonoDevelop.Projects.Dom.CommentType.MultiLine;
158
cmt.ClosingTag = "*/";
160
case SpecialsBag.CommentType.Single:
161
cmt.CommentType = MonoDevelop.Projects.Dom.CommentType.SingleLine;
164
case SpecialsBag.CommentType.Documentation:
165
cmt.CommentType = MonoDevelop.Projects.Dom.CommentType.SingleLine;
166
cmt.IsDocumentation = true;
170
cmt.Region = new DomRegion (comment.Line, comment.Col, comment.EndLine, comment.EndCol);
171
result.Comments.Add (cmt);
172
foreach (string tag in tagComments) {
173
int idx = comment.Content.IndexOf (tag);
176
result.Add (new Tag (tag, comment.Content, cmt.Region));
180
Stack<SpecialsBag.PreProcessorDirective> regions = new Stack<SpecialsBag.PreProcessorDirective> ();
181
Stack<SpecialsBag.PreProcessorDirective> ifBlocks = new Stack<SpecialsBag.PreProcessorDirective> ();
182
List<SpecialsBag.PreProcessorDirective> elifBlocks = new List<SpecialsBag.PreProcessorDirective> ();
183
SpecialsBag.PreProcessorDirective elseBlock = null;
185
Stack<ConditionalRegion> conditionalRegions = new Stack<ConditionalRegion> ();
186
ConditionalRegion ConditionalRegion {
188
return conditionalRegions.Count > 0 ? conditionalRegions.Peek () : null;
192
void CloseConditionBlock (DomLocation loc)
194
if (ConditionalRegion == null || ConditionalRegion.ConditionBlocks.Count == 0 || !ConditionalRegion.ConditionBlocks[ConditionalRegion.ConditionBlocks.Count - 1].End.IsEmpty)
196
ConditionalRegion.ConditionBlocks[ConditionalRegion.ConditionBlocks.Count - 1].End = loc;
199
void AddCurRegion (ParsedDocument result, int line, int col)
201
if (ConditionalRegion == null)
203
ConditionalRegion.End = new DomLocation (line, col);
204
result.Add (ConditionalRegion);
205
conditionalRegions.Pop ();
208
static ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor visitor = new ICSharpCode.NRefactory.PrettyPrinter.CSharpOutputVisitor ();
210
void VisitPreprocessorDirective (ParsedDocument result, SpecialsBag.PreProcessorDirective directive)
212
DomLocation loc = new DomLocation (directive.Line, directive.Col);
213
switch (directive.Cmd) {
214
case Tokenizer.PreprocessorDirective.If:
215
conditionalRegions.Push (new ConditionalRegion (visitor.Text));
216
ifBlocks.Push (directive);
217
ConditionalRegion.Start = loc;
219
case Tokenizer.PreprocessorDirective.Elif:
220
CloseConditionBlock (new DomLocation (directive.EndLine, directive.EndCol));
221
if (ConditionalRegion != null)
222
ConditionalRegion.ConditionBlocks.Add (new ConditionBlock (visitor.Text, loc));
224
case Tokenizer.PreprocessorDirective.Else:
225
CloseConditionBlock (new DomLocation (directive.EndLine, directive.EndCol));
226
if (ConditionalRegion != null)
227
ConditionalRegion.ElseBlock = new DomRegion (loc, DomLocation.Empty);
229
case Tokenizer.PreprocessorDirective.Endif:
230
DomLocation endLoc = new DomLocation (directive.EndLine, directive.EndCol);
231
CloseConditionBlock (endLoc);
232
if (ConditionalRegion != null && !ConditionalRegion.ElseBlock.Start.IsEmpty)
233
ConditionalRegion.ElseBlock = new DomRegion (ConditionalRegion.ElseBlock.Start, endLoc);
234
AddCurRegion (result, directive.EndLine, directive.EndCol);
235
if (ifBlocks.Count > 0) {
236
var ifBlock = ifBlocks.Pop ();
237
DomRegion dr = new DomRegion (ifBlock.Line, ifBlock.Col, directive.EndLine, directive.EndCol);
238
result.Add (new FoldingRegion ("#if " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
239
foreach (var d in elifBlocks) {
240
dr.Start = new DomLocation (d.Line, d.Col);
241
result.Add (new FoldingRegion ("#elif " + ifBlock.Arg.Trim (), dr, FoldType.UserRegion, false));
243
if (elseBlock != null) {
244
dr.Start = new DomLocation (elseBlock.Line, elseBlock.Col);
245
result.Add (new FoldingRegion ("#else", dr, FoldType.UserRegion, false));
250
case Tokenizer.PreprocessorDirective.Define:
251
result.Add (new PreProcessorDefine (directive.Arg, loc));
253
case Tokenizer.PreprocessorDirective.Region:
254
regions.Push (directive);
256
case Tokenizer.PreprocessorDirective.Endregion:
257
if (regions.Count > 0) {
258
var start = regions.Pop ();
259
DomRegion dr = new DomRegion (start.Line, start.Col, directive.EndLine, directive.EndCol);
260
result.Add (new FoldingRegion (start.Arg, dr, FoldType.UserRegion, true));
266
class ConversionVisitor : StructuralVisitor
268
public ProjectDom Dom {
273
public ParsedDocument ParsedDocument {
278
public LocationsBag LocationsBag {
283
public MonoDevelop.Projects.Dom.CompilationUnit Unit {
287
static string[] keywordTable;
288
static ConversionVisitor ()
290
keywordTable = new string[255];
291
for (int i = 0; i < 255; i++)
292
keywordTable [i] = DomReturnType.Void.FullName;
294
keywordTable [(int)BuiltinTypeSpec.Type.Other] = DomReturnType.Void.FullName;
295
keywordTable [(int)BuiltinTypeSpec.Type.String] = DomReturnType.String.FullName;
296
keywordTable [(int)BuiltinTypeSpec.Type.Int] = DomReturnType.Int32.FullName;
297
keywordTable [(int)BuiltinTypeSpec.Type.UInt] = DomReturnType.UInt32.FullName;
298
keywordTable [(int)BuiltinTypeSpec.Type.Long] = DomReturnType.Int64.FullName;
299
keywordTable [(int)BuiltinTypeSpec.Type.ULong] = DomReturnType.UInt64.FullName;
300
keywordTable [(int)BuiltinTypeSpec.Type.Object] = DomReturnType.Object.FullName;
301
keywordTable [(int)BuiltinTypeSpec.Type.Float] = DomReturnType.Float.FullName;
302
keywordTable [(int)BuiltinTypeSpec.Type.Double] = DomReturnType.Double.FullName;
303
keywordTable [(int)BuiltinTypeSpec.Type.Byte] = DomReturnType.Byte.FullName;
304
keywordTable [(int)BuiltinTypeSpec.Type.SByte] = DomReturnType.SByte.FullName;
305
keywordTable [(int)BuiltinTypeSpec.Type.Short] = DomReturnType.Int16.FullName;
306
keywordTable [(int)BuiltinTypeSpec.Type.UShort] = DomReturnType.UInt16.FullName;
307
keywordTable [(int)BuiltinTypeSpec.Type.Decimal] = DomReturnType.Decimal.FullName;
308
keywordTable [(int)BuiltinTypeSpec.Type.Char] = DomReturnType.Char.FullName;
309
keywordTable [(int)BuiltinTypeSpec.Type.Bool] = DomReturnType.Bool.FullName;
310
keywordTable [(int)BuiltinTypeSpec.Type.IntPtr] = DomReturnType.IntPtr.FullName;
311
keywordTable [(int)BuiltinTypeSpec.Type.UIntPtr] = DomReturnType.UIntPtr.FullName;
314
public ConversionVisitor (LocationsBag locationsBag)
316
this.LocationsBag = locationsBag;
320
string RetrieveDocumentation (int upToLine)
322
StringBuilder result = null;
323
while (lastComment < ParsedDocument.Comments.Count) {
324
var cur = ParsedDocument.Comments[lastComment];
325
if (cur.Region.Start.Line >= upToLine)
327
if (cur.IsDocumentation) {
329
result = new StringBuilder ();
330
result.Append (cur.Text);
334
return result == null ? null : result.ToString ();
337
public static DomLocation Convert (Mono.CSharp.Location loc)
339
return new DomLocation (loc.Row, loc.Column);
342
public DomRegion ConvertRegion (Mono.CSharp.Location start, Mono.CSharp.Location end)
344
DomLocation startLoc = Convert (start);
345
var endLoc = Convert (end);
347
return new DomRegion (startLoc, endLoc);
350
static MonoDevelop.Projects.Dom.Modifiers ConvertModifiers (Mono.CSharp.Modifiers modifiers)
352
MonoDevelop.Projects.Dom.Modifiers result = MonoDevelop.Projects.Dom.Modifiers.None;
354
if ((modifiers & Mono.CSharp.Modifiers.PUBLIC) != 0)
355
result |= MonoDevelop.Projects.Dom.Modifiers.Public;
356
if ((modifiers & Mono.CSharp.Modifiers.PRIVATE) != 0)
357
result |= MonoDevelop.Projects.Dom.Modifiers.Private;
358
if ((modifiers & Mono.CSharp.Modifiers.PROTECTED) != 0)
359
result |= MonoDevelop.Projects.Dom.Modifiers.Protected;
360
if ((modifiers & Mono.CSharp.Modifiers.INTERNAL) != 0)
361
result |= MonoDevelop.Projects.Dom.Modifiers.Internal;
363
if ((modifiers & Mono.CSharp.Modifiers.ABSTRACT) != 0)
364
result |= MonoDevelop.Projects.Dom.Modifiers.Abstract;
365
if ((modifiers & Mono.CSharp.Modifiers.NEW) != 0)
366
result |= MonoDevelop.Projects.Dom.Modifiers.New;
367
if ((modifiers & Mono.CSharp.Modifiers.SEALED) != 0)
368
result |= MonoDevelop.Projects.Dom.Modifiers.Sealed;
369
if ((modifiers & Mono.CSharp.Modifiers.READONLY) != 0)
370
result |= MonoDevelop.Projects.Dom.Modifiers.Readonly;
371
if ((modifiers & Mono.CSharp.Modifiers.VIRTUAL) != 0)
372
result |= MonoDevelop.Projects.Dom.Modifiers.Virtual;
373
if ((modifiers & Mono.CSharp.Modifiers.OVERRIDE) != 0)
374
result |= MonoDevelop.Projects.Dom.Modifiers.Override;
375
if ((modifiers & Mono.CSharp.Modifiers.EXTERN) != 0)
376
result |= MonoDevelop.Projects.Dom.Modifiers.Extern;
377
if ((modifiers & Mono.CSharp.Modifiers.VOLATILE) != 0)
378
result |= MonoDevelop.Projects.Dom.Modifiers.Volatile;
379
if ((modifiers & Mono.CSharp.Modifiers.UNSAFE) != 0)
380
result |= MonoDevelop.Projects.Dom.Modifiers.Unsafe;
382
if ((modifiers & Mono.CSharp.Modifiers.STATIC) != 0)
383
result |= MonoDevelop.Projects.Dom.Modifiers.Static;
385
if ((modifiers & Mono.CSharp.Modifiers.PARTIAL) != 0)
386
result |= MonoDevelop.Projects.Dom.Modifiers.Partial;
390
void AddType (IType child)
392
if (typeStack.Count > 0) {
393
typeStack.Peek ().Add (child);
400
void AddTypeArguments (ATypeNameExpression texpr, DomReturnType result)
402
if (!texpr.HasTypeArguments)
404
foreach (var arg in texpr.TypeArguments.Args) {
405
result.AddTypeParameter (ConvertReturnType (arg));
409
IReturnType ConvertReturnType (Mono.CSharp.Expression typeName)
411
if (typeName is TypeExpression) {
412
var typeExpr = (Mono.CSharp.TypeExpression)typeName;
413
return new DomReturnType (keywordTable [(int)typeExpr.Type.BuiltinType]);
416
if (typeName is Mono.CSharp.QualifiedAliasMember) {
417
var qam = (Mono.CSharp.QualifiedAliasMember)typeName;
418
// TODO: Overwork the return type model - atm we don't have a good representation
419
// for qualified alias members.
420
return new DomReturnType (qam.Name);
423
if (typeName is MemberAccess) {
424
MemberAccess ma = (MemberAccess)typeName;
425
var baseType = (DomReturnType)ConvertReturnType (ma.LeftExpression);
426
baseType.Parts.Add (new ReturnTypePart (ma.Name));
427
AddTypeArguments (ma, baseType);
431
if (typeName is SimpleName) {
432
var sn = (SimpleName)typeName;
433
var result = new DomReturnType (sn.Name);
434
AddTypeArguments (sn, result);
438
if (typeName is ComposedCast) {
439
var cc = (ComposedCast)typeName;
440
var baseType = (DomReturnType)ConvertReturnType (cc.Left);
441
if (cc.Spec.IsNullable) {
442
return new DomReturnType ("System.Nullable", true, new IReturnType[] { baseType });
443
} else if (cc.Spec.IsPointer) {
444
baseType.PointerNestingLevel++;
446
baseType.ArrayDimensions++;
447
baseType.SetDimension (baseType.ArrayDimensions - 1, cc.Spec.Dimension - 1);
451
MonoDevelop.Core.LoggingService.LogError ("Error while converting :" + typeName + " - unknown type name");
452
return new DomReturnType (DomReturnType.Void.FullName);
456
IReturnType ConvertReturnType (MemberName name)
458
return ConvertReturnType (name.GetTypeExpression ());
462
string currentNamespaceName = "";
463
Stack<UsingsBag.Namespace> currentNamespace = new Stack<UsingsBag.Namespace> ();
465
string ConvertToString (MemberName name)
470
return name.Left != null ? ConvertToString (name.Left) + "." + name.Name : name.Name;
474
public override void Visit (ModuleContainer mc)
476
foreach (var at in ConvertAttributes (mc.OptAttributes, mc))
480
public override void Visit (UsingsBag.Namespace nspace)
482
string oldNamespace = currentNamespaceName;
483
currentNamespace.Push (nspace);
484
if (nspace.Name != null) { // no need to push the global namespace
485
string name = ConvertToString (nspace.Name);
486
string[] splittedNamespace = name.Split ('.');
487
for (int i = splittedNamespace.Length; i > 0; i--) {
488
DomUsing domUsing = new DomUsing ();
489
domUsing.IsFromNamespace = true;
490
domUsing.Region = domUsing.ValidRegion = ConvertRegion (nspace.OpenBrace, nspace.CloseBrace);
491
domUsing.Add (string.Join (".", splittedNamespace, 0, i));
494
currentNamespaceName = string.IsNullOrEmpty (currentNamespaceName) ? name : currentNamespaceName + "." + name;
497
VisitNamespaceUsings (nspace);
498
VisitNamespaceBody (nspace);
499
currentNamespace.Pop ();
500
currentNamespaceName = oldNamespace;
503
public override void Visit (UsingsBag.Using u)
505
if (!string.IsNullOrEmpty (currentNamespaceName)) {
506
DomUsing relativeNamespaceUsing = new DomUsing ();
507
relativeNamespaceUsing.Region = ConvertRegion (u.UsingLocation, u.SemicolonLocation);
508
relativeNamespaceUsing.ValidRegion = ConvertRegion (currentNamespace.Peek ().OpenBrace, currentNamespace.Peek ().CloseBrace);
509
relativeNamespaceUsing.Add (currentNamespaceName + "." + ConvertToString (u.NSpace));
510
Unit.Add (relativeNamespaceUsing);
512
DomUsing domUsing = new DomUsing ();
513
domUsing.Region = ConvertRegion (u.UsingLocation, u.SemicolonLocation);
514
domUsing.ValidRegion = ConvertRegion (currentNamespace.Peek ().OpenBrace, currentNamespace.Peek ().CloseBrace);
515
domUsing.Add (ConvertToString (u.NSpace));
519
public override void Visit (UsingsBag.AliasUsing u)
521
DomUsing domUsing = new DomUsing ();
522
domUsing.Region = ConvertRegion (u.UsingLocation, u.SemicolonLocation);
523
domUsing.ValidRegion = ConvertRegion (currentNamespace.Peek ().OpenBrace, currentNamespace.Peek ().CloseBrace);
524
domUsing.Add (u.Identifier.Value, new DomReturnType (ConvertToString (u.Nspace)));
528
public override void Visit (MemberCore member)
530
Console.WriteLine ("Unknown member:");
531
Console.WriteLine (member.GetType () + "-> Member {0}", member.GetSignatureForError ());
534
Stack<DomType> typeStack = new Stack<DomType> ();
536
void VisitType (TypeContainer c, ClassType classType)
538
DomType newType = new DomType ();
539
newType.SourceProjectDom = Dom;
540
newType.CompilationUnit = Unit;
541
if (typeStack.Count == 0 && !string.IsNullOrEmpty (currentNamespaceName))
542
newType.Namespace = currentNamespaceName;
544
newType.Name = ConvertQuoted (c.MemberName.Name);
545
newType.Location = Convert (c.MemberName.Location);
546
newType.ClassType = classType;
547
var location = LocationsBag.GetMemberLocation (c);
549
if (location != null && location.Count > 2) {
550
var region = ConvertRegion (c.MemberName.Location, location[2]);
551
region.Start = new DomLocation (region.Start.Line, region.Start.Column + c.MemberName.Name.Length);
552
newType.BodyRegion = region;
554
var region = ConvertRegion (c.MemberName.Location, c.MemberName.Location);
555
region.Start = new DomLocation (region.Start.Line, region.Start.Column + c.MemberName.Name.Length);
556
region.End = new DomLocation (int.MaxValue, int.MaxValue);
557
newType.BodyRegion = region;
560
newType.Modifiers = ConvertModifiers (c.ModFlags);
561
AddAttributes (newType, c.OptAttributes, c);
562
AddTypeParameter (newType, c);
564
if (c.TypeBaseExpressions != null) {
565
foreach (var type in c.TypeBaseExpressions) {
566
var baseType = ConvertReturnType (type);
567
// Console.WriteLine (newType.Name + " -- " + baseType);
568
if (newType.BaseType == null) {
569
newType.BaseType = baseType;
571
newType.AddInterfaceImplementation (baseType);
578
typeStack.Push (newType);
579
foreach (MemberCore member in c.OrderedAllMembers) {
580
member.Accept (this);
585
public override void Visit (Class c)
587
VisitType (c, ClassType.Class);
590
public override void Visit (Struct s)
592
VisitType (s, ClassType.Struct);
595
public override void Visit (Interface i)
597
VisitType (i, ClassType.Interface);
600
public override void Visit (Mono.CSharp.Enum e)
602
VisitType (e, ClassType.Enum);
605
class CodeAstVisitor : StructuralVisitor
607
public override object Visit (Constant constant)
609
return new CodePrimitiveExpression (constant.GetValue ());
612
public override object Visit (Unary unaryExpression)
614
var exprResult = (CodeExpression)unaryExpression.Expr.Accept (this);
616
switch (unaryExpression.Oper) {
617
case Unary.Operator.UnaryPlus:
619
case Unary.Operator.UnaryNegation: // -a => 0 - a
620
return new CodeBinaryOperatorExpression (new CodePrimitiveExpression (0), CodeBinaryOperatorType.Subtract, exprResult);
621
case Unary.Operator.LogicalNot: // !a => a == false
622
return new CodeBinaryOperatorExpression (exprResult, CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression (false));
626
static CodeBinaryOperatorType Convert (Binary.Operator o)
629
case Binary.Operator.Multiply:
630
return CodeBinaryOperatorType.Multiply;
631
case Binary.Operator.Division:
632
return CodeBinaryOperatorType.Divide;
633
case Binary.Operator.Modulus:
634
return CodeBinaryOperatorType.Modulus;
635
case Binary.Operator.Addition:
636
return CodeBinaryOperatorType.Add;
637
case Binary.Operator.Subtraction:
638
return CodeBinaryOperatorType.Subtract;
639
case Binary.Operator.LeftShift:
640
case Binary.Operator.RightShift:
641
return CodeBinaryOperatorType.Multiply; // unsupported
642
case Binary.Operator.LessThan:
643
return CodeBinaryOperatorType.LessThan;
644
case Binary.Operator.GreaterThan:
645
return CodeBinaryOperatorType.GreaterThan;
646
case Binary.Operator.LessThanOrEqual:
647
return CodeBinaryOperatorType.LessThanOrEqual;
648
case Binary.Operator.GreaterThanOrEqual:
649
return CodeBinaryOperatorType.GreaterThanOrEqual;
650
case Binary.Operator.Equality:
651
return CodeBinaryOperatorType.IdentityEquality;
652
case Binary.Operator.Inequality:
653
return CodeBinaryOperatorType.IdentityInequality;
654
case Binary.Operator.BitwiseAnd:
655
return CodeBinaryOperatorType.BitwiseAnd;
656
case Binary.Operator.ExclusiveOr:
657
return CodeBinaryOperatorType.BitwiseOr; // unsupported
658
case Binary.Operator.BitwiseOr:
659
return CodeBinaryOperatorType.BitwiseOr;
660
case Binary.Operator.LogicalAnd:
661
return CodeBinaryOperatorType.BooleanAnd;
662
case Binary.Operator.LogicalOr:
663
return CodeBinaryOperatorType.BooleanOr;
666
return CodeBinaryOperatorType.Add;
669
public override object Visit (Binary binaryExpression)
671
return new CodeBinaryOperatorExpression (
672
(CodeExpression)binaryExpression.Left.Accept (this),
673
Convert (binaryExpression.Oper),
674
(CodeExpression)binaryExpression.Right.Accept (this));
679
System.CodeDom.CodeExpression ResolveMemberAccessExpression (Mono.CSharp.Expression expr)
681
if (expr is MemberAccess) {
682
var ma = (MemberAccess)expr;
683
return new CodeFieldReferenceExpression (ResolveMemberAccessExpression (ma.LeftExpression), ma.Name);
685
if (expr is SimpleName)
686
return new CodeTypeReferenceExpression (((SimpleName)expr).Name);
690
IEnumerable<IAttribute> ConvertAttributes (Attributes optAttributes, IMemberContext mc)
692
List<IAttribute> atts = new List<IAttribute> ();
694
if (optAttributes == null || optAttributes.Attrs == null)
697
ResolveContext ctx = new ResolveContext (mc);
699
foreach (var attr in optAttributes.Attrs) {
700
DomAttribute domAttribute = new DomAttribute ();
701
domAttribute.Name = ConvertQuoted (attr.Name);
702
domAttribute.Region = ConvertRegion (attr.Location, attr.Location);
703
domAttribute.AttributeType = ConvertReturnType (attr.TypeNameExpression);
704
if (attr.PosArguments != null) {
705
for (int i = 0; i < attr.PosArguments.Count; i++) {
706
CodeExpression domExp;
707
var exp = attr.PosArguments [i].Expr;
709
TypeOf tof = (TypeOf)exp;
710
IReturnType rt = ConvertReturnType (tof.TypeExpression);
711
domExp = new CodeTypeOfExpression (rt.FullName);
714
domExp = ResolveMemberAccessExpression (exp);
716
if (domExp == null) {
717
var res = exp.Resolve (ctx);
718
var val = res as Constant;
721
domExp = new CodePrimitiveExpression (val.GetValue ());
727
domAttribute.AddPositionalArgument (domExp);
730
if (attr.NamedArguments != null) {
731
for (int i = 0; i < attr.NamedArguments.Count; i++) {
732
var val = attr.NamedArguments [i].Expr as Constant;
735
domAttribute.AddNamedArgument (((NamedArgument)attr.NamedArguments [i]).Name, new CodePrimitiveExpression (val.GetValue ()));
739
atts.Add (domAttribute);
744
public void AddAttributes (MonoDevelop.Projects.Dom.AbstractMember member, Attributes optAttributes, IMemberContext mc)
746
foreach (var attr in ConvertAttributes (optAttributes, mc))
750
MonoDevelop.Projects.Dom.TypeParameter ConvertTemplateDefinition (Mono.CSharp.TypeParameter parameter)
752
var result = new MonoDevelop.Projects.Dom.TypeParameter (parameter.Name);
753
if (parameter.Constraints != null) {
754
foreach (var constraintExpr in parameter.Constraints.ConstraintExpressions) {
755
if (constraintExpr is SpecialContraintExpr) {
756
var sce = (SpecialContraintExpr)constraintExpr;
757
if (sce.Constraint == SpecialConstraint.Struct)
758
result.AddConstraint (DomReturnType.ValueType);
759
if (sce.Constraint == SpecialConstraint.Class)
760
result.AddConstraint (DomReturnType.Object);
761
if (sce.Constraint == SpecialConstraint.Constructor)
762
result.TypeParameterModifier |= TypeParameterModifier.HasDefaultConstructorConstraint;
764
result.AddConstraint (ConvertReturnType (constraintExpr));
771
public void AddTypeParameter (AbstractTypeParameterMember member, DeclSpace decl)
773
if (!decl.IsGeneric || decl.CurrentTypeParameters == null)
776
foreach (var typeParameter in decl.CurrentTypeParameters) {
777
var par = ConvertTemplateDefinition (typeParameter);
778
member.AddTypeParameter (par);
782
public override void Visit (Mono.CSharp.Delegate d)
784
DomType delegateType = DomType.CreateDelegate (Unit, d.MemberName.Name, Convert (d.MemberName.Location), ConvertReturnType (d.ReturnType), null);
785
delegateType.SourceProjectDom = Dom;
786
delegateType.Location = Convert (d.MemberName.Location);
787
delegateType.Documentation = RetrieveDocumentation (d.MemberName.Location.Row);
788
delegateType.Modifiers = ConvertModifiers (d.ModFlags);
789
AddAttributes (delegateType, d.OptAttributes, d);
791
AddParameter ((MonoDevelop.Projects.Dom.AbstractMember)delegateType.Methods.First (), d.Parameters);
792
AddTypeParameter (delegateType, d);
793
AddType (delegateType);
801
public override void Visit (FixedField f)
803
DomField field = new DomField ();
804
field.Name = ConvertQuoted (f.MemberName.Name);
805
field.Documentation = RetrieveDocumentation (f.Location.Row);
806
field.Location = Convert (f.MemberName.Location);
807
field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Fixed;
808
field.ReturnType = ConvertReturnType (f.TypeName);
809
AddAttributes (field, f.OptAttributes, f);
810
field.DeclaringType = typeStack.Peek ();
811
typeStack.Peek ().Add (field);
812
if (f.Declarators != null) {
813
foreach (var decl in f.Declarators) {
814
field = new DomField ();
815
field.Name = ConvertQuoted (decl.Name.Value);
816
field.Location = Convert (decl.Name.Location);
817
field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Fixed;
818
field.ReturnType = ConvertReturnType (f.TypeName);
819
AddAttributes (field, f.OptAttributes, f);
820
field.DeclaringType = typeStack.Peek ();
821
typeStack.Peek ().Add (field);
826
public override void Visit (Field f)
828
var field = new DomField ();
829
field.Name = ConvertQuoted (f.MemberName.Name);
830
field.Documentation = RetrieveDocumentation (f.Location.Row);
831
field.Location = Convert (f.MemberName.Location);
832
field.Modifiers = ConvertModifiers (f.ModFlags);
833
field.ReturnType = ConvertReturnType (f.TypeName);
834
AddAttributes (field, f.OptAttributes, f);
835
field.DeclaringType = typeStack.Peek ();
836
typeStack.Peek ().Add (field);
838
if (f.Declarators != null) {
839
foreach (var decl in f.Declarators) {
840
field = new DomField ();
841
field.Name = ConvertQuoted (decl.Name.Value);
842
field.Location = Convert (decl.Name.Location);
843
field.Modifiers = ConvertModifiers (f.ModFlags);
844
field.ReturnType = ConvertReturnType (f.TypeName);
845
AddAttributes (field, f.OptAttributes, f);
846
field.DeclaringType = typeStack.Peek ();
847
typeStack.Peek ().Add (field);
852
public override void Visit (Const f)
854
DomField field = new DomField ();
855
field.Name = ConvertQuoted (f.MemberName.Name);
856
field.Documentation = RetrieveDocumentation (f.Location.Row);
857
field.Location = Convert (f.MemberName.Location);
858
field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Const;
859
field.ReturnType = ConvertReturnType (f.TypeName);
860
AddAttributes (field, f.OptAttributes, f);
861
field.DeclaringType = typeStack.Peek ();
862
typeStack.Peek ().Add (field);
863
if (f.Declarators != null) {
864
foreach (var decl in f.Declarators) {
865
field = new DomField ();
866
field.Name = ConvertQuoted (decl.Name.Value);
867
field.Location = Convert (decl.Name.Location);
868
field.Modifiers = ConvertModifiers (f.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.Const;
869
field.ReturnType = ConvertReturnType (f.TypeName);
870
AddAttributes (field, f.OptAttributes, f);
871
field.DeclaringType = typeStack.Peek ();
872
typeStack.Peek ().Add (field);
877
void AddExplicitInterfaces (MonoDevelop.Projects.Dom.AbstractMember member, InterfaceMemberBase mcsMember)
879
if (!mcsMember.IsExplicitImpl)
881
member.AddExplicitInterface (ConvertReturnType (mcsMember.MemberName.Left));
884
public override void Visit (EventField e)
886
var evt = new DomEvent ();
887
evt.Name = ConvertQuoted (e.MemberName.Name);
888
evt.Documentation = RetrieveDocumentation (e.Location.Row);
889
evt.Location = Convert (e.MemberName.Location);
890
evt.Modifiers = ConvertModifiers (e.ModFlags);
891
evt.ReturnType = ConvertReturnType (e.TypeName);
892
AddAttributes (evt, e.OptAttributes, e);
893
AddExplicitInterfaces (evt, e);
894
evt.DeclaringType = typeStack.Peek ();
895
typeStack.Peek ().Add (evt);
896
if (e.Declarators != null) {
897
foreach (var decl in e.Declarators) {
898
evt = new DomEvent ();
899
evt.Name = ConvertQuoted (decl.Name.Value);
900
evt.Location = Convert (decl.Name.Location);
901
evt.Modifiers = ConvertModifiers (e.ModFlags);
902
evt.ReturnType = ConvertReturnType (e.TypeName);
903
AddAttributes (evt, e.OptAttributes, e);
904
evt.DeclaringType = typeStack.Peek ();
905
typeStack.Peek ().Add (evt);
910
public override void Visit (EventProperty e)
912
DomEvent evt = new DomEvent ();
913
evt.Name = ConvertQuoted (e.MemberName.Name);
914
evt.Documentation = RetrieveDocumentation (e.Location.Row);
915
evt.Location = Convert (e.MemberName.Location);
916
evt.Modifiers = ConvertModifiers (e.ModFlags);
917
evt.ReturnType = ConvertReturnType (e.TypeName);
918
var location = LocationsBag.GetMemberLocation (e);
919
if (location != null)
920
evt.BodyRegion = ConvertRegion (location[1], location[2]);
922
AddAttributes (evt, e.OptAttributes, e);
923
AddExplicitInterfaces (evt, e);
925
evt.DeclaringType = typeStack.Peek ();
926
typeStack.Peek ().Add (evt);
929
public override void Visit (Property p)
931
DomProperty property = new DomProperty ();
932
property.Name = ConvertQuoted (p.MemberName.Name);
933
property.Documentation = RetrieveDocumentation (p.Location.Row);
934
property.Location = Convert (p.MemberName.Location);
935
property.GetterModifier = property.SetterModifier = ConvertModifiers (p.ModFlags);
937
var location = LocationsBag.GetMemberLocation (p);
938
if (location != null && location.Count >= 1) {
939
var endLoc = location.Count == 1 ? location[0] : location[1];
940
property.BodyRegion = ConvertRegion (location[0], endLoc);
942
property.BodyRegion = DomRegion.Empty;
944
property.ReturnType = ConvertReturnType (p.TypeName);
946
AddAttributes (property, p.OptAttributes, p);
947
AddExplicitInterfaces (property, p);
950
property.PropertyModifier |= PropertyModifier.HasGet;
951
if ((p.Get.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
952
property.GetterModifier = ConvertModifiers (p.Get.ModFlags);
953
if (p.Get.Block != null) {
954
property.GetRegion = ConvertRegion (p.Get.Location, p.Get.Block.EndLocation);
956
var getLocation = LocationsBag.GetMemberLocation (p.Get);
957
property.GetRegion = ConvertRegion (p.Get.Location, getLocation.Count > 0 ? getLocation[0] : p.Get.Location);
962
property.PropertyModifier |= PropertyModifier.HasSet;
963
if ((p.Set.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
964
property.SetterModifier = ConvertModifiers (p.Set.ModFlags);
965
if (p.Set.Block != null) {
966
property.SetRegion = ConvertRegion (p.Set.Location, p.Set.Block.EndLocation);
968
var setLocation = LocationsBag.GetMemberLocation (p.Set);
969
property.SetRegion = ConvertRegion (p.Set.Location, setLocation.Count > 0 ? setLocation[0] : p.Set.Location);
972
property.DeclaringType = typeStack.Peek ();
973
typeStack.Peek ().Add (property);
976
static string ConvertQuoted (string name)
980
return name.StartsWith ("@") ? name.Substring (1) : name;
983
public void AddParameter (MonoDevelop.Projects.Dom.AbstractMember member, AParametersCollection parameters)
985
for (int i = 0; i < parameters.Count; i++) {
986
var p = (Parameter)parameters.FixedParameters[i];
987
DomParameter parameter = new DomParameter ();
988
parameter.Name = ConvertQuoted (p.Name);
989
parameter.Location = Convert (p.Location);
990
parameter.ReturnType = ConvertReturnType (p.TypeExpression);
991
var modifiers = MonoDevelop.Projects.Dom.ParameterModifiers.None;
992
if ((p.ParameterModifier & Parameter.Modifier.OUT) == Parameter.Modifier.OUT)
993
modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.Out;
994
if ((p.ParameterModifier & Parameter.Modifier.REF) == Parameter.Modifier.REF)
995
modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.Ref;
996
if ((p.ParameterModifier & Parameter.Modifier.PARAMS) == Parameter.Modifier.PARAMS)
997
modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.Params;
998
if ((p.ParameterModifier & Parameter.Modifier.This) == Parameter.Modifier.This)
999
modifiers |= MonoDevelop.Projects.Dom.ParameterModifiers.This;
1000
parameter.ParameterModifiers = modifiers;
1001
member.Add (parameter);
1005
public override void Visit (Indexer i)
1007
DomProperty indexer = new DomProperty ();
1008
indexer.PropertyModifier |= PropertyModifier.IsIndexer;
1009
indexer.Name = "this";
1010
indexer.Documentation = RetrieveDocumentation (i.Location.Row);
1011
indexer.Location = Convert (i.Location);
1012
indexer.GetterModifier = indexer.SetterModifier = ConvertModifiers (i.ModFlags);
1013
var location = LocationsBag.GetMemberLocation (i);
1014
if (location != null && location.Count >= 1) {
1015
var endLoc = location.Count == 1 ? location[0] : location[1];
1016
indexer.BodyRegion = ConvertRegion (location[0], endLoc);
1018
indexer.BodyRegion = DomRegion.Empty;
1021
indexer.ReturnType = ConvertReturnType (i.TypeName);
1022
AddParameter (indexer, i.ParameterInfo);
1024
AddAttributes (indexer, i.OptAttributes, i);
1025
AddExplicitInterfaces (indexer, i);
1027
if (i.Get != null) {
1028
indexer.PropertyModifier |= PropertyModifier.HasGet;
1029
if ((i.Get.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
1030
indexer.GetterModifier = ConvertModifiers (i.Get.ModFlags);
1031
if (i.Get.Block != null) {
1032
indexer.GetRegion = ConvertRegion (i.Get.Location, i.Get.Block.EndLocation);
1034
var getLocation = LocationsBag.GetMemberLocation (i.Get);
1035
indexer.GetRegion = ConvertRegion (i.Get.Location, getLocation.Count > 0 ? getLocation[0] : i.Get.Location);
1039
if (i.Set != null) {
1040
indexer.PropertyModifier |= PropertyModifier.HasSet;
1041
if ((i.Set.ModFlags & Mono.CSharp.Modifiers.AccessibilityMask) != 0)
1042
indexer.SetterModifier = ConvertModifiers (i.Set.ModFlags);
1043
if (i.Set.Block != null) {
1044
indexer.SetRegion = ConvertRegion (i.Set.Location, i.Set.Block.EndLocation);
1046
var setLocation = LocationsBag.GetMemberLocation (i.Set);
1047
indexer.SetRegion = ConvertRegion (i.Set.Location, setLocation.Count > 0 ? setLocation[0] : i.Set.Location);
1050
indexer.DeclaringType = typeStack.Peek ();
1051
typeStack.Peek ().Add (indexer);
1054
public override void Visit (Method m)
1056
DomMethod method = new DomMethod ();
1057
method.Name = ConvertQuoted (m.MemberName.Name);
1058
method.Documentation = RetrieveDocumentation (m.Location.Row);
1059
method.Location = Convert (m.MemberName.Location);
1060
method.Modifiers = ConvertModifiers (m.ModFlags);
1061
if (m.Block != null) {
1062
var location = LocationsBag.GetMemberLocation (m);
1063
var region = ConvertRegion (location != null ? location[1] : m.Block.StartLocation, m.Block.EndLocation);
1064
if (location != null)
1065
region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
1066
method.BodyRegion = region;
1069
method.ReturnType = ConvertReturnType (m.TypeName);
1070
AddAttributes (method, m.OptAttributes, m);
1071
AddParameter (method, m.ParameterInfo);
1072
AddExplicitInterfaces (method, m);
1073
method.Modifiers = ConvertModifiers (m.ModFlags);
1074
if (method.IsStatic && method.Parameters.Count > 0 && method.Parameters[0].ParameterModifiers == ParameterModifiers.This)
1075
method.MethodModifier |= MethodModifier.IsExtension;
1076
if (m.GenericMethod != null)
1077
AddTypeParameter (method, m.GenericMethod);
1078
method.DeclaringType = typeStack.Peek ();
1079
typeStack.Peek ().Add (method);
1082
public override void Visit (Operator o)
1084
DomMethod method = new DomMethod ();
1085
method.Name = ConvertQuoted (o.MemberName.Name);
1086
method.Documentation = RetrieveDocumentation (o.Location.Row);
1087
method.Location = Convert (o.MemberName.Location);
1088
method.Modifiers = ConvertModifiers (o.ModFlags);
1089
if (o.Block != null) {
1090
var location = LocationsBag.GetMemberLocation (o);
1091
var region = ConvertRegion (location != null ? location[1] : o.Block.StartLocation, o.Block.EndLocation);
1092
if (location != null)
1093
region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
1094
method.BodyRegion = region;
1096
method.Modifiers = ConvertModifiers (o.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.SpecialName;
1097
method.ReturnType = ConvertReturnType (o.TypeName);
1098
AddAttributes (method, o.OptAttributes, o);
1099
AddParameter (method, o.ParameterInfo);
1100
AddExplicitInterfaces (method, o);
1102
method.DeclaringType = typeStack.Peek ();
1103
typeStack.Peek ().Add (method);
1106
public override void Visit (Constructor c)
1108
DomMethod method = new DomMethod ();
1109
method.Name = ".ctor";
1110
method.Documentation = RetrieveDocumentation (c.Location.Row);
1111
method.Location = Convert (c.MemberName.Location);
1112
method.Modifiers = ConvertModifiers (c.ModFlags);
1113
if (c.Block != null) {
1114
var location = LocationsBag.GetMemberLocation (c);
1115
var region = ConvertRegion (location != null ? location[1] : c.Block.StartLocation, c.Block.EndLocation);
1116
if (location != null)
1117
region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
1118
method.BodyRegion = region;
1120
method.Modifiers = ConvertModifiers (c.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.SpecialName;
1121
method.MethodModifier |= MethodModifier.IsConstructor;
1122
AddAttributes (method, c.OptAttributes, c);
1123
AddParameter (method, c.ParameterInfo);
1124
AddExplicitInterfaces (method, c);
1125
method.DeclaringType = typeStack.Peek ();
1126
typeStack.Peek ().Add (method);
1129
public override void Visit (Destructor d)
1131
DomMethod method = new DomMethod ();
1132
method.Name = ".dtor";
1133
method.Documentation = RetrieveDocumentation (d.Location.Row);
1134
method.Location = Convert (d.MemberName.Location);
1135
if (d.Block != null) {
1136
var location = LocationsBag.GetMemberLocation (d);
1137
var region = ConvertRegion (location != null ? location[1] : d.Block.StartLocation, d.Block.EndLocation);
1138
if (location != null)
1139
region.Start = new DomLocation (region.Start.Line, region.Start.Column + 1);
1140
method.BodyRegion = region;
1142
method.Modifiers = ConvertModifiers (d.ModFlags) | MonoDevelop.Projects.Dom.Modifiers.SpecialName;
1143
method.MethodModifier |= MethodModifier.IsFinalizer;
1144
AddAttributes (method, d.OptAttributes, d);
1145
AddExplicitInterfaces (method, d);
1146
method.DeclaringType = typeStack.Peek ();
1147
typeStack.Peek ().Add (method);
1150
public override void Visit (EnumMember f)
1152
DomField field = new DomField ();
1153
field.Name = ConvertQuoted (f.MemberName.Name);
1154
field.Documentation = RetrieveDocumentation (f.Location.Row);
1155
// return types for enum fields are == null
1156
field.Location = Convert (f.MemberName.Location);
1157
field.Modifiers = MonoDevelop.Projects.Dom.Modifiers.Const | MonoDevelop.Projects.Dom.Modifiers.SpecialName| MonoDevelop.Projects.Dom.Modifiers.Public;
1158
AddAttributes (field, f.OptAttributes, f);
1159
field.DeclaringType = typeStack.Peek ();
1160
typeStack.Peek ().Add (field);