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