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