* BindingSourceTest.cs: New Filter/RemoveFilter tests.
[mono.git] / mcs / class / System / Microsoft.VisualBasic / VBCodeGenerator.cs
1 //
2 // Microsoft.VisualBasic.VBCodeGenerator.cs
3 //
4 // Author:
5 //   Andreas Nahr (ClassDevelopment@A-SoftTech.com)
6 //   (partially based on CSharpCodeGenerator)
7 //   Jochen Wezel (jwezel@compumaster.de)
8 //   Frederik Carlier (frederik.carlier@carlier-online.be)
9 //   Rolf Bjarne Kvinge (RKvinge@novell.com)
10 //
11 // (C) 2003 Andreas Nahr
12 // (C) 2003 Jochen Wezel (http://www.compumaster.de)
13 //
14 // Modifications:
15 // 2003-11-06 JW: some corrections regarding missing spaces in generated code (e. g. "Property ")
16 // 2003-11-06 JW: QuoteSnippetString implemented
17 // 2003-11-08 JW: automatically add Microsoft.VisualBasic
18 // 2003-11-12 JW: some corrections to allow correct compilation
19 // 2003-11-28 JW: implementing code differences into current build of this file
20 // 2003-12-10 JW: added "String." for the ChrW method because mbas doesn't support it without the String currently / TODO: remove it ASAP!
21 // 2007-04-13 FC: Added support for the IdentityInequality operator when comparing against Nothing
22
23 //
24 // Permission is hereby granted, free of charge, to any person obtaining
25 // a copy of this software and associated documentation files (the
26 // "Software"), to deal in the Software without restriction, including
27 // without limitation the rights to use, copy, modify, merge, publish,
28 // distribute, sublicense, and/or sell copies of the Software, and to
29 // permit persons to whom the Software is furnished to do so, subject to
30 // the following conditions:
31 // 
32 // The above copyright notice and this permission notice shall be
33 // included in all copies or substantial portions of the Software.
34 // 
35 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
36 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
37 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
38 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
39 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
40 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
41 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
42 //
43
44
45 using System;
46 using System.Globalization;
47 using System.Text;
48 using System.Text.RegularExpressions;
49 using System.CodeDom;
50 using System.CodeDom.Compiler;
51 using System.IO;
52 using System.Reflection;
53 using System.Collections;
54
55 namespace Microsoft.VisualBasic
56 {
57         internal class VBCodeGenerator : CodeGenerator
58         {
59 #if NET_2_0
60                 private string [] Keywords = new string [] {
61                         "AddHandler", "AddressOf", "Alias", "And",
62                         "AndAlso", "Ansi", "As", "Assembly",
63                         "Auto", "Boolean", "ByRef", "Byte", 
64                         "ByVal", "Call", "Case", "Catch", 
65                         "CBool", "CByte", "CChar", "CDate", 
66                         "CDec", "CDbl", "Char", "CInt", 
67                         "Class", "CLng", "CObj", "Const", 
68                         "CShort", "CSng", "CStr", "CType", 
69                         "Date", "Decimal", "Declare", "Default", 
70                         "Delegate", "Dim", "DirectCast", "Do", 
71                         "Double", "Each", "Else", "ElseIf", 
72                         "End", "Enum", "Erase", "Error", 
73                         "Event", "Exit", "False", "Finally", 
74                         "For", "Friend", "Function", "Get", 
75                         "GetType", "Global", "GoSub", "GoTo", "Handles", 
76                         "If", "Implements", "Imports", "In", 
77                         "Inherits", "Integer", "Interface", "Is", 
78                         "Let", "Lib", "Like", "Long", 
79                         "Loop", "Me", "Mod", "Module", 
80                         "MustInherit", "MustOverride", "MyBase", "MyClass", 
81                         "Namespace", "New", "Next", "Not", 
82                         "Nothing", "NotInheritable", "NotOverridable", "Object", 
83                         "On", "Option", "Optional", "Or", 
84                         "OrElse", "Overloads", "Overridable", "Overrides", 
85                         "ParamArray", "Partial", "Preserve", "Private", "Property", 
86                         "Protected", "Public", "RaiseEvent", "ReadOnly", 
87                         "ReDim", "REM", "RemoveHandler", "Resume", 
88                         "Return", "Select", "Set", "Shadows", 
89                         "Shared", "Short", "Single", "Static", 
90                         "Step", "Stop", "String", "Structure", 
91                         "Sub", "SyncLock", "Then", "Throw", 
92                         "To", "True", "Try", "TypeOf", 
93                         "Unicode", "Until", "Variant", "When", 
94                         "While", "With", "WithEvents", "WriteOnly", 
95                         "Xor" 
96                 };
97 #else
98                 private string [] Keywords = new string [] {
99                         "AddHandler", "AddressOf", "Alias", "And",
100                         "AndAlso", "Ansi", "As", "Assembly",
101                         "Auto", "Boolean", "ByRef", "Byte", 
102                         "ByVal", "Call", "Case", "Catch", 
103                         "CBool", "CByte", "CChar", "CDate", 
104                         "CDec", "CDbl", "Char", "CInt", 
105                         "Class", "CLng", "CObj", "Const", 
106                         "CShort", "CSng", "CStr", "CType", 
107                         "Date", "Decimal", "Declare", "Default", 
108                         "Delegate", "Dim", "DirectCast", "Do", 
109                         "Double", "Each", "Else", "ElseIf", 
110                         "End", "Enum", "Erase", "Error", 
111                         "Event", "Exit", "False", "Finally", 
112                         "For", "Friend", "Function", "Get", 
113                         "GetType", "GoSub", "GoTo", "Handles", 
114                         "If", "Implements", "Imports", "In", 
115                         "Inherits", "Integer", "Interface", "Is", 
116                         "Let", "Lib", "Like", "Long", 
117                         "Loop", "Me", "Mod", "Module", 
118                         "MustInherit", "MustOverride", "MyBase", "MyClass", 
119                         "Namespace", "New", "Next", "Not", 
120                         "Nothing", "NotInheritable", "NotOverridable", "Object", 
121                         "On", "Option", "Optional", "Or", 
122                         "OrElse", "Overloads", "Overridable", "Overrides", 
123                         "ParamArray", "Preserve", "Private", "Property", 
124                         "Protected", "Public", "RaiseEvent", "ReadOnly", 
125                         "ReDim", "REM", "RemoveHandler", "Resume", 
126                         "Return", "Select", "Set", "Shadows", 
127                         "Shared", "Short", "Single", "Static", 
128                         "Step", "Stop", "String", "Structure", 
129                         "Sub", "SyncLock", "Then", "Throw", 
130                         "To", "True", "Try", "TypeOf", 
131                         "Unicode", "Until", "Variant", "When", 
132                         "While", "With", "WithEvents", "WriteOnly", 
133                         "Xor" 
134                 };
135 #endif
136
137                 public VBCodeGenerator()
138                 {
139                 }
140
141                 protected override string NullToken {
142                         get {
143                                 return "Nothing";
144                         }
145                 }
146
147                 protected override void ContinueOnNewLine (string st)
148                 {
149                         Output.Write (st);
150                         Output.WriteLine (" _");
151                 }
152
153                 protected override void GenerateBinaryOperatorExpression (CodeBinaryOperatorExpression e)
154                 {
155                         // We need to special case for comparisons against null;
156                         // in Visual Basic the "Not (Expr) Is Nothing" construct is used
157                         
158                         bool null_comparison = false;
159                         bool reverse = false;
160                         if (e.Operator == CodeBinaryOperatorType.IdentityInequality) {
161                                 CodePrimitiveExpression nothing;
162                                 nothing = e.Left as CodePrimitiveExpression;
163                                 if (nothing == null) {
164                                         nothing = e.Right as CodePrimitiveExpression;
165                                 } else {
166                                         reverse = true;
167                                 }
168                                 null_comparison = nothing != null && nothing.Value == null;
169                         }
170
171                         if (null_comparison) {
172                                 TextWriter output = Output;
173
174                                 output.Write ("(Not (");
175                                 GenerateExpression (reverse ? e.Right : e.Left);
176                                 output.Write (") Is ");
177                                 GenerateExpression (reverse ? e.Left : e.Right);
178                                 output.Write (')');
179                         } else {
180                                 base.GenerateBinaryOperatorExpression (e);
181                         }
182                 }
183
184                 protected override void GenerateArrayCreateExpression (CodeArrayCreateExpression expression)
185                 {
186                         TextWriter output = Output;
187
188                         output.Write ("New ");
189
190                         CodeExpressionCollection initializers = expression.Initializers;
191                         CodeTypeReference createType = expression.CreateType;
192
193                         if (initializers.Count > 0) {
194
195                                 OutputType (createType);
196                                 
197                                 output.Write ("() {");
198                                 ++Indent;
199                                 OutputExpressionList (initializers);
200                                 --Indent;
201                                 output.Write ("}");
202                         } else {
203                                 CodeTypeReference arrayType = createType.ArrayElementType;
204                                 while (arrayType != null) {
205                                         createType = arrayType;
206                                         arrayType = arrayType.ArrayElementType;
207                                 }
208
209                                 OutputType (createType);
210
211                                 output.Write ("((");
212
213                                 CodeExpression size = expression.SizeExpression;
214                                 if (size != null)
215                                         GenerateExpression (size);
216                                 else
217                                         output.Write (expression.Size);
218
219                                 output.Write (") - 1) {}");
220                         }
221                 }
222
223                 protected override void GenerateBaseReferenceExpression (CodeBaseReferenceExpression expression)
224                 {
225                         Output.Write ("MyBase");
226                 }
227
228                 protected override void GenerateCastExpression (CodeCastExpression expression)
229                 {
230                         TextWriter output = Output;
231                         // ENHANCE: Use a DirectCast if it is known that expression.Expression is no Value-Type
232                         output.Write ("CType(");
233                         GenerateExpression (expression.Expression);
234                         output.Write (", ");
235                         OutputType (expression.TargetType);
236                         output.Write (")");
237                 }
238
239                 private bool AsBool (object datavalue)
240                 {
241                         return datavalue != null && datavalue is bool && (bool) datavalue;
242                 }
243                 
244                 private string OnOff (bool datavalue)
245                 {
246                         return datavalue ? "On" : "Off";
247                 }
248
249                 protected override void GenerateCompileUnitStart (CodeCompileUnit compileUnit)
250                 {
251                         GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));
252                         GenerateComment (new CodeComment (" <autogenerated>"));
253                         GenerateComment (new CodeComment ("     This code was generated by a tool."));
254                         GenerateComment (new CodeComment ("     Mono Runtime Version: " + System.Environment.Version));
255                         GenerateComment (new CodeComment (""));
256                         GenerateComment (new CodeComment ("     Changes to this file may cause incorrect behavior and will be lost if "));
257                         GenerateComment (new CodeComment ("     the code is regenerated."));
258                         GenerateComment (new CodeComment (" </autogenerated>"));
259                         GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));
260                         Output.WriteLine ();
261                         if (AsBool (compileUnit.UserData ["AllowLateBound"])) {
262                                 Output.WriteLine("Option Explicit {0}", OnOff (AsBool (compileUnit.UserData ["RequireVariableDeclaration"])));
263                                 Output.WriteLine("Option Strict Off");
264                         } else {
265                                 Output.WriteLine("Option Explicit On"); // Strict On implies Explicit On
266                                 Output.WriteLine("Option Strict On");
267                         }
268                         Output.WriteLine ();
269                 }
270
271                 protected override void GenerateCompileUnit (CodeCompileUnit compileUnit)
272                 {
273                         GenerateCompileUnitStart (compileUnit);
274
275                         OutputAttributes (compileUnit.AssemblyCustomAttributes,
276                                 "Assembly: ", LineHandling.NewLine);
277
278                         GenerateNamespaces (compileUnit);
279
280                         GenerateCompileUnitEnd (compileUnit);
281                 }
282
283                 protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)
284                 {
285                         TextWriter output = Output;
286
287                         output.Write ("AddressOf ");
288
289                         CodeExpression targetObject = expression.TargetObject;
290                         if (targetObject != null) {
291                                 GenerateExpression (targetObject);
292                                 Output.Write ('.');
293                         }
294                         output.Write (expression.MethodName);
295                 }
296
297                 protected override void GenerateFieldReferenceExpression (CodeFieldReferenceExpression expression)
298                 {
299                         CodeExpression targetObject = expression.TargetObject;
300                         if (targetObject != null) {
301                                 GenerateExpression (targetObject);
302                                 Output.Write ('.');
303                         }
304                         Output.Write (CreateEscapedIdentifier (expression.FieldName));
305                 }
306                 
307                 protected override void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression expression)
308                 {
309                         Output.Write (CreateEscapedIdentifier (expression.ParameterName));
310                 }
311
312                 protected override void GenerateVariableReferenceExpression (CodeVariableReferenceExpression expression)
313                 {
314                         Output.Write (CreateEscapedIdentifier (expression.VariableName));
315                 }
316                 
317                 protected override void GenerateIndexerExpression (CodeIndexerExpression expression)
318                 {
319                         TextWriter output = Output;
320
321                         GenerateExpression (expression.TargetObject);
322                         output.Write ('(');
323                         OutputExpressionList (expression.Indices);
324                         output.Write (')');
325                 }
326                 
327                 protected override void GenerateArrayIndexerExpression (CodeArrayIndexerExpression expression)
328                 {
329                         TextWriter output = Output;
330
331                         GenerateExpression (expression.TargetObject);
332                         output.Write ("(");
333                         OutputExpressionList (expression.Indices);
334                         output.Write (')');
335                 }
336                 
337                 protected override void GenerateSnippetExpression (CodeSnippetExpression expression)
338                 {
339                         Output.Write (expression.Value);
340                 }
341                 
342                 protected override void GenerateMethodInvokeExpression (CodeMethodInvokeExpression expression)
343                 {
344                         TextWriter output = Output;
345
346                         GenerateMethodReferenceExpression (expression.Method);
347
348                         output.Write ('(');
349                         OutputExpressionList (expression.Parameters);
350                         output.Write (')');
351                 }
352
353                 protected override void GenerateMethodReferenceExpression (CodeMethodReferenceExpression expression)
354                 {
355                         if (expression.TargetObject != null) {
356                                 GenerateExpression (expression.TargetObject);
357                                 Output.Write ('.');
358                         }
359                         Output.Write (CreateEscapedIdentifier (expression.MethodName));
360                 }
361
362                 protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression expression)
363                 {
364                         if (expression.TargetObject != null) {
365                                 GenerateExpression (expression.TargetObject);
366                                 Output.Write ('.');
367                                 if (expression.TargetObject is CodeThisReferenceExpression) {
368                                         // We're actually creating a reference to a compiler-generated field here...
369                                         Output.Write (expression.EventName + "Event");
370                                 } else {
371                                         Output.Write (CreateEscapedIdentifier (expression.EventName));
372                                 }
373                         } else {
374                                 Output.Write (CreateEscapedIdentifier (expression.EventName + "Event"));
375                         }
376                 }
377
378                 protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression expression)
379                 {
380                         CodeEventReferenceExpression ev = expression.TargetObject as CodeEventReferenceExpression;
381                         
382 #if ONLY_1_1
383                         Output.Write ("RaiseEvent ");
384 #endif
385                         if (ev != null) {
386 #if NET_2_0
387                                 Output.Write ("RaiseEvent ");
388 #endif
389                                 if (ev.TargetObject != null && !(ev.TargetObject is CodeThisReferenceExpression)) {
390                                         GenerateExpression (ev.TargetObject);
391                                         Output.Write (".");
392                                 }
393                                 Output.Write (ev.EventName);
394                         } else if (expression.TargetObject != null) {
395                                 GenerateExpression (expression.TargetObject);
396                         }
397                         Output.Write ('(');
398                         OutputExpressionList (expression.Parameters);
399                         Output.Write (')');
400                 }
401                 
402                 protected override void GenerateObjectCreateExpression (CodeObjectCreateExpression expression)
403                 {
404                         Output.Write( "New " );
405                         OutputType (expression.CreateType);
406                         Output.Write ('(');
407                         OutputExpressionList (expression.Parameters);
408                         Output.Write (')');
409                 }
410
411                 protected override void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)
412                 {
413                         OutputAttributes (e.CustomAttributes, null, LineHandling.InLine);
414                         OutputDirection (e.Direction);
415                         OutputTypeNamePair (e.Type, e.Name);
416                 }
417
418                 protected override void GeneratePrimitiveExpression (CodePrimitiveExpression e)
419                 {
420                         if (e.Value is char) {
421                                 char c = (char) e.Value;
422                                 int ch = (int) c;
423 #if NET_2_0
424                                 Output.Write("Global.Microsoft.VisualBasic.ChrW(" + ch.ToString(CultureInfo.InvariantCulture) + ")");
425                         } else if (e.Value is ushort) {
426                                 ushort uc = (ushort) e.Value;
427                                 Output.Write (uc.ToString(CultureInfo.InvariantCulture));
428                                 Output.Write ("US");
429                         } else if (e.Value is uint) {
430                                 uint ui = (uint) e.Value;
431                                 Output.Write (ui.ToString(CultureInfo.InvariantCulture));
432                                 Output.Write ("UI");
433                         } else if (e.Value is ulong) {
434                                 ulong ul = (ulong) e.Value;
435                                 Output.Write (ul.ToString(CultureInfo.InvariantCulture));
436                                 Output.Write ("UL");
437                         } else if (e.Value is sbyte) {
438                                 sbyte sb = (sbyte) e.Value;
439                                 Output.Write ("CSByte(");
440                                 Output.Write (sb.ToString(CultureInfo.InvariantCulture));
441                                 Output.Write (')');
442 #else
443                                 Output.Write("Microsoft.VisualBasic.ChrW(" + ch.ToString(CultureInfo.InvariantCulture) + ")");
444 #endif
445                         } else {
446                                 base.GeneratePrimitiveExpression(e);
447                         }
448                 }
449
450                 protected override void GenerateSingleFloatValue (float s)
451                 {
452                         base.GenerateSingleFloatValue (s);
453                         base.Output.Write ('!');
454                 }
455
456                 protected override void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression expression)
457                 {
458                         if (expression.TargetObject != null) {
459                                 GenerateMemberReferenceExpression (expression.TargetObject, expression.PropertyName);
460                         } else {
461                                 Output.Write (CreateEscapedIdentifier (expression.PropertyName));
462                         }
463                 }
464
465                 protected override void GeneratePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression expression)
466                 {
467                         Output.Write ("Value"); 
468                 }
469
470                 protected override void GenerateThisReferenceExpression (CodeThisReferenceExpression expression)
471                 {
472                         Output.Write ("Me");
473                 }
474
475                 protected override void GenerateExpressionStatement (CodeExpressionStatement statement)
476                 {
477                         GenerateExpression (statement.Expression);
478                         Output.WriteLine (); //start new line
479                 }
480
481                 protected override void GenerateIterationStatement (CodeIterationStatement statement)
482                 {
483                         TextWriter output = Output;
484
485                         GenerateStatement (statement.InitStatement);
486                         output.Write ("Do While ");
487                         GenerateExpression (statement.TestExpression);
488                         output.WriteLine ();
489                         Indent++;
490                         GenerateStatements (statement.Statements);
491                         GenerateStatement (statement.IncrementStatement);
492                         Indent--;
493                         output.WriteLine ("Loop");
494                 }
495
496                 protected override void GenerateThrowExceptionStatement (CodeThrowExceptionStatement statement)
497                 {
498                         Output.Write ("Throw");
499                         if (statement.ToThrow != null) {
500                                 Output.Write (' ');
501                                 GenerateExpression (statement.ToThrow);
502                         }
503                         Output.WriteLine ();
504                 }
505
506                 protected override void GenerateComment (CodeComment comment)
507                 {
508                         TextWriter output = Output;
509                         string commentChars = null;
510
511                         if (comment.DocComment) {
512                                 commentChars = "'''";
513                         } else {
514                                 commentChars = "'";
515                         }
516         
517                         output.Write (commentChars);
518                         string text = comment.Text;
519
520                         for (int i = 0; i < text.Length; i++) {
521                                 output.Write (text [i]);
522                                 if (text[i] == '\r') {
523                                         if (i < (text.Length - 1) && text [i + 1] == '\n') {
524                                                 continue;
525                                         }
526                                         output.Write (commentChars);
527                                 } else if (text [i] == '\n') {
528                                         output.Write (commentChars);
529                                 }
530                         }
531
532                         output.WriteLine ();
533                 }
534
535                 protected override void GenerateMethodReturnStatement (CodeMethodReturnStatement statement)
536                 {
537                         TextWriter output = Output;
538
539                         if (statement.Expression != null) {
540                                 output.Write ("Return ");
541                                 GenerateExpression (statement.Expression);
542                                 output.WriteLine ();
543                         } else {
544                                 output.WriteLine ("Return");
545                         }
546                 }
547
548                 protected override void GenerateConditionStatement (CodeConditionStatement statement)
549                 {
550                         TextWriter output = Output;
551                         output.Write ("If ");
552
553                         GenerateExpression (statement.Condition);
554
555                         output.WriteLine (" Then");
556                         ++Indent;
557                         GenerateStatements (statement.TrueStatements);
558                         --Indent;
559
560                         CodeStatementCollection falses = statement.FalseStatements;
561                         if (falses.Count > 0) {
562                                 output.WriteLine ("Else");
563                                 ++Indent;
564                                 GenerateStatements (falses);
565                                 --Indent;
566                         }
567                         else {
568                                 if (Options.ElseOnClosing)
569                                         output.WriteLine ("Else");
570                         }
571                         output.WriteLine ("End If");
572                 }
573
574                 protected override void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement statement)
575                 {
576                         TextWriter output = Output;
577
578                         output.WriteLine ("Try ");
579                         ++Indent;
580                         GenerateStatements (statement.TryStatements);
581                         --Indent;
582                         
583                         foreach (CodeCatchClause clause in statement.CatchClauses) {
584                                 output.Write ("Catch ");
585                                 OutputTypeNamePair (clause.CatchExceptionType, clause.LocalName);
586                                 output.WriteLine ();
587                                 ++Indent;
588                                 GenerateStatements (clause.Statements);
589                                 --Indent;
590                         }
591
592                         CodeStatementCollection finallies = statement.FinallyStatements;
593                         if (finallies.Count > 0) {
594                                 output.WriteLine ("Finally");
595                                 ++Indent;
596                                 GenerateStatements (finallies);
597                                 --Indent;
598                         }
599
600                         output.WriteLine("End Try");
601                 }
602
603                 protected override void GenerateAssignStatement (CodeAssignStatement statement)
604                 {
605                         TextWriter output = Output;
606                         GenerateExpression (statement.Left);
607                         output.Write (" = ");
608                         GenerateExpression (statement.Right);
609                         output.WriteLine ();
610                 }
611
612                 protected override void GenerateAttachEventStatement (CodeAttachEventStatement statement)
613                 {
614                         TextWriter output = Output;
615
616                         Output.Write ("AddHandler ");
617                         if (statement.Event.TargetObject != null) {
618                                 GenerateEventReferenceExpression (statement.Event);
619                         } else {
620                                 Output.Write (CreateEscapedIdentifier (statement.Event.EventName));
621                         }
622                         Output.Write ( ", ");
623                         GenerateExpression (statement.Listener);
624                         output.WriteLine ();
625                 }
626
627                 protected override void GenerateRemoveEventStatement (CodeRemoveEventStatement statement)
628                 {
629                         TextWriter output = Output;
630
631                         Output.Write ("RemoveHandler ");
632                         if (statement.Event.TargetObject != null) {
633                                 GenerateEventReferenceExpression (statement.Event);
634                         } else {
635                                 Output.Write (CreateEscapedIdentifier (statement.Event.EventName));
636                         }
637                         Output.Write ( ", ");
638                         GenerateExpression (statement.Listener);
639                         output.WriteLine ();
640                 }
641
642                 protected override void GenerateGotoStatement (CodeGotoStatement statement)
643                 {
644                         TextWriter output = Output;
645
646                         output.Write ("goto ");
647                         output.Write (statement.Label);
648                         output.WriteLine ();
649                 }
650                 
651                 protected override void GenerateLabeledStatement (CodeLabeledStatement statement)
652                 {
653                         TextWriter output = Output;
654
655                         Indent--;
656                         output.WriteLine (statement.Label + ":");
657                         Indent++;
658                         if (statement.Statement != null) {
659                                 GenerateStatement (statement.Statement);
660                         }
661                 }
662
663                 protected override void GenerateTypeOfExpression (CodeTypeOfExpression e)
664                 {
665                         TextWriter output = Output;
666
667                         output.Write ("GetType(");
668                         OutputType (e.Type);
669                         output.Write (")");
670                 }
671
672                 protected override void GenerateVariableDeclarationStatement( CodeVariableDeclarationStatement statement )
673                 {
674                         TextWriter output = Output;
675
676                         output.Write ("Dim ");
677                         OutputTypeNamePair (statement.Type, statement.Name);
678
679                         CodeExpression initExpression = statement.InitExpression;
680                         if (initExpression != null) {
681                                 output.Write (" = ");
682                                 GenerateExpression (initExpression);
683                         }
684
685                         output.WriteLine();
686                 }
687
688                 protected override void GenerateLinePragmaStart (CodeLinePragma linePragma)
689                 {
690                         Output.WriteLine ();
691                         Output.Write ("#ExternalSource(\"");
692                         Output.Write (linePragma.FileName);
693                         Output.Write ("\",");
694                         Output.Write (linePragma.LineNumber);
695                         Output.WriteLine (")");
696                         Output.WriteLine ("");
697                 }
698
699                 protected override void GenerateLinePragmaEnd (CodeLinePragma linePragma)
700                 {
701                         Output.WriteLine ("#End ExternalSource");
702                 }
703
704                 protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)
705                 {
706                         if (IsCurrentDelegate || IsCurrentEnum)
707                                 return;
708
709                         TextWriter output = Output;
710
711                         OutputAttributes (eventRef.CustomAttributes, null,
712                                 LineHandling.ContinueLine);
713
714                         OutputMemberAccessModifier (eventRef.Attributes);
715
716                         output.Write ("Event ");
717                         OutputTypeNamePair (eventRef.Type, GetEventName(eventRef));
718
719 #if NET_2_0
720                         if (eventRef.ImplementationTypes.Count > 0) {
721                                 OutputImplementationTypes (eventRef.ImplementationTypes, eventRef.Name);
722                         } else if (eventRef.PrivateImplementationType != null) {
723                                 output.Write (" Implements ");
724                                 OutputType (eventRef.PrivateImplementationType);
725                                 output.Write ('.');
726                                 output.Write (eventRef.Name);
727                         }
728 #endif
729
730                         output.WriteLine ();
731                 }
732
733                 protected override void GenerateField (CodeMemberField field)
734                 {
735                         if (IsCurrentDelegate || IsCurrentInterface)
736                                 return;
737
738                         TextWriter output = Output;
739
740                         OutputAttributes (field.CustomAttributes, null, 
741                                 LineHandling.ContinueLine);
742
743                         if (IsCurrentEnum) {
744                                 output.Write (field.Name);
745                         } else {
746                                 MemberAttributes attributes = field.Attributes;
747                                 OutputMemberAccessModifier (attributes);
748                                 OutputVTableModifier (attributes);
749                                 OutputFieldScopeModifier (attributes);
750                                 OutputTypeNamePair (field.Type, field.Name);
751                         }
752
753                         CodeExpression initExpression = field.InitExpression;
754                         if (initExpression != null) {
755                                 output.Write (" = ");
756                                 GenerateExpression (initExpression);
757                         }
758
759                         output.WriteLine();
760                 }
761                 
762                 protected override void GenerateSnippetMember (CodeSnippetTypeMember member)
763                 {
764                         Output.Write (member.Text);
765                 }
766                 
767                 protected override void GenerateEntryPointMethod (CodeEntryPointMethod method, CodeTypeDeclaration declaration)
768                 {
769 #if NET_2_0
770                         OutputAttributes (method.CustomAttributes, null,
771                                 LineHandling.ContinueLine);
772 #endif
773
774                         Output.WriteLine ("Public Shared Sub Main()");
775                         Indent++;
776                         GenerateStatements (method.Statements);
777                         Indent--;
778                         Output.WriteLine ("End Sub");
779                 }
780                 
781                 [MonoTODO ("partially implemented")]
782                 protected override void GenerateMethod (CodeMemberMethod method, CodeTypeDeclaration declaration)
783                 {
784                         if (IsCurrentDelegate || IsCurrentEnum)
785                                 return;
786
787                         bool isSub = method.ReturnType.BaseType == typeof(void).FullName;
788
789                         TextWriter output = Output;
790
791                         OutputAttributes (method.CustomAttributes, null, 
792                                 LineHandling.ContinueLine);
793
794                         MemberAttributes attributes = method.Attributes;
795
796                         if (!IsCurrentInterface) {
797                                 if (method.PrivateImplementationType == null) {
798                                         OutputMemberAccessModifier (attributes);
799                                         if (IsOverloaded (method, declaration)) {
800                                                 output.Write ("Overloads ");
801                                         }
802                                 }
803                                 OutputVTableModifier (attributes);
804                                 OutputMemberScopeModifier (attributes);
805                         } else {
806                                 OutputVTableModifier (attributes);
807                         }
808
809                         if (isSub)
810                                 output.Write ("Sub ");
811                         else
812                                 output.Write ("Function ");
813
814                         output.Write (GetMethodName(method));
815
816 #if NET_2_0
817                         OutputTypeParameters (method.TypeParameters);
818 #endif
819
820                         output.Write ('(');
821                         OutputParameters (method.Parameters);
822                         output.Write (')');
823
824                         if (!isSub) {
825                                 output.Write (" As ");
826                                 OutputAttributes (method.ReturnTypeCustomAttributes, null,
827                                         LineHandling.InLine);
828                                 OutputType (method.ReturnType);
829                         }
830
831                         if (method.ImplementationTypes.Count > 0) {
832                                 OutputImplementationTypes (method.ImplementationTypes, method.Name);
833                         } else if (method.PrivateImplementationType != null) {
834                                 output.Write (" Implements ");
835                                 OutputType (method.PrivateImplementationType);
836                                 output.Write ('.');
837                                 output.Write (method.Name);
838                         }
839
840                         output.WriteLine ();
841                         if (!IsCurrentInterface) {
842                                 if ((attributes & MemberAttributes.ScopeMask) != MemberAttributes.Abstract) {
843                                         ++Indent;
844                                         GenerateStatements (method.Statements);
845                                         --Indent;
846                                         if (isSub)
847                                                 output.WriteLine ("End Sub");
848                                         else
849                                                 output.WriteLine ("End Function");
850                                 }
851                         }
852                 }
853
854                 protected override void GenerateProperty (CodeMemberProperty property, CodeTypeDeclaration declaration)
855                 {
856                         if (IsCurrentDelegate || IsCurrentEnum)
857                                 return;
858
859                         TextWriter output = Output;
860
861                         OutputAttributes (property.CustomAttributes, null, 
862                                 LineHandling.ContinueLine);
863
864                         MemberAttributes attributes = property.Attributes;
865
866                         if (!IsCurrentInterface) {
867                                 if (property.PrivateImplementationType == null) {
868                                         OutputMemberAccessModifier (attributes);
869                                         if (IsOverloaded (property, declaration)) {
870                                                 output.Write ("Overloads ");
871                                         }
872                                 }
873                                 OutputVTableModifier (attributes);
874                                 OutputMemberScopeModifier (attributes);
875                         } else {
876                                 OutputVTableModifier (attributes);
877                         }
878
879                         // mark property as default property if we're dealing with an indexer
880                         if (string.Compare (GetPropertyName(property), "Item", true, CultureInfo.InvariantCulture) == 0 && property.Parameters.Count > 0) {
881                                 output.Write ("Default ");
882                         }
883
884                         if (property.HasGet && (!property.HasSet))
885                                 output.Write ("ReadOnly " );
886
887                         if (property.HasSet && (!property.HasGet))
888                                 output.Write ("WriteOnly " );
889
890                         output.Write ("Property ");
891                         Output.Write (GetPropertyName (property));
892 #if NET_2_0
893                         // in .NET 2.0, always output parantheses (whether or not there 
894                         // are any parameters to output
895                         Output.Write ('(');
896                         OutputParameters (property.Parameters);
897                         Output.Write (')');
898 #else
899                         if (property.Parameters.Count > 0) {
900                                 Output.Write ('(');
901                                 OutputParameters (property.Parameters);
902                                 Output.Write (')');
903                         }
904 #endif
905                         Output.Write (" As ");
906                         Output.Write (GetTypeOutput(property.Type));
907
908                         if (property.ImplementationTypes.Count > 0) {
909                                 OutputImplementationTypes (property.ImplementationTypes, property.Name);
910                         } else if (property.PrivateImplementationType != null) {
911                                 output.Write (" Implements ");
912                                 OutputType (property.PrivateImplementationType);
913                                 output.Write ('.');
914                                 output.Write (property.Name);
915                         }
916
917                         output.WriteLine ();
918
919                         if (!IsCurrentInterface) {
920                                 ++Indent;
921                                 if (property.HasGet) {
922                                         output.WriteLine ("Get");
923                                         ++Indent;
924                                         GenerateStatements (property.GetStatements);
925                                         --Indent;
926                                         output.WriteLine ("End Get");
927                                 }
928
929                                 if (property.HasSet) {
930                                         output.WriteLine ("Set");
931                                         ++Indent;
932                                         GenerateStatements (property.SetStatements);
933                                         --Indent;
934                                         output.WriteLine ("End Set");
935                                 }
936
937                                 --Indent;
938                                 output.WriteLine ("End Property");
939                         }
940                 }
941
942                 protected override void GenerateConstructor (CodeConstructor constructor, CodeTypeDeclaration declaration)
943                 {
944                         if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface)
945                                 return;
946
947                         OutputAttributes (constructor.CustomAttributes, null,
948                                 LineHandling.ContinueLine);
949                         OutputMemberAccessModifier (constructor.Attributes);
950                         Output.Write ("Sub New(");
951                         OutputParameters (constructor.Parameters);
952                         Output.WriteLine (")");
953                         Indent++;
954                         // check if ctor passes args on to other ctor in class
955                         CodeExpressionCollection ctorArgs = constructor.ChainedConstructorArgs;
956                         if (ctorArgs.Count > 0) {
957                                 Output.Write ("Me.New(");
958                                 OutputExpressionList (ctorArgs);
959                                 Output.WriteLine (")");
960                         } else {
961                                 // check if ctor passes args on to ctor in base class
962                                 ctorArgs = constructor.BaseConstructorArgs;
963                                 if (ctorArgs.Count > 0) {
964                                         Output.Write ("MyBase.New(");
965                                         OutputExpressionList (ctorArgs);
966                                         Output.WriteLine (")");
967 #if NET_2_0
968                                 } else if (IsCurrentClass) {
969 #else
970                                 } else {
971 #endif
972                                         // call default base ctor
973                                         Output.WriteLine ("MyBase.New");
974                                 }
975                         }
976                         GenerateStatements (constructor.Statements);
977                         Indent--;
978                         Output.WriteLine ("End Sub");
979                 }
980                 
981                 protected override void GenerateTypeConstructor (CodeTypeConstructor constructor)
982                 {
983                         if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface)
984                                 return;
985
986 #if NET_2_0
987                         OutputAttributes (constructor.CustomAttributes, null,
988                                 LineHandling.ContinueLine);
989 #endif
990
991                         Output.WriteLine ("Shared Sub New()");
992                         Indent++;
993                         GenerateStatements (constructor.Statements);
994                         Indent--;
995                         Output.WriteLine ("End Sub");
996                 }
997
998                 [MonoTODO ("partially implemented")]
999                 protected override void GenerateTypeStart (CodeTypeDeclaration declaration)
1000                 {
1001                         TextWriter output = Output;
1002
1003                         OutputAttributes (declaration.CustomAttributes, null, 
1004                                 LineHandling.ContinueLine);
1005
1006                         TypeAttributes attributes = declaration.TypeAttributes;
1007
1008                         if (IsCurrentDelegate) {
1009                                 CodeTypeDelegate delegateDecl = (CodeTypeDelegate) declaration;
1010
1011                                 if ((attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) {
1012                                         output.Write ("Public ");
1013                                 }
1014
1015                                 bool isSub = delegateDecl.ReturnType.BaseType == typeof (void).FullName;
1016                                 if (isSub) {
1017                                         output.Write ("Delegate Sub ");
1018                                 } else {
1019                                         output.Write ("Delegate Function ");
1020                                 }
1021
1022                                 output.Write (CreateEscapedIdentifier (delegateDecl.Name));
1023 #if NET_2_0
1024                                 OutputTypeParameters (delegateDecl.TypeParameters);
1025 #endif
1026                                 output.Write ("(");
1027                                 OutputParameters (delegateDecl.Parameters);
1028                                 Output.Write (")");
1029                                 if (!isSub) {
1030                                         Output.Write (" As ");
1031                                         OutputType (delegateDecl.ReturnType);
1032                                 }
1033                                 Output.WriteLine ("");
1034                         } else {
1035                                 OutputTypeAttributes (declaration);
1036                                 output.Write (CreateEscapedIdentifier (declaration.Name));
1037 #if NET_2_0
1038                                 OutputTypeParameters (declaration.TypeParameters);
1039 #endif
1040
1041                                 if (IsCurrentEnum) {
1042                                         if (declaration.BaseTypes.Count > 0) {
1043                                                 output.Write (" As ");
1044                                                 OutputType (declaration.BaseTypes[0]);
1045                                         }
1046                                         output.WriteLine ();
1047                                         ++Indent;
1048                                 } else {
1049                                         ++Indent;
1050
1051                                         bool firstInherits = true;
1052                                         bool firstImplements = true;
1053
1054                                         for (int i = 0; i < declaration.BaseTypes.Count; i++) {
1055                                                 // a struct can only implement interfaces
1056                                                 // an interface can only inherit from other interface
1057
1058                                                 CodeTypeReference typeRef = declaration.BaseTypes[i];
1059                                                 
1060                                                 if (firstInherits && !declaration.IsStruct && !typeRef.IsInterface) {
1061                                                         output.WriteLine ();
1062                                                         output.Write ("Inherits ");
1063                                                         firstInherits = false;
1064                                                 } else if (!declaration.IsInterface && firstImplements) {
1065                                                         output.WriteLine ();
1066                                                         output.Write ("Implements ");
1067                                                         firstImplements = false;
1068                                                 } else {
1069                                                         output.Write (", ");
1070                                                 }
1071                                                 OutputType (typeRef);
1072                                         }
1073                                         output.WriteLine ();
1074                                 }
1075                         }
1076                 }
1077
1078                 protected override void GenerateTypeEnd (CodeTypeDeclaration declaration)
1079                 {
1080                         if (IsCurrentDelegate) {
1081                                 return;
1082                         }
1083                         string output = string.Empty;
1084
1085                         --Indent;
1086                         if (declaration.IsStruct)
1087                                 output = "End Structure";
1088                         if (declaration.IsInterface)
1089                                 output = "End Interface";
1090                         if (declaration.IsEnum)
1091                                 output = "End Enum";
1092                         if (declaration.IsClass)
1093                                 output = "End Class";
1094
1095                         Output.WriteLine (output);
1096                 }
1097
1098                 protected override void GenerateNamespace(CodeNamespace ns)
1099                 {
1100                         GenerateNamespaceImports (ns);
1101                         Output.WriteLine ();
1102                         GenerateCommentStatements (ns.Comments);
1103                         GenerateNamespaceStart (ns); 
1104                         GenerateTypes (ns);
1105                         GenerateNamespaceEnd (ns);
1106                 }
1107
1108
1109                 protected override void GenerateNamespaceStart (CodeNamespace ns)
1110                 {
1111                         TextWriter output = Output;
1112                         
1113                         string name = ns.Name;
1114                         if (name != null && name != string.Empty) {
1115                                 output.Write ("Namespace ");
1116                                 output.WriteLine (name);
1117                                 ++Indent;
1118                         }
1119                 }
1120
1121                 protected override void GenerateNamespaceEnd (CodeNamespace ns)
1122                 {
1123                         string name = ns.Name;
1124                         if (name != null && name != string.Empty) {
1125                                 --Indent;
1126                                 Output.WriteLine ("End Namespace");
1127                         }
1128                 }
1129
1130                 protected override void GenerateNamespaceImport (CodeNamespaceImport import)
1131                 {
1132                         TextWriter output = Output;
1133
1134                         output.Write ("Imports ");
1135                         output.Write (import.Namespace);
1136                         output.WriteLine ();
1137                 }
1138                 
1139                 protected override void GenerateAttributeDeclarationsStart (CodeAttributeDeclarationCollection attributes)
1140                 {
1141                         Output.Write ('<');
1142                 }
1143                 
1144                 protected override void GenerateAttributeDeclarationsEnd (CodeAttributeDeclarationCollection attributes)
1145                 {
1146                         Output.Write (">");
1147                 }
1148
1149                 private void OutputAttributes (CodeAttributeDeclarationCollection attributes, string prefix, LineHandling lineHandling) {
1150                         if (attributes.Count == 0) {
1151                                 return;
1152                         }
1153
1154                         GenerateAttributeDeclarationsStart (attributes);
1155
1156                         IEnumerator enumerator = attributes.GetEnumerator ();
1157                         if (enumerator.MoveNext ()) {
1158                                 CodeAttributeDeclaration att = (CodeAttributeDeclaration) enumerator.Current;
1159                                 if (prefix != null) {
1160                                         Output.Write (prefix);
1161                                 }
1162                                 OutputAttributeDeclaration (att);
1163
1164                                 while (enumerator.MoveNext ()) {
1165                                         Output.Write (", ");
1166                                         if (lineHandling != LineHandling.InLine) {
1167                                                 ContinueOnNewLine ("");
1168                                                 Output.Write (" ");
1169                                         }
1170                                         att = (CodeAttributeDeclaration) enumerator.Current;
1171                                         if (prefix != null) {
1172                                                 Output.Write (prefix);
1173                                         }
1174                                         OutputAttributeDeclaration (att);
1175                                 }
1176                         }
1177                         GenerateAttributeDeclarationsEnd (attributes);
1178                         Output.Write (" ");
1179
1180                         switch (lineHandling) {
1181                                 case LineHandling.ContinueLine:
1182                                         ContinueOnNewLine ("");
1183                                         break;
1184                                 case LineHandling.NewLine:
1185                                         Output.WriteLine ();
1186                                         break;
1187                         }
1188                 }
1189
1190                 protected override void OutputAttributeArgument (CodeAttributeArgument argument)
1191                 {
1192                         string name = argument.Name;
1193                         if (name != null && name.Length > 0) {
1194                                 Output.Write (name);
1195                                 Output.Write (":=");
1196                         }
1197                         GenerateExpression (argument.Value);
1198                 }
1199
1200                 private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
1201                 {
1202                         Output.Write (attribute.Name.Replace ('+', '.'));
1203                         Output.Write ('(');
1204                         IEnumerator enumerator = attribute.Arguments.GetEnumerator ();
1205                         if (enumerator.MoveNext ()) {
1206                                 CodeAttributeArgument argument = (CodeAttributeArgument) enumerator.Current;
1207                                 OutputAttributeArgument (argument);
1208
1209                                 while (enumerator.MoveNext ()) {
1210                                         Output.Write (", ");
1211                                         argument = (CodeAttributeArgument) enumerator.Current;
1212                                         OutputAttributeArgument (argument);
1213                                 }
1214                         }
1215                         Output.Write (')');
1216                 }
1217
1218                 protected override void OutputDirection (FieldDirection direction)
1219                 {
1220                         switch (direction) {
1221                         case FieldDirection.In:
1222                                 Output.Write ("ByVal ");
1223                                 break;
1224                         case FieldDirection.Out:
1225                         case FieldDirection.Ref:
1226                                 Output.Write ("ByRef ");
1227                                 break;
1228                         }
1229                 }
1230
1231                 protected override void OutputFieldScopeModifier (MemberAttributes attributes)
1232                 {
1233                         switch (attributes & MemberAttributes.ScopeMask) {
1234                         case MemberAttributes.Static:
1235                                 Output.Write ("Shared ");
1236                                 break;
1237                         case MemberAttributes.Const:
1238                                 Output.Write ("Const ");
1239                                 break;
1240                         }
1241                 }
1242
1243                 private void OutputImplementationTypes (CodeTypeReferenceCollection implementationTypes, string member)
1244                 {
1245                         IEnumerator enumerator = implementationTypes.GetEnumerator ();
1246                         if (enumerator.MoveNext ()) {
1247                                 Output.Write (" Implements ");
1248
1249                                 CodeTypeReference typeReference = (CodeTypeReference) enumerator.Current;
1250                                 OutputType (typeReference);
1251                                 Output.Write ('.');
1252                                 OutputIdentifier (member);
1253
1254                                 while (enumerator.MoveNext ()) {
1255                                         Output.Write (" , ");
1256                                         typeReference = (CodeTypeReference) enumerator.Current;
1257                                         OutputType (typeReference);
1258                                         Output.Write ('.');
1259                                         OutputIdentifier (member);
1260                                 }
1261                         }
1262                 }
1263
1264                 protected override void OutputMemberAccessModifier (MemberAttributes attributes)
1265                 {
1266                         switch (attributes & MemberAttributes.AccessMask) {
1267                         case MemberAttributes.Assembly:
1268                         case MemberAttributes.FamilyAndAssembly:
1269                                 Output.Write ("Friend "); 
1270                                 break;
1271                         case MemberAttributes.Family:
1272                                 Output.Write ("Protected ");
1273                                 break;
1274                         case MemberAttributes.FamilyOrAssembly:
1275                                 Output.Write ("Protected Friend ");
1276                                 break;
1277                         case MemberAttributes.Private:
1278                                 Output.Write ("Private ");
1279                                 break;
1280                         case MemberAttributes.Public:
1281                                 Output.Write ("Public ");
1282                                 break;
1283                         }
1284                 }
1285
1286                 private void OutputVTableModifier (MemberAttributes attributes)
1287                 {
1288                         if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New)
1289                                 Output.Write ("Shadows ");
1290                 }
1291
1292                 protected override void OutputMemberScopeModifier (MemberAttributes attributes)
1293                 {
1294                         switch (attributes & MemberAttributes.ScopeMask) {
1295                         case MemberAttributes.Abstract:
1296                                 Output.Write ("MustOverride ");
1297                                 break;
1298                         case MemberAttributes.Final:
1299                                 // do nothing
1300                                 break;
1301                         case MemberAttributes.Static:
1302                                 Output.Write ("Shared ");
1303                                 break;
1304                         case MemberAttributes.Override:
1305                                 Output.Write ("Overrides ");
1306                                 break;
1307                         case MemberAttributes.Overloaded:
1308                                 // based on http://gendotnet.com/Code%20Gen%20Articles/codedom.htm
1309                                 Output.Write ("Overloads ");
1310
1311                                 MemberAttributes access_ovl = attributes & MemberAttributes.AccessMask;
1312                                 if (access_ovl == MemberAttributes.Public || access_ovl == MemberAttributes.Family)
1313                                         Output.Write ("Overridable ");
1314                                 break;
1315                         default:
1316                                 //
1317                                 // FUNNY! if the scope value is
1318                                 // rubbish (0 or >Const), and access
1319                                 // is public, protected make it
1320                                 // "virtual".
1321                                 //
1322                                 // i'm not sure whether this is 100%
1323                                 // correct, but it seems to be MS
1324                                 // behavior.
1325                                 //
1326                                 // On MS.NET 2.0, internal properties
1327                                 // are also marked "virtual".
1328                                 //
1329                                 MemberAttributes access = attributes & MemberAttributes.AccessMask;
1330                                 if (access == MemberAttributes.Public || 
1331 #if NET_2_0
1332                                         access == MemberAttributes.Family || access == MemberAttributes.Assembly)
1333 #else
1334                                         access == MemberAttributes.Family)
1335 #endif
1336                                         Output.Write ("Overridable ");
1337                                 break;
1338                         }
1339                 }
1340
1341                 protected override void OutputOperator (CodeBinaryOperatorType op)
1342                 {
1343                         switch (op) {
1344                         case CodeBinaryOperatorType.Add:
1345                                 Output.Write ("+");
1346                                 break;
1347                         case CodeBinaryOperatorType.Subtract:
1348                                 Output.Write ("-");
1349                                 break;
1350                         case CodeBinaryOperatorType.Multiply:
1351                                 Output.Write ("*");
1352                                 break;
1353                         case CodeBinaryOperatorType.Divide:
1354                                 Output.Write ("/");
1355                                 break;
1356                         case CodeBinaryOperatorType.Modulus:
1357                                 Output.Write ("Mod");
1358                                 break;
1359                         case CodeBinaryOperatorType.Assign:
1360                                 Output.Write ("=");
1361                                 break;
1362                         case CodeBinaryOperatorType.IdentityInequality:
1363                                 Output.Write ("<>");
1364                                 break;
1365                         case CodeBinaryOperatorType.IdentityEquality:
1366                                 Output.Write ("Is");
1367                                 break;
1368                         case CodeBinaryOperatorType.ValueEquality:
1369                                 Output.Write ("=");
1370                                 break;
1371                         case CodeBinaryOperatorType.BitwiseOr:
1372                                 Output.Write ("Or");
1373                                 break;
1374                         case CodeBinaryOperatorType.BitwiseAnd:
1375                                 Output.Write ("And");
1376                                 break;
1377                         case CodeBinaryOperatorType.BooleanOr:
1378                                 Output.Write ("OrElse");
1379                                 break;
1380                         case CodeBinaryOperatorType.BooleanAnd:
1381                                 Output.Write ("AndAlso");
1382                                 break;
1383                         case CodeBinaryOperatorType.LessThan:
1384                                 Output.Write ("<");
1385                                 break;
1386                         case CodeBinaryOperatorType.LessThanOrEqual:
1387                                 Output.Write ("<=");
1388                                 break;
1389                         case CodeBinaryOperatorType.GreaterThan:
1390                                 Output.Write (">");
1391                                 break;
1392                         case CodeBinaryOperatorType.GreaterThanOrEqual:
1393                                 Output.Write (">=");
1394                                 break;
1395                         }
1396                 }
1397
1398                 private void OutputTypeAttributes (CodeTypeDeclaration declaration)
1399                 {
1400                         TextWriter output = Output;
1401                         TypeAttributes attributes = declaration.TypeAttributes;
1402
1403 #if NET_2_0
1404                         if (declaration.IsPartial)
1405                                 output.Write ("Partial ");
1406 #endif
1407                         
1408                         switch (attributes & TypeAttributes.VisibilityMask) {
1409                         case TypeAttributes.Public:
1410                         case TypeAttributes.NestedPublic:
1411                                 output.Write ("Public ");
1412                                 break;
1413                         case TypeAttributes.NestedPrivate:
1414                                 output.Write ("Private ");
1415                                 break;
1416 #if NET_2_0
1417                         case TypeAttributes.NotPublic:
1418                         case TypeAttributes.NestedFamANDAssem:
1419                         case TypeAttributes.NestedAssembly:
1420                                 output.Write ("Friend ");
1421                                 break; 
1422                         case TypeAttributes.NestedFamily:
1423                                 output.Write ("Protected ");
1424                                 break;
1425                         case TypeAttributes.NestedFamORAssem:
1426                                 output.Write ("Protected Friend ");
1427                                 break;
1428 #endif
1429                         }
1430
1431                         if (declaration.IsStruct) {
1432                                 output.Write ("Structure ");
1433                         } else if (declaration.IsEnum) {
1434                                 output.Write ("Enum ");
1435                         } else {
1436                                 if ((attributes & TypeAttributes.Interface) != 0) {
1437                                         output.Write ("Interface ");
1438                                 } else {
1439                                         if ((attributes & TypeAttributes.Sealed) != 0)
1440                                                 output.Write ("NotInheritable ");
1441
1442                                         if ((attributes & TypeAttributes.Abstract) != 0)
1443                                                 output.Write ("MustInherit ");
1444
1445                                         output.Write ("Class ");
1446                                 }
1447                         }
1448                 }
1449
1450 #if NET_2_0
1451                 void OutputTypeParameters (CodeTypeParameterCollection parameters)
1452                 {
1453                         int count = parameters.Count;
1454                         if (count == 0)
1455                                 return;
1456
1457                         Output.Write ("(Of ");
1458                         for (int i = 0; i < count; ++i) {
1459                                 if (i > 0)
1460                                         Output.Write (", ");
1461                                 CodeTypeParameter p = parameters [i];
1462                                 Output.Write (p.Name);
1463                                 OutputTypeParameterConstraints (p);
1464                         }
1465                         Output.Write (')');
1466                 }
1467
1468                 void OutputTypeParameterConstraints (CodeTypeParameter parameter)
1469                 {
1470                         int constraint_count = parameter.Constraints.Count +
1471                                 (parameter.HasConstructorConstraint ? 1 : 0);
1472
1473                         if (constraint_count == 0)
1474                                 return;
1475
1476                         Output.Write (" As ");
1477
1478                         if (constraint_count > 1)
1479                                 Output.Write (" {");
1480
1481                         for (int i = 0; i < parameter.Constraints.Count; i++) {
1482                                 if (i > 0)
1483                                         Output.Write (", ");
1484                                 OutputType (parameter.Constraints [i]);
1485                         }
1486
1487                         if (parameter.HasConstructorConstraint) {
1488                                 if (constraint_count > 1)
1489                                         Output.Write (", ");
1490                                 Output.Write ("New");
1491                         }
1492
1493                         if (constraint_count > 1)
1494                                 Output.Write ("}");
1495                 }
1496 #endif
1497
1498                 protected override void OutputTypeNamePair (CodeTypeReference typeRef, String name)
1499                 {
1500 #if NET_2_0
1501                         if (name.Length == 0)
1502                                 name = "__exception";
1503 #endif
1504                         Output.Write (CreateEscapedIdentifier(name) + " As " + GetTypeOutput (typeRef));
1505                 }
1506
1507                 protected override void OutputType (CodeTypeReference type)
1508                 {
1509                         Output.Write (GetTypeOutput (type));
1510                 }
1511
1512                 protected override string QuoteSnippetString (string value)
1513                 {
1514                         StringBuilder mySBuilder = new StringBuilder(value.Length);
1515                         mySBuilder.Append ("\"");
1516                         bool inQuotes = true;
1517                         for (int MyCounter = 0; MyCounter < value.Length; MyCounter++) {
1518                                 if (value[MyCounter] == 34) //quotation mark
1519                                 {
1520                                         if (!inQuotes) {
1521                                                 mySBuilder.Append ("&\"");
1522                                                 inQuotes = true;
1523                                         }
1524                                         mySBuilder.Append (value[MyCounter]);
1525                                         mySBuilder.Append (value[MyCounter]);
1526                                 }
1527                                 else if (value[MyCounter] >= 32) //standard ansi/unicode characters
1528                                 {
1529                                         if (!inQuotes) {
1530                                                 mySBuilder.Append ("&\"");
1531                                                 inQuotes = true;
1532                                         }
1533                                         mySBuilder.Append (value[MyCounter]);
1534                                 }
1535                                 else //special chars, e.g. line break
1536                                 {
1537                                         if (inQuotes) {
1538                                                 mySBuilder.Append ("\"");
1539                                                 inQuotes = false;
1540                                         }
1541                                         mySBuilder.Append ("&Microsoft.VisualBasic.ChrW(");
1542                                         mySBuilder.Append ((int)value[MyCounter]); 
1543                                         mySBuilder.Append (")");
1544                                 }
1545                         }
1546                         if (inQuotes)
1547                                 mySBuilder.Append ("\"");
1548                         return mySBuilder.ToString();
1549                 }
1550
1551                 private void GenerateMemberReferenceExpression (CodeExpression targetObject, string memberName)
1552                 {
1553                         GenerateExpression (targetObject);
1554                         Output.Write ('.');
1555                         Output.Write (memberName);
1556                 }
1557                         
1558                 /* 
1559                  * ICodeGenerator
1560                  */
1561
1562                 protected override string CreateEscapedIdentifier (string value)
1563                 {
1564                         for (int x = 0; x < Keywords.Length; x++)
1565                                 if (value.ToLower().Equals (Keywords[x].ToLower()))
1566                                         return "[" + value + "]";
1567                         return value;
1568                 }
1569
1570                 protected override string CreateValidIdentifier (string value)
1571                 {
1572                         for (int x = 0; x < Keywords.Length; x++)
1573                                 if (value.ToLower().Equals (Keywords[x].ToLower()))
1574                                         return "_" + value;
1575                         return value;
1576                 }
1577
1578                 protected override string GetTypeOutput (CodeTypeReference type)
1579                 {
1580                         string output;
1581                         CodeTypeReference arrayType;
1582
1583                         arrayType = type.ArrayElementType;
1584                         if (arrayType != null)
1585                                 output = GetTypeOutput (arrayType);
1586                         else {
1587                                 switch (type.BaseType) {
1588                                 case "System.DateTime":
1589                                         output = "Date";
1590                                         break;
1591                                 case "System.Decimal":
1592                                         output = "Decimal";
1593                                         break;
1594                                 case "System.Double":
1595                                         output = "Double";
1596                                         break;
1597                                 case "System.Single":
1598                                         output = "Single";
1599                                         break;
1600                                 case "System.Byte":
1601                                         output = "Byte";
1602                                         break;
1603                                 case "System.Int32":
1604                                         output = "Integer";
1605                                         break;
1606                                 case "System.Int64":
1607                                         output = "Long";
1608                                         break;
1609                                 case "System.Int16":
1610                                         output = "Short";
1611                                         break;
1612                                 case "System.Boolean":
1613                                         output = "Boolean";
1614                                         break;
1615                                 case "System.Char":
1616                                         output = "Char";
1617                                         break;
1618                                 case "System.String":
1619                                         output = "String";
1620                                         break;
1621                                 case "System.Object":
1622                                         output = "Object";
1623                                         break;
1624 #if NET_2_0
1625                                 case "System.SByte":
1626                                         output = "SByte";
1627                                         break;
1628                                 case "System.UInt16":
1629                                         output = "UShort";
1630                                         break;
1631                                 case "System.UInt32":
1632                                         output = "UInteger";
1633                                         break;
1634                                 case "System.UInt64":
1635                                         output = "ULong";
1636                                         break;
1637 #endif
1638                                 default:
1639                                         output = type.BaseType.Replace('+', '.');
1640                                         output = CreateEscapedIdentifier (output);
1641                                         break;
1642                                 }
1643                         }
1644
1645                         int rank = type.ArrayRank;
1646                         if (rank > 0) {
1647                                 output += "(";
1648                                 for (--rank; rank > 0; --rank)
1649                                         output += ",";
1650                                 output += ")";
1651                         }
1652
1653                         return output;
1654                 }
1655
1656                 protected override bool IsValidIdentifier (string identifier)
1657                 {
1658                         for (int x = 0; x < Keywords.Length; x++)
1659                                 if (identifier.ToLower().Equals (Keywords[x].ToLower()))
1660                                         return false;
1661                         return true;
1662                 }
1663
1664                 protected override bool Supports (GeneratorSupport supports)
1665                 {
1666                         return true;
1667                 }
1668
1669                 private bool IsOverloaded (CodeMemberProperty property, CodeTypeDeclaration type)
1670                 {
1671                         if ((property.Attributes & MemberAttributes.Overloaded) == MemberAttributes.Overloaded) {
1672                                 return true;
1673                         }
1674
1675                         foreach (CodeTypeMember member in type.Members) {
1676                                 CodeMemberProperty p = member as CodeMemberProperty;
1677                                 if (p == null) {
1678                                         // member is not a property
1679                                         continue;
1680                                 }
1681
1682                                 if (p != property && p.Name == property.Name && p.PrivateImplementationType == null)
1683                                         return true;
1684                         }
1685                         return false;
1686                 }
1687
1688                 private bool IsOverloaded (CodeMemberMethod method, CodeTypeDeclaration type)
1689                 {
1690                         if ((method.Attributes & MemberAttributes.Overloaded) == MemberAttributes.Overloaded) {
1691                                 return true;
1692                         }
1693
1694                         foreach (CodeTypeMember member in type.Members) {
1695                                 CodeMemberMethod m = member as CodeMemberMethod;
1696                                 if (m == null) {
1697                                         // member is not a method
1698                                         continue;
1699                                 }
1700
1701                                 if (!(m is CodeTypeConstructor) && !(m is CodeConstructor) && m != method && m.Name == method.Name && m.PrivateImplementationType == null)
1702                                         return true;
1703                         }
1704                         return false;
1705                 }
1706
1707                 private string GetEventName (CodeMemberEvent evt)
1708                 {
1709 #if NET_2_0
1710                         if (evt.PrivateImplementationType == null)
1711                                 return evt.Name;
1712
1713                         string baseType = evt.PrivateImplementationType.BaseType.Replace ('.', '_');
1714                         return baseType + "_" + evt.Name;
1715 #else
1716                         return evt.Name;
1717 #endif
1718                 }
1719
1720                 private string GetMethodName (CodeMemberMethod method)
1721                 {
1722                         if (method.PrivateImplementationType == null)
1723                                 return method.Name;
1724
1725                         string baseType = method.PrivateImplementationType.BaseType.Replace ('.', '_');
1726                         return baseType + "_" + method.Name;
1727                 }
1728
1729                 private string GetPropertyName (CodeMemberProperty property)
1730                 {
1731                         if (property.PrivateImplementationType == null)
1732                                 return property.Name;
1733
1734                         string baseType = property.PrivateImplementationType.BaseType.Replace ('.', '_');
1735                         return baseType + "_" + property.Name;
1736                 }
1737
1738                 private enum LineHandling
1739                 {
1740                         InLine,
1741                         ContinueLine,
1742                         NewLine
1743                 }
1744         }
1745 }