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