6301ddf46432e6b3bf794f8495db61b281094b47
[mono.git] / mcs / class / referencesource / System / compmod / microsoft / visualbasic / VBCodeProvider.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="VBCodeProvider.cs" company="Microsoft">
3 // 
4 // <OWNER>gpaperin</OWNER>
5 //     Copyright (c) Microsoft Corporation.  All rights reserved.
6 // </copyright>                                                                
7 //------------------------------------------------------------------------------
8
9 using System.Diagnostics;
10 using System;
11 using System.IO;
12 using System.Collections;
13 using System.Collections.Specialized;
14 using System.ComponentModel;
15 using System.Reflection;
16 using System.CodeDom;
17 using System.Text;
18 using System.Text.RegularExpressions;
19 using System.Globalization;
20 using System.CodeDom.Compiler;
21 using System.Security.Permissions;
22 using Microsoft.Win32;
23 using System.Collections.Generic;
24 using System.Runtime.Versioning;
25
26 namespace Microsoft.VisualBasic {
27
28     #region class VBCodeProvider
29
30     /// <devdoc>
31     /// <para>[To be supplied.]</para>
32     /// </devdoc>
33     [PermissionSet(SecurityAction.LinkDemand, Name="FullTrust")]
34     [PermissionSet(SecurityAction.InheritanceDemand, Name="FullTrust")]
35     public class VBCodeProvider: CodeDomProvider {
36         private VBCodeGenerator generator;
37
38         public VBCodeProvider() {
39             generator = new VBCodeGenerator();
40         }
41
42         public VBCodeProvider(IDictionary<string, string> providerOptions) {
43             if (providerOptions == null) {
44                 throw new ArgumentNullException("providerOptions");
45             }
46
47             generator = new VBCodeGenerator(providerOptions);
48         }
49
50         /// <devdoc>
51         /// <para>Retrieves the default extension to use when saving files using this code dom provider.</para>
52         /// </devdoc>
53         public override string FileExtension {
54             get {
55                 return "vb";
56             }
57         }
58
59         /// <devdoc>
60         /// <para>Returns flags representing language variations.</para>
61         /// </devdoc>
62         public override LanguageOptions LanguageOptions {
63             get {
64                 return LanguageOptions.CaseInsensitive;
65             }
66         }
67
68         [Obsolete("Callers should not use the ICodeGenerator interface and should instead use the methods directly on the CodeDomProvider class.")]
69         public override ICodeGenerator CreateGenerator() {
70             return (ICodeGenerator)generator;
71         }
72
73         [Obsolete("Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.")]
74         public override ICodeCompiler CreateCompiler() {
75             return (ICodeCompiler)generator;
76         }
77
78         /// <devdoc>
79         /// This method allows a code dom provider implementation to provide a different type converter
80         /// for a given data type.  At design time, a designer may pass data types through this
81         /// method to see if the code dom provider wants to provide an additional converter.  
82         /// A typical way this would be used is if the language this code dom provider implements
83         /// does not support all of the values of the MemberAttributes enumeration, or if the language
84         /// uses different names (Protected instead of Family, for example).  The default 
85         /// implementation just calls TypeDescriptor.GetConverter for the given type.
86         /// </devdoc>
87         public override TypeConverter GetConverter(Type type) {
88             if (type == typeof(MemberAttributes)) {
89                 return VBMemberAttributeConverter.Default;
90             }
91             else if(type == typeof(TypeAttributes)) {
92                 return VBTypeAttributeConverter.Default;
93             }
94             
95             return base.GetConverter(type);
96         }
97         
98         public override void GenerateCodeFromMember(CodeTypeMember member, TextWriter writer, CodeGeneratorOptions options) {
99             generator.GenerateCodeFromMember(member, writer, options);
100         }
101         
102     }  // VBCodeProvider
103
104     #endregion class VBCodeProvider
105
106
107     #region class VBCodeGenerator
108
109     /// <devdoc>
110     ///    <para>
111     ///       Visual Basic 7 Code Generator.
112     ///    </para>
113     /// </devdoc>
114     internal class VBCodeGenerator : CodeCompiler {
115         private const int MaxLineLength = 80;
116
117         private const GeneratorSupport LanguageSupport = GeneratorSupport.EntryPointMethod |
118                                                          GeneratorSupport.GotoStatements |
119                                                          GeneratorSupport.ArraysOfArrays |
120                                                          GeneratorSupport.MultidimensionalArrays |
121                                                          GeneratorSupport.StaticConstructors |
122                                                          GeneratorSupport.ReturnTypeAttributes |
123                                                          GeneratorSupport.AssemblyAttributes |
124                                                          GeneratorSupport.TryCatchStatements |
125                                                          GeneratorSupport.DeclareValueTypes |
126                                                          GeneratorSupport.DeclareEnums | 
127                                                          GeneratorSupport.DeclareEvents | 
128                                                          GeneratorSupport.DeclareDelegates |
129                                                          GeneratorSupport.DeclareInterfaces |
130                                                          GeneratorSupport.ParameterAttributes |
131                                                          GeneratorSupport.ReferenceParameters |
132                                                          GeneratorSupport.ChainedConstructorArguments |
133                                                          GeneratorSupport.NestedTypes |
134                                                          GeneratorSupport.MultipleInterfaceMembers |
135                                                          GeneratorSupport.PublicStaticMembers |
136                                                          GeneratorSupport.ComplexExpressions |
137                                                          GeneratorSupport.Win32Resources |
138                                                          GeneratorSupport.Resources|
139                                                          GeneratorSupport.PartialTypes|
140                                                          GeneratorSupport.GenericTypeReference |
141                                                          GeneratorSupport.GenericTypeDeclaration |                                                         
142                                                          GeneratorSupport.DeclareIndexerProperties;
143
144         private static volatile Regex outputReg;
145         
146         private int statementDepth = 0;
147         private IDictionary<string, string> provOptions;
148             
149         // This is the keyword list. To minimize search time and startup time, this is stored by length
150         // and then alphabetically for use by FixedStringLookup.Contains.
151         private static readonly string[][] keywords = new string[][] {
152             null,           // 1 character
153             new string[] {  // 2 characters            
154                 "as",
155                 "do",
156                 "if",
157                 "in",
158                 "is",
159                 "me",
160                 "of",                
161                 "on",
162                 "or",
163                 "to",
164             },
165             new string[] {  // 3 characters
166                 "and",
167                 "dim",
168                 "end",
169                 "for",
170                 "get",
171                 "let",
172                 "lib",
173                 "mod",
174                 "new",
175                 "not",
176                 "rem",
177                 "set",
178                 "sub",
179                 "try",
180                 "xor",
181             },
182             new string[] {  // 4 characters
183                 "ansi",
184                 "auto",
185                 "byte",
186                 "call",
187                 "case",
188                 "cdbl",
189                 "cdec",
190                 "char",
191                 "cint",
192                 "clng",
193                 "cobj",
194                 "csng",
195                 "cstr",
196                 "date",
197                 "each",
198                 "else",
199                 "enum",
200                 "exit",
201                 "goto",
202                 "like",
203                 "long",
204                 "loop",
205                 "next",
206                 "step",
207                 "stop",
208                 "then",
209                 "true",
210                 "wend",
211                 "when",
212                 "with",
213             },
214             new string[] {  // 5 characters  
215                 "alias",
216                 "byref",
217                 "byval",
218                 "catch",
219                 "cbool",
220                 "cbyte",
221                 "cchar",
222                 "cdate",
223                 "class",
224                 "const",
225                 "ctype",
226                 "cuint",
227                 "culng",                
228                 "endif",
229                 "erase",
230                 "error",
231                 "event",
232                 "false",
233                 "gosub",
234                 "isnot",                
235                 "redim",
236                 "sbyte",
237                 "short",
238                 "throw",
239                 "ulong",
240                 "until",
241                 "using",
242                 "while",
243              },
244             new string[] {  // 6 characters
245                 "csbyte",
246                 "cshort",
247                 "double",
248                 "elseif",
249                 "friend",
250                 "global",
251                 "module",
252                 "mybase",
253                 "object",
254                 "option",
255                 "orelse",
256                 "public",
257                 "resume",
258                 "return",
259                 "select",
260                 "shared",
261                 "single",
262                 "static",
263                 "string",
264                 "typeof",
265                 "ushort",
266             },
267             new string[] { // 7 characters
268                 "andalso",
269                 "boolean",
270                 "cushort",
271                 "decimal",
272                 "declare",
273                 "default",
274                 "finally",
275                 "gettype",
276                 "handles",
277                 "imports",
278                 "integer",
279                 "myclass",
280                 "nothing",
281                 "partial",
282                 "private",
283                 "shadows",
284                 "trycast",
285                 "unicode",
286                 "variant",
287             },
288             new string[] {  // 8 characters
289                 "assembly",
290                 "continue",                    
291                 "delegate",
292                 "function",
293                 "inherits",
294                 "operator",                
295                 "optional",
296                 "preserve",
297                 "property",
298                 "readonly",
299                 "synclock",
300                 "uinteger",
301                 "widening"                
302             },
303             new string [] { // 9 characters
304                 "addressof",
305                 "interface",
306                 "namespace",
307                 "narrowing",                
308                 "overloads",
309                 "overrides",
310                 "protected",
311                 "structure",
312                 "writeonly",
313             },
314             new string [] { // 10 characters
315                 "addhandler",
316                 "directcast",
317                 "implements",
318                 "paramarray",
319                 "raiseevent",
320                 "withevents",
321             },
322             new string[] {  // 11 characters
323                 "mustinherit",
324                 "overridable",
325             },
326             new string[] { // 12 characters
327                 "mustoverride",
328             },
329             new string [] { // 13 characters
330                 "removehandler",
331             },
332             // class_finalize and class_initialize are not keywords anymore,
333             // but it will be nice to escape them to avoid warning
334             new string [] { // 14 characters
335                 "class_finalize",
336                 "notinheritable",
337                 "notoverridable",
338             },
339             null,           // 15 characters
340             new string [] {
341                 "class_initialize",
342             }
343         };
344
345         internal VBCodeGenerator() {
346         }
347
348         internal VBCodeGenerator(IDictionary<string, string> providerOptions) {
349             provOptions = providerOptions;
350         }
351
352
353 #if DEBUG
354         static VBCodeGenerator() {
355             FixedStringLookup.VerifyLookupTable(keywords, true);
356
357             // Sanity check: try some values;
358             Debug.Assert(IsKeyword("for"));
359             Debug.Assert(IsKeyword("foR"));
360             Debug.Assert(IsKeyword("cdec"));
361             Debug.Assert(!IsKeyword("cdab"));
362             Debug.Assert(!IsKeyword("cdum"));
363         }
364 #endif
365
366         /// <devdoc>
367         ///    <para>
368         ///       Gets or the file extension to use for source files.
369         ///    </para>
370         /// </devdoc>
371         protected override string FileExtension { get { return ".vb"; } }
372
373         /// <devdoc>
374         ///    <para>
375         ///       Gets the name of the compiler exe
376         ///    </para>
377         /// </devdoc>
378         protected override string CompilerName { get { return "vbc.exe"; } }
379
380         /// <devdoc>
381         ///    <para>
382         ///       Tells whether or not the current class should be generated as a module
383         ///    </para>
384         /// </devdoc>
385         private bool IsCurrentModule {
386             get {
387                 return (IsCurrentClass && GetUserData(CurrentClass, "Module", false));
388             }
389         }
390         
391         /// <devdoc>
392         ///    <para>
393         ///       Gets the token that is used to represent <see langword='null'/>.
394         ///    </para>
395         /// </devdoc>
396         protected override string NullToken {
397             get {
398                 return "Nothing";
399             }
400         }
401
402         private void EnsureInDoubleQuotes(ref bool fInDoubleQuotes, StringBuilder b) {
403             if (fInDoubleQuotes) return;
404             b.Append("&\"");
405             fInDoubleQuotes = true;
406         }
407
408         private void EnsureNotInDoubleQuotes(ref bool fInDoubleQuotes, StringBuilder b) {
409             if (!fInDoubleQuotes) return;
410             b.Append("\"");
411             fInDoubleQuotes = false;
412         }
413
414         /// <devdoc>
415         ///    <para>
416         ///       Provides conversion to formatting with escape codes.
417         ///    </para>
418         /// </devdoc>
419         protected override string QuoteSnippetString(string value) {
420             StringBuilder b = new StringBuilder(value.Length+5);
421
422             bool fInDoubleQuotes = true;
423             Indentation indentObj = new Indentation((IndentedTextWriter)Output, Indent + 1);
424
425             b.Append("\"");
426
427             int i = 0;
428             while(i < value.Length) {
429                 char ch = value[i];
430                 switch (ch) {
431                     case '\"':
432                     // These are the inward sloping quotes used by default in some cultures like CHS. 
433                     // VBC.EXE does a mapping ANSI that results in it treating these as syntactically equivalent to a
434                     // regular double quote.
435                     case '\u201C': 
436                     case '\u201D':
437                     case '\uFF02':
438                         EnsureInDoubleQuotes(ref fInDoubleQuotes, b);
439                         b.Append(ch);
440                         b.Append(ch);
441                         break;
442                     case '\r':
443                         EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b);
444                         if (i < value.Length - 1 && value[i+1] == '\n') {
445                             b.Append("&Global.Microsoft.VisualBasic.ChrW(13)&Global.Microsoft.VisualBasic.ChrW(10)");
446                             i++;
447                         }
448                         else {
449                             b.Append("&Global.Microsoft.VisualBasic.ChrW(13)");
450                         }
451                         break;
452                     case '\t':
453                         EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b);
454                         b.Append("&Global.Microsoft.VisualBasic.ChrW(9)");
455                         break;
456                     case '\0':
457                         EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b);
458                         b.Append("&Global.Microsoft.VisualBasic.ChrW(0)");
459                         break;
460                     case '\n':
461                         EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b);
462                         b.Append("&Global.Microsoft.VisualBasic.ChrW(10)");
463                         break;
464                     case '\u2028':
465                     case '\u2029':
466                         EnsureNotInDoubleQuotes(ref fInDoubleQuotes, b);
467                         AppendEscapedChar(b,ch);
468                         break;
469                     default:
470                         EnsureInDoubleQuotes(ref fInDoubleQuotes, b);
471                         b.Append(value[i]);
472                         break;
473                 }
474
475                 if (i > 0 && i % MaxLineLength == 0) {
476                     //
477                     // If current character is a high surrogate and the following 
478                     // character is a low surrogate, don't break them. 
479                     // Otherwise when we write the string to a file, we might lose 
480                     // the characters.
481                     // 
482                     if( Char.IsHighSurrogate(value[i])
483                         && (i < value.Length -1) 
484                         && Char.IsLowSurrogate(value[i+1])){ 
485                         b.Append(value[++i]);    
486                     }
487                                         
488                     if (fInDoubleQuotes)
489                         b.Append("\"");
490                     fInDoubleQuotes = true;
491
492                     b.Append("& _ ");
493                     b.Append(Environment.NewLine);                    
494                     b.Append(indentObj.IndentationString);
495                     b.Append('\"');
496                 }
497                 ++i;
498             }
499
500             if (fInDoubleQuotes)
501                 b.Append("\"");
502
503             return b.ToString();
504         }
505
506         //@
507         private static void AppendEscapedChar(StringBuilder b, char value) {
508             b.Append("&Global.Microsoft.VisualBasic.ChrW(");
509             b.Append(((int)value).ToString(CultureInfo.InvariantCulture));
510             b.Append(")");
511         }
512
513         protected override void ProcessCompilerOutputLine(CompilerResults results, string line) {
514             if (outputReg == null) {
515                 outputReg = new Regex(@"^([^(]*)\(?([0-9]*)\)? ?:? ?(error|warning) ([A-Z]+[0-9]+) ?: ((.|\n)*)");
516             }
517             Match m = outputReg.Match(line);
518             if (m.Success) {
519                 CompilerError ce = new CompilerError();
520                 ce.FileName = m.Groups[1].Value;
521                 string rawLine = m.Groups[2].Value;
522                 if (rawLine != null && rawLine.Length > 0) {
523                     ce.Line = int.Parse(rawLine, CultureInfo.InvariantCulture);
524                 }
525                 if (string.Compare(m.Groups[3].Value, "warning", StringComparison.OrdinalIgnoreCase) == 0) {
526                     ce.IsWarning = true;
527                 }
528                 ce.ErrorNumber = m.Groups[4].Value;
529                 ce.ErrorText = m.Groups[5].Value;
530                 results.Errors.Add(ce);
531             }
532         }
533
534         [ResourceExposure(ResourceScope.None)]
535         [ResourceConsumption(ResourceScope.Machine, ResourceScope.Machine)]
536         protected override string CmdArgsFromParameters(CompilerParameters options) {
537             // The VB Compiler throws an error if an empty string is specified as an assembly reference.
538             foreach (string s in options.ReferencedAssemblies)
539             {
540                 if(String.IsNullOrEmpty(s))
541                 {
542                     throw new ArgumentException(SR.GetString(SR.NullOrEmpty_Value_in_Property, "ReferencedAssemblies"), "options");
543                 }
544             }
545             
546             StringBuilder sb = new StringBuilder(128);
547             if (options.GenerateExecutable) {
548                 sb.Append("/t:exe ");
549                 if (options.MainClass != null && options.MainClass.Length > 0) {
550                     sb.Append("/main:");
551                     sb.Append(options.MainClass);
552                     sb.Append(" ");
553                 }
554             }
555             else {
556                 sb.Append("/t:library ");
557             }
558
559             // Get UTF8 output from the compiler
560             sb.Append("/utf8output ");
561
562             string coreAssemblyFileName = options.CoreAssemblyFileName;
563
564             if (String.IsNullOrWhiteSpace(options.CoreAssemblyFileName)) {
565                 string probableCoreAssemblyFilePath;
566                 if (CodeDomProvider.TryGetProbableCoreAssemblyFilePath(options, out probableCoreAssemblyFilePath)) {
567                     coreAssemblyFileName = probableCoreAssemblyFilePath;
568                 }
569             }
570
571             if (!String.IsNullOrWhiteSpace(coreAssemblyFileName)) {
572
573                 string asmblFilePath = coreAssemblyFileName.Trim();
574                 string asmblFileDir = Path.GetDirectoryName(asmblFilePath);
575
576                 sb.Append("/nostdlib ");
577                 sb.Append("/sdkpath:\"").Append(asmblFileDir).Append("\" ");
578                 sb.Append("/R:\"").Append(asmblFilePath).Append("\" ");
579             }
580
581             foreach (string s in options.ReferencedAssemblies) {
582
583                 // Ignore any Microsoft.VisualBasic.dll, since Visual Basic implies it (
584                 string fileName = Path.GetFileName(s);
585                 if (string.Compare(fileName, "Microsoft.VisualBasic.dll", StringComparison.OrdinalIgnoreCase) == 0)
586                     continue;
587
588                 // Same deal for mscorlib (
589                 if (string.Compare(fileName, "mscorlib.dll", StringComparison.OrdinalIgnoreCase) == 0)
590                     continue;
591
592                 sb.Append("/R:");
593                 sb.Append("\"");
594                 sb.Append(s);
595                 sb.Append("\"");
596                 sb.Append(" ");
597             }
598
599             sb.Append("/out:");
600             sb.Append("\"");
601             sb.Append(options.OutputAssembly);
602             sb.Append("\"");
603             sb.Append(" ");
604
605             if (options.IncludeDebugInformation) {
606                 sb.Append("/D:DEBUG=1 ");
607                 sb.Append("/debug+ ");
608             }
609             else {
610                 sb.Append("/debug- ");
611             }
612
613             if (options.Win32Resource != null) {
614                 sb.Append("/win32resource:\"" + options.Win32Resource + "\" ");
615             }
616
617             foreach (string s in options.EmbeddedResources) {
618                 sb.Append("/res:\"");
619                 sb.Append(s);
620                 sb.Append("\" ");
621             }
622
623             foreach (string s in options.LinkedResources) {
624                 sb.Append("/linkres:\"");
625                 sb.Append(s);
626                 sb.Append("\" ");
627             }
628
629             if (options.TreatWarningsAsErrors) {
630                 sb.Append("/warnaserror+ ");
631             }
632
633             if (options.CompilerOptions != null) {
634                 sb.Append(options.CompilerOptions + " ");
635             }
636
637             return sb.ToString();
638         }
639
640         protected override void OutputAttributeArgument(CodeAttributeArgument arg) {
641             if (arg.Name != null && arg.Name.Length > 0) {
642                 OutputIdentifier(arg.Name);
643                 Output.Write(":=");
644             }
645             ((ICodeGenerator)this).GenerateCodeFromExpression(arg.Value, ((IndentedTextWriter)Output).InnerWriter, Options);
646         }
647
648         private void OutputAttributes(CodeAttributeDeclarationCollection attributes, bool inLine) {
649             OutputAttributes(attributes, inLine, null, false);
650         }
651
652         private void OutputAttributes(CodeAttributeDeclarationCollection attributes, bool inLine, string prefix, bool closingLine) {
653             if (attributes.Count == 0) return;
654             IEnumerator en = attributes.GetEnumerator();
655             bool firstAttr = true;
656             GenerateAttributeDeclarationsStart(attributes);
657             while (en.MoveNext()) {
658
659                 if (firstAttr) {
660                     firstAttr = false;
661                 }
662                 else {
663                     Output.Write(", ");
664                     if (!inLine) {
665                         ContinueOnNewLine("");
666                         Output.Write(" ");
667                     }
668                 }
669
670                 if (prefix != null && prefix.Length > 0) {
671                     Output.Write(prefix);
672                 }
673
674                 CodeAttributeDeclaration current = (CodeAttributeDeclaration)en.Current;
675
676                 if( current.AttributeType != null) {                
677                     Output.Write(GetTypeOutput(current.AttributeType));
678                 }
679                 Output.Write("(");
680
681                 bool firstArg = true;
682                 foreach (CodeAttributeArgument arg in current.Arguments) {
683                     if (firstArg) {
684                         firstArg = false;
685                     }
686                     else {
687                         Output.Write(", ");
688                     }
689
690                     OutputAttributeArgument(arg);
691                 }
692
693                 Output.Write(")");
694
695             }
696             GenerateAttributeDeclarationsEnd(attributes);
697             Output.Write(" ");            
698             if (!inLine) {
699                 if (closingLine) {
700                     Output.WriteLine();
701                 }
702                 else {
703                     ContinueOnNewLine("");
704                 }
705             }
706         }
707
708         protected override void OutputDirection(FieldDirection dir) {
709             switch (dir) {
710                 case FieldDirection.In:
711                     Output.Write("ByVal ");
712                     break;
713                 case FieldDirection.Out:
714                 case FieldDirection.Ref:
715                     Output.Write("ByRef ");
716                     break;
717             }
718         }
719
720         protected override void GenerateDefaultValueExpression(CodeDefaultValueExpression e) {
721             Output.Write("CType(Nothing, " + GetTypeOutput(e.Type) + ")");
722         }
723         
724         protected override void GenerateDirectionExpression(CodeDirectionExpression e) {
725             // Visual Basic does not need to adorn the calling point with a direction, so just output the expression.
726             GenerateExpression(e.Expression);
727         }
728
729         
730         protected override void OutputFieldScopeModifier(MemberAttributes attributes) {
731             switch (attributes & MemberAttributes.ScopeMask) {
732                 case MemberAttributes.Final:
733                     Output.Write("");
734                     break;
735                 case MemberAttributes.Static:
736                     // ignore Static for fields in a Module since all fields in a module are already
737                     //  static and it is a syntax error to explicitly mark them as static
738                     //
739                     if (!IsCurrentModule) {
740                         Output.Write("Shared ");
741                     }
742                     break;
743                 case MemberAttributes.Const:
744                     Output.Write("Const ");
745                     break;
746                 default:
747                     Output.Write("");
748                     break;
749             }
750         }
751
752         /// <devdoc>
753         ///    <para>
754         ///       Generates code for the specified CodeDom based member
755         ///       access modifier representation.
756         ///    </para>
757         /// </devdoc>
758         protected override void OutputMemberAccessModifier(MemberAttributes attributes) {
759             switch (attributes & MemberAttributes.AccessMask) {
760                 case MemberAttributes.Assembly:
761                     Output.Write("Friend ");
762                     break;
763                 case MemberAttributes.FamilyAndAssembly:
764                     Output.Write("Friend ");
765                     break;
766                 case MemberAttributes.Family:
767                     Output.Write("Protected ");
768                     break;
769                 case MemberAttributes.FamilyOrAssembly:
770                     Output.Write("Protected Friend ");
771                     break;
772                 case MemberAttributes.Private:
773                     Output.Write("Private ");
774                     break;
775                 case MemberAttributes.Public:
776                     Output.Write("Public ");
777                     break;
778             }
779         }
780
781         private void OutputVTableModifier(MemberAttributes attributes) {
782             switch (attributes & MemberAttributes.VTableMask) {
783                 case MemberAttributes.New:
784                     Output.Write("Shadows ");
785                     break;
786             }
787         }
788
789         /// <devdoc>
790         ///    <para>
791         ///       Generates code for the specified CodeDom based member scope modifier
792         ///       representation.
793         ///    </para>
794         /// </devdoc>
795         protected override void OutputMemberScopeModifier(MemberAttributes attributes) {
796
797             switch (attributes & MemberAttributes.ScopeMask) {
798                 case MemberAttributes.Abstract:
799                     Output.Write("MustOverride ");
800                     break;
801                 case MemberAttributes.Final:
802                     Output.Write("");
803                     break;
804                 case MemberAttributes.Static:
805                     // ignore Static for members in a Module since all members in a module are already
806                     //  static and it is a syntax error to explicitly mark them as static
807                     //
808                     if (!IsCurrentModule) {
809                         Output.Write("Shared ");
810                     }
811                     break;
812                 case MemberAttributes.Override:
813                     Output.Write("Overrides ");
814                     break;
815                 case MemberAttributes.Private:
816                     Output.Write("Private ");
817                     break;
818                 default:
819                     switch (attributes & MemberAttributes.AccessMask) {
820                         case MemberAttributes.Family:
821                         case MemberAttributes.Public:
822                         case MemberAttributes.Assembly:                            
823                             Output.Write("Overridable ");
824                             break;
825                         default:
826                             // nothing;
827                             break;
828                     }
829                     break;
830             }
831         }
832
833         /// <devdoc>
834         ///    <para>
835         ///       Generates code for the specified CodeDom based operator
836         ///       representation.
837         ///    </para>
838         /// </devdoc>
839         protected override void OutputOperator(CodeBinaryOperatorType op) {
840             switch (op) {
841                 case CodeBinaryOperatorType.IdentityInequality:
842                     Output.Write("<>");
843                     break;
844                 case CodeBinaryOperatorType.IdentityEquality:
845                     Output.Write("Is");
846                     break;
847                 case CodeBinaryOperatorType.BooleanOr:
848                     Output.Write("OrElse");
849                     break;
850                 case CodeBinaryOperatorType.BooleanAnd:
851                     Output.Write("AndAlso");
852                     break;
853                 case CodeBinaryOperatorType.ValueEquality:
854                     Output.Write("=");
855                     break;
856                 case CodeBinaryOperatorType.Modulus:
857                     Output.Write("Mod");
858                     break;
859                 case CodeBinaryOperatorType.BitwiseOr:
860                     Output.Write("Or");
861                     break;
862                 case CodeBinaryOperatorType.BitwiseAnd:
863                     Output.Write("And");
864                     break;
865                 default:
866                     base.OutputOperator(op);
867                 break;
868             }
869         }
870
871         private void GenerateNotIsNullExpression(CodeExpression e) {
872             Output.Write("(Not (");
873             GenerateExpression(e);
874             Output.Write(") Is ");
875             Output.Write(NullToken);
876             Output.Write(")");
877         }
878
879         protected override void GenerateBinaryOperatorExpression(CodeBinaryOperatorExpression e) {
880             if (e.Operator != CodeBinaryOperatorType.IdentityInequality) {
881                 base.GenerateBinaryOperatorExpression(e);
882                 return;
883             }
884
885             // "o <> nothing" should be "not o is nothing"
886             if (e.Right is CodePrimitiveExpression && ((CodePrimitiveExpression)e.Right).Value == null){
887                 GenerateNotIsNullExpression(e.Left);
888                 return;    
889             }
890             if (e.Left is CodePrimitiveExpression && ((CodePrimitiveExpression)e.Left).Value == null){
891                 GenerateNotIsNullExpression(e.Right);
892                 return;
893             }
894
895             base.GenerateBinaryOperatorExpression(e);
896         }
897
898         /// <devdoc>
899         ///    <para>[To be supplied.]</para>
900         /// </devdoc>
901         protected override string GetResponseFileCmdArgs(CompilerParameters options, string cmdArgs) {
902
903             // Always specify the /noconfig flag (outside of the response file) 
904             return "/noconfig " + base.GetResponseFileCmdArgs(options, cmdArgs);
905         }
906
907         protected override void OutputIdentifier(string ident) {
908             Output.Write(CreateEscapedIdentifier(ident));
909         }
910
911         /// <devdoc>
912         ///    <para>
913         ///       Generates code for the specified CodeDom based return type
914         ///       representation.
915         ///    </para>
916         /// </devdoc>
917         protected override void OutputType(CodeTypeReference typeRef) {
918             Output.Write(GetTypeOutputWithoutArrayPostFix(typeRef));
919         }
920
921         private void OutputTypeAttributes(CodeTypeDeclaration e) {
922             if((e.Attributes & MemberAttributes.New) != 0) {
923                 Output.Write("Shadows ");
924             }
925             
926             TypeAttributes attributes = e.TypeAttributes;
927
928             if (e.IsPartial) {            
929                Output.Write("Partial ");
930             }
931
932             switch(attributes & TypeAttributes.VisibilityMask) {
933                 case TypeAttributes.Public:                  
934                 case TypeAttributes.NestedPublic:
935                     Output.Write("Public ");
936                     break;
937                 case TypeAttributes.NestedPrivate:
938                     Output.Write("Private ");
939                     break;
940
941                 case TypeAttributes.NestedFamily:
942                     Output.Write("Protected ");
943                     break;
944                 case TypeAttributes.NotPublic:
945                 case TypeAttributes.NestedAssembly:
946                 case TypeAttributes.NestedFamANDAssem:
947                     Output.Write("Friend ");
948                     break;
949                 case TypeAttributes.NestedFamORAssem:
950                     Output.Write("Protected Friend ");
951                     break;
952             }
953             
954             if (e.IsStruct) {
955                 Output.Write("Structure ");
956             }
957             else if (e.IsEnum) {
958                 Output.Write("Enum ");
959             }     
960             else {            
961
962                 switch (attributes & TypeAttributes.ClassSemanticsMask) {
963                     case TypeAttributes.Class:
964                         // if this "class" should generate as a module, then don't check
965                         //  inheritance flags since modules can't inherit
966                         if (IsCurrentModule) {
967                             Output.Write("Module ");
968                         }
969                         else {
970                             if ((attributes & TypeAttributes.Sealed) == TypeAttributes.Sealed) {
971                                 Output.Write("NotInheritable ");
972                             }
973                             if ((attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract)  {
974                                 Output.Write("MustInherit ");
975                             }
976                             Output.Write("Class ");
977                         }
978                         break;                
979                     case TypeAttributes.Interface:
980                         Output.Write("Interface ");
981                         break;
982                 }
983             }
984             
985         }
986
987         /// <devdoc>
988         ///    <para>
989         ///       Generates code for the specified CodeDom based type name pair
990         ///       representation.
991         ///    </para>
992         /// </devdoc>
993         protected override void OutputTypeNamePair(CodeTypeReference typeRef, string name) {
994             if (string.IsNullOrEmpty(name)) 
995                 name = "__exception";
996                 
997             OutputIdentifier(name);
998             OutputArrayPostfix(typeRef);
999             Output.Write(" As ");
1000             OutputType(typeRef);
1001         }
1002
1003         private string GetArrayPostfix(CodeTypeReference typeRef) {
1004             string s = "";
1005             if (typeRef.ArrayElementType != null) {
1006                 // Recurse up
1007                 s = GetArrayPostfix(typeRef.ArrayElementType);
1008             }
1009
1010             if (typeRef.ArrayRank > 0) {            
1011                 char [] results = new char [typeRef.ArrayRank + 1];
1012                 results[0] = '(';
1013                 results[typeRef.ArrayRank] = ')';
1014                 for (int i = 1; i < typeRef.ArrayRank; i++) {
1015                     results[i] = ',';
1016                 }
1017                 s = new string(results) + s;
1018             }
1019
1020             return s;
1021
1022         }
1023
1024         private void OutputArrayPostfix(CodeTypeReference typeRef) {
1025             if (typeRef.ArrayRank > 0) {                        
1026                 Output.Write(GetArrayPostfix(typeRef));
1027             }
1028         }
1029
1030         /// <devdoc>
1031         ///    <para>
1032         ///       Generates code for the specified CodeDom based for loop statement
1033         ///       representation.
1034         ///    </para>
1035         /// </devdoc>
1036         protected override void GenerateIterationStatement(CodeIterationStatement e) {
1037             GenerateStatement(e.InitStatement);
1038             Output.Write("Do While ");
1039             GenerateExpression(e.TestExpression);
1040             Output.WriteLine("");
1041             Indent++;
1042             GenerateVBStatements(e.Statements);
1043             GenerateStatement(e.IncrementStatement);
1044             Indent--;
1045             Output.WriteLine("Loop");
1046         }
1047         
1048         /// <devdoc>
1049         ///    <para>
1050         ///       Generates code for the specified CodeDom based primitive expression
1051         ///       representation.
1052         ///    </para>
1053         /// </devdoc>
1054         protected override void GeneratePrimitiveExpression(CodePrimitiveExpression e) {
1055             if (e.Value is char) {
1056                 Output.Write("Global.Microsoft.VisualBasic.ChrW(" + ((IConvertible)e.Value).ToInt32(CultureInfo.InvariantCulture).ToString(CultureInfo.InvariantCulture) + ")");
1057             }
1058             else if (e.Value is SByte) {
1059                 Output.Write("CSByte(");
1060                 Output.Write(((SByte)e.Value).ToString(CultureInfo.InvariantCulture));
1061                 Output.Write(")");
1062             }
1063             else if (e.Value is UInt16) {
1064                 Output.Write(((UInt16)e.Value).ToString(CultureInfo.InvariantCulture));
1065                 Output.Write("US");
1066             }
1067             else if (e.Value is UInt32) {
1068                 Output.Write(((UInt32)e.Value).ToString(CultureInfo.InvariantCulture));
1069                 Output.Write("UI");
1070             }
1071             else if (e.Value is UInt64) {
1072                 Output.Write(((UInt64)e.Value).ToString(CultureInfo.InvariantCulture));
1073                 Output.Write("UL");
1074             }            
1075             else {
1076                 base.GeneratePrimitiveExpression(e);
1077             }
1078         }
1079
1080         /// <devdoc>
1081         ///    <para>
1082         ///       Generates code for the specified CodeDom based throw exception statement
1083         ///       representation.
1084         ///    </para>
1085         /// </devdoc>
1086         protected override void GenerateThrowExceptionStatement(CodeThrowExceptionStatement e) {
1087             Output.Write("Throw");
1088             if (e.ToThrow != null) {
1089                 Output.Write(" ");
1090                 GenerateExpression(e.ToThrow);
1091             }
1092             Output.WriteLine("");
1093         }
1094
1095
1096         /// <devdoc>
1097         ///    <para>
1098         ///       Generates code for the specified CodeDom based array creation expression
1099         ///       representation.
1100         ///    </para>
1101         /// </devdoc>
1102         protected override void GenerateArrayCreateExpression(CodeArrayCreateExpression e) {
1103             Output.Write("New ");
1104
1105             CodeExpressionCollection init = e.Initializers;
1106             if (init.Count > 0) {
1107                 String typeName = GetTypeOutput(e.CreateType);
1108                 Output.Write(typeName);
1109                 
1110                 // 
1111
1112                 if( typeName.IndexOf('(') == -1) { 
1113                     Output.Write("()");
1114                 }
1115
1116                 Output.Write(" {");
1117                 Indent++;
1118                 OutputExpressionList(init);
1119                 Indent--;
1120                 Output.Write("}");
1121             }
1122             else {
1123                 String typeName = GetTypeOutput(e.CreateType);
1124                 
1125                 int index = typeName.IndexOf('(');
1126                 if( index == -1) {
1127                     // 
1128
1129                     Output.Write(typeName);
1130                     Output.Write('(');
1131                 }
1132                 else {
1133                     Output.Write(typeName.Substring(0, index+1));
1134                 }
1135
1136                 // The tricky thing is we need to declare the size - 1
1137                 if (e.SizeExpression != null) {
1138                     Output.Write("(");
1139                     GenerateExpression(e.SizeExpression);
1140                     Output.Write(") - 1");
1141                 }
1142                 else {
1143                     Output.Write(e.Size - 1);
1144                 }
1145
1146                 if( index == -1) {
1147                     Output.Write(')');
1148                 }
1149                 else {
1150                     Output.Write(typeName.Substring(index+1));
1151                 }
1152
1153                 Output.Write(" {}");
1154             }
1155         }
1156
1157         /// <devdoc>
1158         ///    <para>
1159         ///       Generates code for the specified CodeDom based base reference expression
1160         ///       representation.
1161         ///    </para>
1162         /// </devdoc>
1163         protected override void GenerateBaseReferenceExpression(CodeBaseReferenceExpression e) {
1164             Output.Write("MyBase");
1165         }
1166
1167         /// <devdoc>
1168         ///    <para>
1169         ///       Generates code for the specified CodeDom based cast expression representation.
1170         ///    </para>
1171         /// </devdoc>
1172         protected override void GenerateCastExpression(CodeCastExpression e) {
1173             Output.Write("CType(");
1174             GenerateExpression(e.Expression);
1175             Output.Write(",");
1176             OutputType(e.TargetType);
1177             OutputArrayPostfix(e.TargetType);
1178             Output.Write(")");
1179         }
1180
1181         /// <devdoc>
1182         ///    <para>
1183         ///       Generates code for the specified CodeDom based delegate creation expression
1184         ///       representation.
1185         ///    </para>
1186         /// </devdoc>
1187         protected override void GenerateDelegateCreateExpression(CodeDelegateCreateExpression e) {
1188             Output.Write("AddressOf ");
1189             GenerateExpression(e.TargetObject);
1190             Output.Write(".");
1191             OutputIdentifier(e.MethodName);
1192         }
1193
1194         /// <devdoc>
1195         ///    <para>
1196         ///       Generates code for the specified CodeDom based field reference expression
1197         ///       representation.
1198         ///    </para>
1199         /// </devdoc>
1200         protected override void GenerateFieldReferenceExpression(CodeFieldReferenceExpression e) {
1201
1202             if (e.TargetObject != null) {
1203                 GenerateExpression(e.TargetObject);
1204                 Output.Write(".");
1205             }
1206             
1207             OutputIdentifier(e.FieldName);
1208         }
1209
1210         protected override void GenerateSingleFloatValue(Single s) {
1211             if( float.IsNaN(s)) {
1212                 Output.Write("Single.NaN");
1213             }
1214             else if( float.IsNegativeInfinity(s)) {
1215                 Output.Write("Single.NegativeInfinity");                
1216             }
1217             else if( float.IsPositiveInfinity(s)) {
1218                 Output.Write("Single.PositiveInfinity");                
1219             }
1220             else {
1221                 Output.Write(s.ToString(CultureInfo.InvariantCulture));
1222                 Output.Write('!');
1223             }
1224         }
1225
1226         protected override void GenerateDoubleValue(double d) {
1227             if( double.IsNaN(d)) {
1228                 Output.Write("Double.NaN");
1229             }
1230             else if( double.IsNegativeInfinity(d)) {
1231                 Output.Write("Double.NegativeInfinity");                
1232             }
1233             else if( double.IsPositiveInfinity(d)) {
1234                 Output.Write("Double.PositiveInfinity");                
1235             }
1236             else {
1237                 Output.Write(d.ToString("R", CultureInfo.InvariantCulture));
1238                 // always mark a double as being a double in case we have no decimal portion (e.g write 1D instead of 1 which is an int)
1239                 Output.Write("R");
1240             }
1241         }
1242
1243         protected override void GenerateDecimalValue(Decimal d) {
1244             Output.Write(d.ToString(CultureInfo.InvariantCulture));
1245             Output.Write('D');
1246         }
1247
1248         protected override void GenerateArgumentReferenceExpression(CodeArgumentReferenceExpression e) {
1249             OutputIdentifier(e.ParameterName);
1250         }
1251
1252         protected override void GenerateVariableReferenceExpression(CodeVariableReferenceExpression e) {
1253             OutputIdentifier(e.VariableName);
1254         }
1255
1256         /// <devdoc>
1257         ///    <para>
1258         ///       Generates code for the specified CodeDom based indexer expression
1259         ///       representation.
1260         ///    </para>
1261         /// </devdoc>
1262         protected override void GenerateIndexerExpression(CodeIndexerExpression e) {
1263             GenerateExpression(e.TargetObject);
1264             // If this IndexerExpression is referencing to base, we need to emit
1265             // .Item after MyBase. Otherwise the code won't compile.
1266             if( e.TargetObject is CodeBaseReferenceExpression) {
1267                 Output.Write(".Item");
1268             }
1269
1270             Output.Write("(");
1271             bool first = true;
1272             foreach(CodeExpression exp in e.Indices) {            
1273                 if (first) {
1274                     first = false;
1275                 }
1276                 else {
1277                     Output.Write(", ");
1278                 }
1279                 GenerateExpression(exp);
1280             }
1281             Output.Write(")");
1282
1283         }
1284
1285         protected override void GenerateArrayIndexerExpression(CodeArrayIndexerExpression e) {
1286             GenerateExpression(e.TargetObject);
1287             Output.Write("(");
1288             bool first = true;
1289             foreach(CodeExpression exp in e.Indices) {            
1290                 if (first) {
1291                     first = false;
1292                 }
1293                 else {
1294                     Output.Write(", ");
1295                 }
1296                 GenerateExpression(exp);
1297             }
1298             Output.Write(")");
1299
1300         }
1301
1302         /// <devdoc>
1303         ///    <para>
1304         ///       Generates code for the specified CodeDom based code snippet expression
1305         ///       representation.
1306         ///    </para>
1307         /// </devdoc>
1308         protected override void GenerateSnippetExpression(CodeSnippetExpression e) {
1309             Output.Write(e.Value);
1310         }
1311         /// <devdoc>
1312         ///    <para>
1313         ///       Generates code for the specified CodeDom based method invoke
1314         ///       expression.
1315         ///    </para>
1316         /// </devdoc>
1317         protected override void GenerateMethodInvokeExpression(CodeMethodInvokeExpression e) {
1318             GenerateMethodReferenceExpression(e.Method);
1319             CodeExpressionCollection parameters = e.Parameters;
1320             if (parameters.Count > 0) {
1321                 Output.Write("(");
1322                 OutputExpressionList(e.Parameters);
1323                 Output.Write(")");
1324             }
1325         }
1326
1327         protected override void GenerateMethodReferenceExpression(CodeMethodReferenceExpression e) {
1328             if (e.TargetObject != null) {
1329                 GenerateExpression(e.TargetObject);
1330                 Output.Write(".");
1331                 Output.Write(e.MethodName);
1332             }
1333             else {
1334                 OutputIdentifier(e.MethodName);
1335             }
1336
1337             if( e.TypeArguments.Count > 0) {
1338                 Output.Write(GetTypeArgumentsOutput(e.TypeArguments));
1339             }            
1340         }
1341
1342         protected override void GenerateEventReferenceExpression(CodeEventReferenceExpression e) {
1343             if (e.TargetObject != null) {
1344                 bool localReference = (e.TargetObject is CodeThisReferenceExpression);
1345                 GenerateExpression(e.TargetObject);
1346                 Output.Write(".");
1347                 if (localReference) {
1348                     Output.Write(e.EventName + "Event");
1349                 }
1350                 else {
1351                     Output.Write(e.EventName);
1352                 }
1353             }
1354             else {
1355                 OutputIdentifier(e.EventName + "Event");
1356             }
1357         }
1358
1359         private void GenerateFormalEventReferenceExpression(CodeEventReferenceExpression e) {
1360             if (e.TargetObject != null) {
1361                 // Visual Basic Compiler does not like the me reference like this.
1362                 if (!(e.TargetObject is CodeThisReferenceExpression)) {
1363                     GenerateExpression(e.TargetObject);
1364                     Output.Write(".");
1365                 }
1366             }
1367             OutputIdentifier(e.EventName);
1368         }
1369
1370
1371         /// <devdoc>
1372         ///    <para>
1373         ///       Generates code for the specified CodeDom based delegate invoke
1374         ///       expression.
1375         ///    </para>
1376         /// </devdoc>
1377         protected override void GenerateDelegateInvokeExpression(CodeDelegateInvokeExpression e) {
1378             if (e.TargetObject != null) {
1379                 if (e.TargetObject is CodeEventReferenceExpression) {
1380                     Output.Write("RaiseEvent ");
1381                     GenerateFormalEventReferenceExpression((CodeEventReferenceExpression)e.TargetObject);
1382                 }
1383                 else {
1384                     GenerateExpression(e.TargetObject);
1385                 }
1386             }
1387
1388             CodeExpressionCollection parameters = e.Parameters;
1389             if (parameters.Count > 0) {
1390                 Output.Write("(");
1391                 OutputExpressionList(e.Parameters);
1392                 Output.Write(")");
1393             }
1394         }
1395
1396         /// <devdoc>
1397         ///    <para>
1398         ///       Generates code for the specified CodeDom based object creation
1399         ///       expression.
1400         ///    </para>
1401         /// </devdoc>
1402         protected override void GenerateObjectCreateExpression(CodeObjectCreateExpression e) {
1403             Output.Write("New ");
1404             OutputType(e.CreateType);
1405             // always write out the () to disambiguate cases like "New System.Random().Next(x,y)"
1406             Output.Write("(");
1407             OutputExpressionList(e.Parameters);
1408             Output.Write(")");
1409         }
1410
1411         /// <devdoc>
1412         ///    <para>
1413         ///       Generates code for the specified CodeDom
1414         ///       based parameter declaration expression representation.
1415         ///    </para>
1416         /// </devdoc>
1417         protected override void GenerateParameterDeclarationExpression(CodeParameterDeclarationExpression e) {
1418             if (e.CustomAttributes.Count > 0) {
1419                 OutputAttributes(e.CustomAttributes, true);
1420             }
1421             OutputDirection(e.Direction);
1422             OutputTypeNamePair(e.Type, e.Name);
1423         }
1424
1425         protected override void GeneratePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e) {
1426             Output.Write("value");
1427         }
1428
1429         /// <devdoc>
1430         ///    <para>
1431         ///       Generates code for the specified CodeDom based this reference expression
1432         ///       representation.
1433         ///    </para>
1434         /// </devdoc>
1435         protected override void GenerateThisReferenceExpression(CodeThisReferenceExpression e) {
1436             Output.Write("Me");
1437         }
1438
1439         /// <devdoc>
1440         ///    <para>
1441         ///       Generates code for the specified CodeDom based method invoke statement
1442         ///       representation.
1443         ///    </para>
1444         /// </devdoc>
1445         protected override void GenerateExpressionStatement(CodeExpressionStatement e) {
1446             GenerateExpression(e.Expression);
1447             Output.WriteLine("");
1448         }
1449
1450         /// <devdoc>
1451         ///    <para>
1452         ///       Tells whether or not the given comment is a DocComment
1453         ///    </para>
1454         /// </devdoc>
1455         private bool IsDocComment(CodeCommentStatement comment) {
1456         
1457             return ((comment != null) && (comment.Comment != null) && comment.Comment.DocComment);
1458         }
1459         
1460         /// <include file='doc\VBCodeProvider.uex' path='docs/doc[@for="VBCodeGenerator.GenerateCommentStatements"]/*' />
1461         /// <devdoc>
1462         ///    <para>Overridden in order to output XML DocComments in the correct order for VB</para>
1463         /// </devdoc>
1464         protected override void GenerateCommentStatements(CodeCommentStatementCollection e) {
1465
1466             // since the compiler emits a warning if XML DocComment blocks appear before
1467             //  normal comments, we need to output non-DocComments first, followed by
1468             //  DocComments.
1469             //            
1470             foreach (CodeCommentStatement comment in e) {
1471                 if (!IsDocComment(comment)) {
1472                     GenerateCommentStatement(comment);
1473                 }
1474             }
1475
1476             foreach (CodeCommentStatement comment in e) {
1477                 if (IsDocComment(comment)) {
1478                     GenerateCommentStatement(comment);
1479                 }
1480             }
1481         }
1482         
1483         protected override void GenerateComment(CodeComment e) {
1484             String commentLineStart = e.DocComment? "'''": "'";            
1485             Output.Write(commentLineStart);                
1486             string value = e.Text;
1487             for (int i=0; i<value.Length; i++) {
1488                 Output.Write(value[i]);
1489
1490                 if( value[i] == '\r') {
1491                     if (i < value.Length - 1 && value[i+1] == '\n') { // if next char is '\n', skip it
1492                         Output.Write('\n');
1493                         i++;
1494                     }
1495                     ((IndentedTextWriter) Output).InternalOutputTabs();
1496                     Output.Write(commentLineStart);
1497                 }
1498                 else if( value[i] == '\n') {
1499                     ((IndentedTextWriter) Output).InternalOutputTabs();
1500                     Output.Write(commentLineStart);
1501                 }
1502                 else if( value[i] == '\u2028' || value[i] == '\u2029' || value[i] == '\u0085') {
1503                     Output.Write(commentLineStart);
1504                 }
1505             }
1506             Output.WriteLine();
1507         }
1508
1509         /// <devdoc>
1510         ///    <para>
1511         ///       Generates code for the specified CodeDom based method return statement
1512         ///       representation.
1513         ///    </para>
1514         /// </devdoc>
1515         protected override void GenerateMethodReturnStatement(CodeMethodReturnStatement e) {
1516             if (e.Expression != null) {
1517                 Output.Write("Return ");
1518                 GenerateExpression(e.Expression);
1519                 Output.WriteLine("");
1520             }
1521             else {
1522                 Output.WriteLine("Return");
1523             }
1524         }
1525
1526         /// <devdoc>
1527         ///    <para>
1528         ///       Generates code for the specified CodeDom based if statement representation.
1529         ///    </para>
1530         /// </devdoc>
1531         protected override void GenerateConditionStatement(CodeConditionStatement e) {
1532             Output.Write("If ");
1533             GenerateExpression(e.Condition);
1534             Output.WriteLine(" Then");
1535             Indent++;
1536             GenerateVBStatements(e.TrueStatements);
1537             Indent--;
1538
1539             CodeStatementCollection falseStatemetns = e.FalseStatements;
1540             if (falseStatemetns.Count > 0) {
1541                 Output.Write("Else");
1542                 Output.WriteLine("");
1543                 Indent++;
1544                 GenerateVBStatements(e.FalseStatements);
1545                 Indent--;
1546             }
1547             Output.WriteLine("End If");
1548         }
1549
1550         /// <devdoc>
1551         ///    <para>
1552         ///       Generates code for the specified CodeDom based try catch finally statement
1553         ///       representation.
1554         ///    </para>
1555         /// </devdoc>
1556         protected override void GenerateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e) {
1557             Output.WriteLine("Try ");
1558             Indent++;
1559             GenerateVBStatements(e.TryStatements);
1560             Indent--;
1561             CodeCatchClauseCollection catches = e.CatchClauses;
1562             if (catches.Count > 0) {
1563                 IEnumerator en = catches.GetEnumerator();
1564                 while (en.MoveNext()) {
1565                     CodeCatchClause current = (CodeCatchClause)en.Current;
1566                     Output.Write("Catch ");
1567                     OutputTypeNamePair(current.CatchExceptionType, current.LocalName);
1568                     Output.WriteLine("");
1569                     Indent++;
1570                     GenerateVBStatements(current.Statements);
1571                     Indent--;
1572                 }
1573             }
1574
1575             CodeStatementCollection finallyStatements = e.FinallyStatements;
1576             if (finallyStatements.Count > 0) {
1577                 Output.WriteLine("Finally");
1578                 Indent++;
1579                 GenerateVBStatements(finallyStatements);
1580                 Indent--;
1581             }
1582             Output.WriteLine("End Try");
1583         }
1584
1585         /// <devdoc>
1586         ///    <para>
1587         ///       Generates code for the specified CodeDom based assignment statement
1588         ///       representation.
1589         ///    </para>
1590         /// </devdoc>
1591         protected override void GenerateAssignStatement(CodeAssignStatement e) {
1592             GenerateExpression(e.Left);
1593             Output.Write(" = ");
1594             GenerateExpression(e.Right);
1595             Output.WriteLine("");
1596         }
1597
1598         protected override void GenerateAttachEventStatement(CodeAttachEventStatement e) {
1599             Output.Write("AddHandler ");
1600             GenerateFormalEventReferenceExpression(e.Event);
1601             Output.Write(", ");
1602             GenerateExpression(e.Listener);
1603             Output.WriteLine("");
1604         }
1605
1606         protected override void GenerateRemoveEventStatement(CodeRemoveEventStatement e) {
1607             Output.Write("RemoveHandler ");
1608             GenerateFormalEventReferenceExpression(e.Event);
1609             Output.Write(", ");
1610             GenerateExpression(e.Listener);
1611             Output.WriteLine("");
1612         }
1613
1614         protected override void GenerateSnippetStatement(CodeSnippetStatement e) {
1615             Output.WriteLine(e.Value);
1616         }
1617
1618         protected override void GenerateGotoStatement(CodeGotoStatement e) {
1619             Output.Write("goto ");
1620             Output.WriteLine(e.Label);
1621         }
1622
1623         protected override void GenerateLabeledStatement(CodeLabeledStatement e) {
1624             Indent--;
1625             Output.Write(e.Label);
1626             Output.WriteLine(":");
1627             Indent++;
1628             if (e.Statement != null) {
1629                 GenerateStatement(e.Statement);
1630             }
1631         }
1632
1633         /// <devdoc>
1634         ///    <para>
1635         ///       Generates code for the specified CodeDom variable declaration statement
1636         ///       representation.
1637         ///    </para>
1638         /// </devdoc>
1639         protected override void GenerateVariableDeclarationStatement(CodeVariableDeclarationStatement e) {
1640             bool doInit = true;
1641             
1642             Output.Write("Dim ");
1643
1644             CodeTypeReference typeRef = e.Type;
1645             if (typeRef.ArrayRank == 1 && e.InitExpression != null) {
1646                 CodeArrayCreateExpression eAsArrayCreate = e.InitExpression as CodeArrayCreateExpression;
1647                 if (eAsArrayCreate != null && eAsArrayCreate.Initializers.Count == 0) {
1648                     doInit = false;
1649                     OutputIdentifier(e.Name);
1650                     Output.Write("(");
1651
1652                     if (eAsArrayCreate.SizeExpression != null) {
1653                         Output.Write("(");
1654                         GenerateExpression(eAsArrayCreate.SizeExpression);
1655                         Output.Write(") - 1");
1656                     }
1657                     else {
1658                         Output.Write(eAsArrayCreate.Size - 1);
1659                     }
1660
1661                     Output.Write(")");
1662
1663                     if (typeRef.ArrayElementType != null)
1664                         OutputArrayPostfix(typeRef.ArrayElementType); 
1665                         
1666                     Output.Write(" As ");
1667                     OutputType(typeRef);
1668                 }
1669                 else
1670                     OutputTypeNamePair(e.Type, e.Name);
1671             }
1672             else
1673                 OutputTypeNamePair(e.Type, e.Name);
1674                 
1675             if (doInit && e.InitExpression != null) {
1676                 Output.Write(" = ");
1677                 GenerateExpression(e.InitExpression);
1678             }   
1679                 
1680             Output.WriteLine("");
1681         }
1682         /// <devdoc>
1683         ///    <para>
1684         ///       Generates code for the specified CodeDom based line pragma start
1685         ///       representation.
1686         ///    </para>
1687         /// </devdoc>
1688         protected override void GenerateLinePragmaStart(CodeLinePragma e) {
1689             Output.WriteLine("");
1690             Output.Write("#ExternalSource(\"");
1691             Output.Write(e.FileName);
1692             Output.Write("\",");
1693             Output.Write(e.LineNumber);
1694             Output.WriteLine(")");
1695         }
1696         /// <devdoc>
1697         ///    <para>
1698         ///       Generates code for the specified CodeDom based line pragma end
1699         ///       representation.
1700         ///    </para>
1701         /// </devdoc>
1702         protected override void GenerateLinePragmaEnd(CodeLinePragma e) {
1703             Output.WriteLine("");
1704             Output.WriteLine("#End ExternalSource");
1705         }
1706
1707
1708         protected override void GenerateEvent(CodeMemberEvent e, CodeTypeDeclaration c) {
1709             if (IsCurrentDelegate || IsCurrentEnum) return;
1710
1711             if (e.CustomAttributes.Count > 0) {
1712                 OutputAttributes(e.CustomAttributes, false);
1713             }
1714             
1715             string eventName = e.Name;
1716             if (e.PrivateImplementationType != null)
1717             {
1718                 string impl = GetBaseTypeOutput(e.PrivateImplementationType);
1719                 impl = impl.Replace('.', '_');
1720                 e.Name = impl + "_" + e.Name;
1721             }
1722
1723             OutputMemberAccessModifier(e.Attributes);
1724             Output.Write("Event ");
1725             OutputTypeNamePair(e.Type, e.Name);
1726
1727             if (e.ImplementationTypes.Count > 0) {
1728                 Output.Write(" Implements ");
1729                 bool first = true;
1730                 foreach (CodeTypeReference type in e.ImplementationTypes) {
1731                     if (first) {
1732                         first = false;
1733                     }   
1734                     else {
1735                         Output.Write(" , ");
1736                     }
1737                     OutputType(type);
1738                     Output.Write(".");
1739                     OutputIdentifier(eventName);
1740                 }
1741             }
1742             else if (e.PrivateImplementationType != null) {
1743                 Output.Write(" Implements ");
1744                 OutputType(e.PrivateImplementationType);
1745                 Output.Write(".");
1746                 OutputIdentifier(eventName);
1747             }
1748
1749             Output.WriteLine("");
1750         }
1751
1752         /// <devdoc>
1753         ///    <para>
1754         ///       Generates code for the specified CodeDom based member
1755         ///       field representation.
1756         ///    </para>
1757         /// </devdoc>
1758         protected override void GenerateField(CodeMemberField e) {
1759             if (IsCurrentDelegate || IsCurrentInterface) return;
1760
1761             if (IsCurrentEnum) {
1762                 if (e.CustomAttributes.Count > 0) {
1763                     OutputAttributes(e.CustomAttributes, false);
1764                 }
1765
1766                 OutputIdentifier(e.Name);
1767                 if (e.InitExpression != null) {
1768                     Output.Write(" = ");
1769                     GenerateExpression(e.InitExpression);
1770                 }
1771                 Output.WriteLine("");
1772             }
1773             else {
1774                 if (e.CustomAttributes.Count > 0) {
1775                     OutputAttributes(e.CustomAttributes, false);
1776                 }
1777
1778                 OutputMemberAccessModifier(e.Attributes);
1779                 OutputVTableModifier(e.Attributes);
1780                 OutputFieldScopeModifier(e.Attributes);
1781
1782                 if (GetUserData(e, "WithEvents", false)) {
1783                     Output.Write("WithEvents ");
1784                 }
1785
1786                 OutputTypeNamePair(e.Type, e.Name);
1787                 if (e.InitExpression != null) {
1788                     Output.Write(" = ");
1789                     GenerateExpression(e.InitExpression);
1790                 }
1791                 Output.WriteLine("");
1792             }
1793         }
1794
1795         private bool MethodIsOverloaded(CodeMemberMethod e, CodeTypeDeclaration c) {
1796             if ((e.Attributes & MemberAttributes.Overloaded) != 0) {
1797                 return true;
1798             }
1799             IEnumerator en = c.Members.GetEnumerator();
1800             while (en.MoveNext()) {
1801                 if (!(en.Current is CodeMemberMethod))
1802                     continue;
1803                 CodeMemberMethod meth = (CodeMemberMethod) en.Current;
1804
1805                 if (!(en.Current is CodeTypeConstructor)
1806                     && !(en.Current is CodeConstructor)
1807                     && meth != e
1808                     && meth.Name.Equals(e.Name, StringComparison.OrdinalIgnoreCase)
1809                     && meth.PrivateImplementationType == null)
1810                 {
1811                     return true;
1812                 }
1813             }
1814
1815             return false;
1816         }
1817
1818         /// <devdoc>
1819         ///    <para>
1820         ///       Generates code for
1821         ///       the specified CodeDom based snippet member representation.
1822         ///    </para>
1823         /// </devdoc>
1824         protected override void GenerateSnippetMember(CodeSnippetTypeMember e) {
1825             Output.Write(e.Text);
1826         }
1827
1828         protected override void GenerateMethod(CodeMemberMethod e, CodeTypeDeclaration c) {
1829             if (!(IsCurrentClass || IsCurrentStruct || IsCurrentInterface)) return;
1830
1831             if (e.CustomAttributes.Count > 0) {
1832                 OutputAttributes(e.CustomAttributes, false);
1833             }
1834
1835             // need to change the implements name before doing overloads resolution
1836             //
1837             string methodName = e.Name;
1838             if (e.PrivateImplementationType != null) {
1839                 string impl = GetBaseTypeOutput(e.PrivateImplementationType);
1840                 impl = impl.Replace('.', '_');
1841                 e.Name = impl + "_" + e.Name;
1842             }
1843
1844             if (!IsCurrentInterface) {
1845                 if (e.PrivateImplementationType == null) {
1846                     OutputMemberAccessModifier(e.Attributes);
1847                     if (MethodIsOverloaded(e, c))
1848                         Output.Write("Overloads ");
1849                 }
1850                 OutputVTableModifier(e.Attributes);
1851                 OutputMemberScopeModifier(e.Attributes);
1852             }
1853             else {
1854                 // interface may still need "Shadows"
1855                 OutputVTableModifier(e.Attributes);
1856             }
1857             bool sub = false;
1858             if (e.ReturnType.BaseType.Length == 0 || string.Compare(e.ReturnType.BaseType, typeof(void).FullName, StringComparison.OrdinalIgnoreCase) == 0) {
1859                 sub = true;
1860             }
1861
1862             if (sub) {
1863                 Output.Write("Sub ");
1864             }
1865             else {
1866                 Output.Write("Function ");
1867             }
1868
1869
1870             OutputIdentifier(e.Name);
1871             OutputTypeParameters(e.TypeParameters);
1872             
1873             Output.Write("(");
1874             OutputParameters(e.Parameters);
1875             Output.Write(")");
1876
1877             if (!sub) {
1878                 Output.Write(" As ");
1879                 if (e.ReturnTypeCustomAttributes.Count > 0) {
1880                     OutputAttributes(e.ReturnTypeCustomAttributes, true);
1881                 }
1882
1883                 OutputType(e.ReturnType);
1884                 OutputArrayPostfix(e.ReturnType);
1885             }
1886             if (e.ImplementationTypes.Count > 0) {
1887                 Output.Write(" Implements ");
1888                 bool first = true;
1889                 foreach (CodeTypeReference type in e.ImplementationTypes) {
1890                     if (first) {
1891                         first = false;
1892                     }   
1893                     else {
1894                         Output.Write(" , ");
1895                     }
1896                     OutputType(type);
1897                     Output.Write(".");
1898                     OutputIdentifier(methodName);
1899                 }
1900             }
1901             else if (e.PrivateImplementationType != null) {
1902                 Output.Write(" Implements ");
1903                 OutputType(e.PrivateImplementationType);
1904                 Output.Write(".");
1905                 OutputIdentifier(methodName);
1906             }
1907             Output.WriteLine("");
1908             if (!IsCurrentInterface
1909                 && (e.Attributes & MemberAttributes.ScopeMask) != MemberAttributes.Abstract) {
1910                 Indent++;
1911
1912                 GenerateVBStatements(e.Statements);
1913
1914                 Indent--;
1915                 if (sub) {
1916                     Output.WriteLine("End Sub");
1917                 }
1918                 else {
1919                     Output.WriteLine("End Function");
1920                 }
1921             }
1922             // reset the name that possibly got changed with the implements clause
1923             e.Name = methodName;
1924         }
1925
1926         protected override void GenerateEntryPointMethod(CodeEntryPointMethod e, CodeTypeDeclaration c) {
1927             if (e.CustomAttributes.Count > 0) {
1928                 OutputAttributes(e.CustomAttributes, false);
1929             }
1930
1931             Output.WriteLine("Public Shared Sub Main()");
1932             Indent++;
1933
1934             GenerateVBStatements(e.Statements);
1935
1936             Indent--;
1937             Output.WriteLine("End Sub");
1938         }
1939
1940         private bool PropertyIsOverloaded(CodeMemberProperty e, CodeTypeDeclaration c) {
1941             if ((e.Attributes & MemberAttributes.Overloaded) != 0) {
1942                 return true;
1943             }
1944             IEnumerator en = c.Members.GetEnumerator();
1945             while (en.MoveNext()) {
1946                 if (!(en.Current is CodeMemberProperty))
1947                     continue;
1948                 CodeMemberProperty prop = (CodeMemberProperty) en.Current;
1949                 if ( prop != e
1950                     && prop.Name.Equals(e.Name, StringComparison.OrdinalIgnoreCase)
1951                     && prop.PrivateImplementationType == null)
1952                 {
1953                     return true;
1954                 }
1955             }
1956
1957             return false;
1958         }
1959
1960         /// <devdoc>
1961         ///    <para>
1962         ///       Generates code for the specified CodeDom based member property
1963         ///       representation.
1964         ///    </para>
1965         /// </devdoc>
1966         protected override void GenerateProperty(CodeMemberProperty e, CodeTypeDeclaration c) {
1967             if (!(IsCurrentClass || IsCurrentStruct || IsCurrentInterface)) return;
1968
1969             if (e.CustomAttributes.Count > 0) {
1970                 OutputAttributes(e.CustomAttributes, false);
1971             }
1972
1973             string propName = e.Name;
1974             if (e.PrivateImplementationType != null)
1975             {
1976                 string impl = GetBaseTypeOutput(e.PrivateImplementationType);
1977                 impl = impl.Replace('.', '_');
1978                 e.Name = impl + "_" + e.Name;
1979             }
1980             if (!IsCurrentInterface) {
1981                 if (e.PrivateImplementationType == null) {
1982                     OutputMemberAccessModifier(e.Attributes);
1983                     if (PropertyIsOverloaded(e,c)) {
1984                         Output.Write("Overloads ");
1985                     }
1986                 }
1987                 OutputVTableModifier(e.Attributes);
1988                 OutputMemberScopeModifier(e.Attributes);
1989             }
1990             else {
1991                 // interface may still need "Shadows"
1992                 OutputVTableModifier(e.Attributes);
1993             }
1994             if (e.Parameters.Count > 0 && String.Compare(e.Name, "Item", StringComparison.OrdinalIgnoreCase) == 0) {
1995                 Output.Write("Default ");
1996             }
1997             if (e.HasGet) {
1998                 if (!e.HasSet) {
1999                     Output.Write("ReadOnly ");
2000                 }
2001             }
2002             else if (e.HasSet) {
2003                 Output.Write("WriteOnly ");
2004             }
2005             Output.Write("Property ");
2006             OutputIdentifier(e.Name);
2007             Output.Write("(");
2008             if (e.Parameters.Count > 0) {
2009                 OutputParameters(e.Parameters);
2010             }
2011             Output.Write(")");
2012             Output.Write(" As ");
2013             OutputType(e.Type);
2014             OutputArrayPostfix(e.Type);
2015
2016             if (e.ImplementationTypes.Count > 0) {
2017                 Output.Write(" Implements ");
2018                 bool first = true;
2019                 foreach (CodeTypeReference type in e.ImplementationTypes) {
2020                     if (first) {
2021                         first = false;
2022                     }   
2023                     else {
2024                         Output.Write(" , ");
2025                     }
2026                     OutputType(type);
2027                     Output.Write(".");
2028                     OutputIdentifier(propName);
2029                 }
2030             }
2031             else if (e.PrivateImplementationType != null) {
2032                 Output.Write(" Implements ");
2033                 OutputType(e.PrivateImplementationType);
2034                 Output.Write(".");
2035                 OutputIdentifier(propName);
2036             }
2037
2038             Output.WriteLine("");
2039
2040             if (!c.IsInterface && (e.Attributes & MemberAttributes.ScopeMask) != MemberAttributes.Abstract) {
2041                 Indent++;
2042
2043                 if (e.HasGet) {
2044
2045                     Output.WriteLine("Get");
2046                     if (!IsCurrentInterface) {
2047                         Indent++;
2048
2049                         GenerateVBStatements(e.GetStatements);
2050                         e.Name = propName;
2051
2052                         Indent--;
2053                         Output.WriteLine("End Get");
2054                     }
2055                 }
2056                 if (e.HasSet) {
2057                     Output.WriteLine("Set");
2058                     if (!IsCurrentInterface) {
2059                         Indent++;
2060                         GenerateVBStatements(e.SetStatements);
2061                         Indent--;
2062                         Output.WriteLine("End Set");
2063                     }
2064                 }
2065                 Indent--;
2066                 Output.WriteLine("End Property");
2067             }
2068
2069             e.Name = propName;
2070         }
2071
2072         /// <devdoc>
2073         ///    <para>
2074         ///       Generates code for the specified CodeDom based property reference
2075         ///       expression representation.
2076         ///    </para>
2077         /// </devdoc>
2078         protected override void GeneratePropertyReferenceExpression(CodePropertyReferenceExpression e) {
2079
2080             if (e.TargetObject != null) {
2081                 GenerateExpression(e.TargetObject);
2082                 Output.Write(".");
2083                 Output.Write(e.PropertyName);
2084             }
2085             else {
2086                 OutputIdentifier(e.PropertyName);
2087             }
2088         }
2089
2090         /// <devdoc>
2091         ///    <para>
2092         ///       Generates code for the specified CodeDom based constructor
2093         ///       representation.
2094         ///    </para>
2095         /// </devdoc>
2096         protected override void GenerateConstructor(CodeConstructor e, CodeTypeDeclaration c) {
2097             if (!(IsCurrentClass || IsCurrentStruct)) return;
2098
2099             if (e.CustomAttributes.Count > 0) {
2100                 OutputAttributes(e.CustomAttributes, false);
2101             }
2102
2103             OutputMemberAccessModifier(e.Attributes);
2104             Output.Write("Sub New(");
2105             OutputParameters(e.Parameters);
2106             Output.WriteLine(")");
2107             Indent++;
2108
2109             CodeExpressionCollection baseArgs = e.BaseConstructorArgs;
2110             CodeExpressionCollection thisArgs = e.ChainedConstructorArgs;
2111
2112             if (thisArgs.Count > 0) {
2113                 Output.Write("Me.New(");
2114                 OutputExpressionList(thisArgs);
2115                 Output.Write(")");
2116                 Output.WriteLine("");                
2117             }
2118             else if (baseArgs.Count > 0) {
2119                 Output.Write("MyBase.New(");
2120                 OutputExpressionList(baseArgs);
2121                 Output.Write(")");
2122                 Output.WriteLine("");
2123             }
2124             else if(IsCurrentClass) {
2125                 // struct doesn't have MyBase
2126                 Output.WriteLine("MyBase.New");
2127             }
2128
2129             GenerateVBStatements(e.Statements);
2130             Indent--;
2131             Output.WriteLine("End Sub");
2132         }
2133         /// <devdoc>
2134         ///    <para>
2135         ///       Generates code for the specified CodeDom based class constructor
2136         ///       representation.
2137         ///    </para>
2138         /// </devdoc>
2139         protected override void GenerateTypeConstructor(CodeTypeConstructor e) {
2140             if (!(IsCurrentClass || IsCurrentStruct)) return;
2141
2142             if (e.CustomAttributes.Count > 0) {
2143                 OutputAttributes(e.CustomAttributes, false);
2144             }
2145
2146             Output.WriteLine("Shared Sub New()");
2147             Indent++;
2148             GenerateVBStatements(e.Statements);
2149             Indent--;
2150             Output.WriteLine("End Sub");
2151         }
2152
2153         protected override void GenerateTypeOfExpression(CodeTypeOfExpression e) {
2154             Output.Write("GetType(");
2155             Output.Write(GetTypeOutput(e.Type));            
2156             Output.Write(")");
2157         }
2158
2159         /// <devdoc>
2160         ///    <para>
2161         ///       Generates code for the CodeDom based class start representation.
2162         ///    </para>
2163         /// </devdoc>
2164         protected override void GenerateTypeStart(CodeTypeDeclaration e) {
2165             if (IsCurrentDelegate) {
2166                 if (e.CustomAttributes.Count > 0) {
2167                     OutputAttributes(e.CustomAttributes, false);
2168                 }
2169
2170                 switch (e.TypeAttributes & TypeAttributes.VisibilityMask) {
2171                     case TypeAttributes.Public:
2172                         Output.Write("Public ");
2173                         break;
2174                     case TypeAttributes.NotPublic:
2175                     default:
2176                         break;
2177                 }
2178
2179                 CodeTypeDelegate del = (CodeTypeDelegate)e;
2180                 if (del.ReturnType.BaseType.Length > 0 && string.Compare(del.ReturnType.BaseType, "System.Void", StringComparison.OrdinalIgnoreCase) != 0)
2181                     Output.Write("Delegate Function ");
2182                 else
2183                     Output.Write("Delegate Sub ");
2184                 OutputIdentifier(e.Name);
2185                 Output.Write("(");
2186                 OutputParameters(del.Parameters);
2187                 Output.Write(")");
2188                 if (del.ReturnType.BaseType.Length > 0 && string.Compare(del.ReturnType.BaseType, "System.Void", StringComparison.OrdinalIgnoreCase) != 0) {
2189                     Output.Write(" As ");
2190                     OutputType(del.ReturnType);
2191                     OutputArrayPostfix(del.ReturnType);
2192                 }
2193                 Output.WriteLine("");
2194             }
2195             else if (e.IsEnum) {
2196                 if (e.CustomAttributes.Count > 0) {
2197                     OutputAttributes(e.CustomAttributes, false);
2198                 }
2199                 OutputTypeAttributes(e);                                
2200                                 
2201                 OutputIdentifier(e.Name);
2202
2203                 if (e.BaseTypes.Count > 0) {
2204                     Output.Write(" As ");                    
2205                     OutputType(e.BaseTypes[0]);
2206                 }
2207
2208                 Output.WriteLine("");
2209                 Indent++;
2210             }
2211             else {                
2212                 if (e.CustomAttributes.Count > 0) {
2213                     OutputAttributes(e.CustomAttributes, false);
2214                 }
2215                 OutputTypeAttributes(e);                                
2216                                 
2217                 OutputIdentifier(e.Name);
2218                 OutputTypeParameters(e.TypeParameters);
2219
2220                 bool writtenInherits = false;
2221                 bool writtenImplements = false;
2222                 // For a structure we can't have an inherits clause
2223                 if (e.IsStruct) {
2224                     writtenInherits = true;
2225                 }
2226                 // For an interface we can't have an implements clause
2227                 if (e.IsInterface) {
2228                     writtenImplements = true;
2229                 }
2230                 Indent++;
2231                 foreach (CodeTypeReference typeRef in e.BaseTypes) {
2232                     // if we're generating an interface, we always want to use Inherits because interfaces can't Implement anything. 
2233                     if (!writtenInherits && (e.IsInterface || !typeRef.IsInterface)) {
2234                         Output.WriteLine("");
2235                         Output.Write("Inherits ");
2236                         writtenInherits = true;
2237                     }
2238                     else if (!writtenImplements) {
2239                         Output.WriteLine("");
2240                         Output.Write("Implements ");
2241                         writtenImplements = true;
2242                     }
2243                     else {
2244                         Output.Write(", ");
2245                     }                 
2246                     OutputType(typeRef);
2247                 }
2248
2249                 Output.WriteLine("");
2250             }
2251         }
2252
2253         private void OutputTypeParameters(CodeTypeParameterCollection typeParameters) {            
2254             if( typeParameters.Count == 0) {
2255                 return;
2256             }
2257
2258             Output.Write("(Of ");
2259             bool first = true;
2260             for(int i = 0; i < typeParameters.Count; i++) {
2261                 if( first) {
2262                     first = false;
2263                 }
2264                 else {
2265                     Output.Write(", ");
2266                 }
2267                 Output.Write(typeParameters[i].Name);
2268                 OutputTypeParameterConstraints(typeParameters[i]);                
2269             }
2270
2271             Output.Write(')');
2272         }
2273
2274         // In VB, constraints are put right after the type paramater name.
2275         // In C#, there is a seperate "where" statement
2276         private void OutputTypeParameterConstraints(CodeTypeParameter typeParameter) {
2277             CodeTypeReferenceCollection constraints = typeParameter.Constraints;
2278             int constraintCount = constraints.Count;
2279             if( typeParameter.HasConstructorConstraint) {
2280                 constraintCount++;
2281             }          
2282
2283             if( constraintCount == 0) {
2284                 return;
2285             }
2286
2287             // generating something like: "ValType As {IComparable, Customer, New}"
2288             Output.Write(" As ");
2289             if(constraintCount > 1) {
2290                 Output.Write(" {");
2291             }
2292
2293             bool first = true;
2294             foreach (CodeTypeReference typeRef in constraints) {
2295                 if (first) {
2296                     first = false;
2297                 }
2298                 else {
2299                     Output.Write(", ");
2300                 }                 
2301                 Output.Write(GetTypeOutput(typeRef));
2302             }
2303                 
2304             if( typeParameter.HasConstructorConstraint) {
2305                 if (!first) {
2306                     Output.Write(", ");
2307                 }                 
2308
2309                 Output.Write("New");
2310             }
2311             
2312             if(constraintCount > 1) {
2313                 Output.Write('}');
2314             }
2315
2316         }
2317         
2318         /// <devdoc>
2319         ///    <para>
2320         ///       Generates code for the specified CodeDom based class end
2321         ///       representation.
2322         ///    </para>
2323         /// </devdoc>
2324         protected override void GenerateTypeEnd(CodeTypeDeclaration e) {
2325             if (!IsCurrentDelegate) {
2326                 Indent--;
2327                 string ending;
2328                 if (e.IsEnum) {
2329                     ending = "End Enum";
2330                 }
2331                 else if (e.IsInterface) {
2332                     ending = "End Interface";
2333                 }
2334                 else if (e.IsStruct) {
2335                     ending = "End Structure";
2336                 } else {
2337                     if (IsCurrentModule) {
2338                         ending = "End Module";
2339                     }
2340                     else {
2341                         ending = "End Class";
2342                     }
2343                 }
2344                 Output.WriteLine(ending);
2345             }
2346         }
2347
2348         /// <devdoc>
2349         ///    <para>
2350         ///       Generates code for the CodeDom based namespace representation.
2351         ///    </para>
2352         /// </devdoc>
2353         protected override void GenerateNamespace(CodeNamespace e) {
2354
2355             if (GetUserData(e, "GenerateImports", true)) {
2356                 GenerateNamespaceImports(e);
2357             }
2358             Output.WriteLine();
2359             GenerateCommentStatements(e.Comments);
2360             GenerateNamespaceStart(e);
2361             GenerateTypes(e);
2362             GenerateNamespaceEnd(e);
2363         }
2364
2365         protected bool AllowLateBound(CodeCompileUnit e) {
2366             object o = e.UserData["AllowLateBound"];
2367             if (o != null && o is bool) {
2368                 return (bool)o;
2369             }
2370             // We have Option Strict Off by default because it can fail on simple things like dividing
2371             // two integers.
2372             return true;
2373         }
2374
2375         protected bool RequireVariableDeclaration(CodeCompileUnit e) {
2376             object o = e.UserData["RequireVariableDeclaration"];
2377             if (o != null && o is bool) {
2378                 return (bool)o;
2379             }
2380             return true;
2381         }
2382
2383         private bool GetUserData(CodeObject e, string property, bool defaultValue) {
2384             object o = e.UserData[property];
2385             if (o != null && o is bool) {
2386                 return (bool)o;
2387             }
2388             return defaultValue;
2389         }
2390
2391         protected override void GenerateCompileUnitStart(CodeCompileUnit e) {
2392             base.GenerateCompileUnitStart(e);
2393         
2394             Output.WriteLine("'------------------------------------------------------------------------------");
2395             Output.Write("' <");
2396             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line1));
2397             Output.Write("'     ");
2398             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line2));
2399             Output.Write("'     ");
2400             Output.Write(SR.GetString(SR.AutoGen_Comment_Line3));
2401             Output.WriteLine(System.Environment.Version.ToString());
2402             Output.WriteLine("'");
2403             Output.Write("'     ");
2404             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line4));
2405             Output.Write("'     ");
2406             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line5));
2407             Output.Write("' </");
2408             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line1));            
2409             Output.WriteLine("'------------------------------------------------------------------------------");
2410             Output.WriteLine("");
2411
2412             if (AllowLateBound(e))
2413                 Output.WriteLine("Option Strict Off");
2414             else
2415                 Output.WriteLine("Option Strict On");
2416
2417             if (!RequireVariableDeclaration(e))
2418                 Output.WriteLine("Option Explicit Off");
2419             else
2420                 Output.WriteLine("Option Explicit On");
2421
2422             Output.WriteLine();
2423
2424         }
2425
2426         protected override void GenerateCompileUnit(CodeCompileUnit e) {
2427            
2428             GenerateCompileUnitStart(e);
2429
2430             SortedList importList;            
2431             // Visual Basic needs all the imports together at the top of the compile unit.
2432             // If generating multiple namespaces, gather all the imports together
2433             importList = new SortedList(StringComparer.OrdinalIgnoreCase);
2434             foreach (CodeNamespace nspace in e.Namespaces) {
2435                 // mark the namespace to stop it generating its own import list
2436                 nspace.UserData["GenerateImports"] = false;
2437
2438                 // Collect the unique list of imports
2439                 foreach (CodeNamespaceImport import in nspace.Imports) {
2440                     if (!importList.Contains(import.Namespace)) {
2441                         importList.Add(import.Namespace, import.Namespace);
2442                     }
2443                 }
2444             }
2445             // now output the imports
2446             foreach(string import in importList.Keys) {
2447                 Output.Write("Imports ");
2448                 OutputIdentifier(import);
2449                 Output.WriteLine("");
2450             }
2451
2452             if (e.AssemblyCustomAttributes.Count > 0) {
2453                 OutputAttributes(e.AssemblyCustomAttributes, false, "Assembly: ", true);
2454             }
2455
2456             GenerateNamespaces(e);
2457             GenerateCompileUnitEnd(e);            
2458         }
2459         
2460         protected override void GenerateDirectives(CodeDirectiveCollection directives) {
2461             for (int i = 0; i < directives.Count; i++) {
2462                 CodeDirective directive = directives[i];
2463                 if (directive is CodeChecksumPragma) {
2464                     GenerateChecksumPragma((CodeChecksumPragma)directive);
2465                 }
2466                 else if (directive is CodeRegionDirective) {
2467                     GenerateCodeRegionDirective((CodeRegionDirective)directive);
2468                 }
2469             }
2470         }
2471
2472         private void GenerateChecksumPragma(CodeChecksumPragma checksumPragma) {
2473             // the syntax is: #ExternalChecksum("FileName","GuidChecksum","ChecksumValue")
2474             Output.Write("#ExternalChecksum(\"");
2475             Output.Write(checksumPragma.FileName);
2476             Output.Write("\",\"");
2477             Output.Write(checksumPragma.ChecksumAlgorithmId.ToString("B", CultureInfo.InvariantCulture));
2478             Output.Write("\",\"");
2479             if (checksumPragma.ChecksumData != null) {
2480                 foreach(Byte b in checksumPragma.ChecksumData) {
2481                     Output.Write(b.ToString("X2", CultureInfo.InvariantCulture));
2482                 }
2483             }
2484             Output.WriteLine("\")");            
2485         }
2486                 
2487         private void GenerateCodeRegionDirective(CodeRegionDirective regionDirective) {
2488             // VB does not support regions within statement blocks
2489             if (IsGeneratingStatements()) {
2490                 return;
2491             }
2492             if (regionDirective.RegionMode == CodeRegionMode.Start) {
2493                 Output.Write("#Region \"");
2494                 Output.Write(regionDirective.RegionText);
2495                 Output.WriteLine("\"");
2496             }
2497             else if (regionDirective.RegionMode == CodeRegionMode.End) {
2498                 Output.WriteLine("#End Region");
2499             }
2500         }        
2501
2502         /// <devdoc>
2503         ///    <para>
2504         ///       Generates code for the specified CodeDom based namespace representation.
2505         ///    </para>
2506         /// </devdoc>
2507         protected override void GenerateNamespaceStart(CodeNamespace e) {
2508             if (e.Name != null && e.Name.Length > 0) {
2509                 Output.Write("Namespace ");
2510                 string[] names = e.Name.Split('.');
2511                 Debug.Assert( names.Length > 0);
2512                 OutputIdentifier(names[0]);
2513                 for( int i = 1; i< names.Length; i++) {
2514                     Output.Write(".");
2515                     OutputIdentifier(names[i]);                    
2516                 }
2517                 Output.WriteLine();
2518                 Indent++;
2519             }
2520         }
2521
2522         /// <devdoc>
2523         ///    <para>
2524         ///       Generates code for the specified CodeDom based namespace representation.
2525         ///    </para>
2526         /// </devdoc>
2527         protected override void GenerateNamespaceEnd(CodeNamespace e) {
2528             if (e.Name != null && e.Name.Length > 0) {
2529                 Indent--;
2530                 Output.WriteLine("End Namespace");
2531             }
2532         }
2533
2534         /// <devdoc>
2535         ///    <para>
2536         ///       Generates code for the specified CodeDom based namespace import
2537         ///       representation.
2538         ///    </para>
2539         /// </devdoc>
2540         protected override void GenerateNamespaceImport(CodeNamespaceImport e) {
2541             Output.Write("Imports ");
2542             OutputIdentifier(e.Namespace);
2543             Output.WriteLine("");
2544         }
2545
2546         /// <devdoc>
2547         ///    <para>
2548         ///       Generates code for the specified CodeDom based attribute block start
2549         ///       representation.
2550         ///    </para>
2551         /// </devdoc>
2552         protected override void GenerateAttributeDeclarationsStart(CodeAttributeDeclarationCollection attributes) {
2553             Output.Write("<");
2554         }
2555         /// <devdoc>
2556         ///    <para>
2557         ///       Generates code for the specified CodeDom based attribute block end
2558         ///       representation.
2559         ///    </para>
2560         /// </devdoc>
2561         protected override void GenerateAttributeDeclarationsEnd(CodeAttributeDeclarationCollection attributes) {
2562             Output.Write(">");
2563         }
2564
2565         public static bool IsKeyword(string value) {
2566             return FixedStringLookup.Contains(keywords, value, true);
2567         }
2568
2569         protected override bool Supports(GeneratorSupport support) {
2570             return ((support & LanguageSupport) == support);
2571         }
2572
2573         /// <devdoc>
2574         ///    <para>
2575         ///       Gets whether the specified identifier is valid.
2576         ///    </para>
2577         /// </devdoc>
2578         protected override bool IsValidIdentifier(string value) {
2579
2580             // identifiers must be 1 char or longer
2581             //
2582             if (value == null || value.Length == 0) {
2583                 return false;
2584             }
2585
2586             if (value.Length > 1023)
2587                 return false;
2588
2589             // identifiers cannot be a keyword unless surrounded by []'s
2590             //
2591             if (value[0] != '[' || value[value.Length - 1] != ']') {
2592                 if (IsKeyword(value)) {
2593                     return false;
2594                 }
2595             } else {
2596                 value = value.Substring(1, value.Length - 2);
2597             }
2598
2599             // just _ as an identifier is not valid. 
2600             if (value.Length == 1 && value[0] == '_')
2601                 return false;
2602             
2603             return CodeGenerator.IsValidLanguageIndependentIdentifier(value);
2604         }
2605
2606         protected override string CreateValidIdentifier(string name) {
2607             if (IsKeyword(name)) {
2608                 return "_" + name;
2609             }
2610             return name;
2611         }
2612
2613         protected override string CreateEscapedIdentifier(string name) {
2614             if (IsKeyword(name)) {
2615                 return "[" + name + "]";
2616             }
2617             return name;
2618         }      
2619         
2620         private string GetBaseTypeOutput(CodeTypeReference typeRef) {
2621             string baseType = typeRef.BaseType;
2622
2623             if (baseType.Length == 0) {
2624                 return "Void";
2625             } 
2626             else if (string.Compare(baseType, "System.Byte", StringComparison.OrdinalIgnoreCase) == 0) {
2627                 return "Byte";
2628             }
2629             else if (string.Compare(baseType, "System.SByte", StringComparison.OrdinalIgnoreCase) == 0) {
2630                 return "SByte";
2631             }
2632             else if (string.Compare(baseType, "System.Int16", StringComparison.OrdinalIgnoreCase) == 0) {
2633                 return "Short";
2634             }
2635             else if (string.Compare(baseType, "System.Int32", StringComparison.OrdinalIgnoreCase) == 0) {
2636                 return "Integer";
2637             }
2638             else if (string.Compare(baseType, "System.Int64", StringComparison.OrdinalIgnoreCase) == 0) {
2639                 return "Long";
2640             }
2641             else if (string.Compare(baseType, "System.UInt16", StringComparison.OrdinalIgnoreCase) == 0) {
2642                 return "UShort";
2643             }
2644             else if (string.Compare(baseType, "System.UInt32", StringComparison.OrdinalIgnoreCase) == 0) {
2645                 return "UInteger";
2646             }
2647             else if (string.Compare(baseType, "System.UInt64", StringComparison.OrdinalIgnoreCase) == 0) {
2648                 return "ULong";
2649             }
2650             else if (string.Compare(baseType, "System.String", StringComparison.OrdinalIgnoreCase) == 0) {
2651                 return "String";
2652             }
2653             else if (string.Compare(baseType, "System.DateTime", StringComparison.OrdinalIgnoreCase) == 0) {
2654                 return "Date";
2655             }
2656             else if (string.Compare(baseType, "System.Decimal", StringComparison.OrdinalIgnoreCase) == 0) {
2657                 return "Decimal";
2658             }
2659             else if (string.Compare(baseType, "System.Single", StringComparison.OrdinalIgnoreCase) == 0) {
2660                 return "Single";
2661             }
2662             else if (string.Compare(baseType, "System.Double", StringComparison.OrdinalIgnoreCase) == 0) {
2663                 return "Double";
2664             }
2665             else if (string.Compare(baseType, "System.Boolean", StringComparison.OrdinalIgnoreCase) == 0) {
2666                 return "Boolean";
2667             }
2668             else if (string.Compare(baseType, "System.Char", StringComparison.OrdinalIgnoreCase) == 0) {
2669                 return "Char";
2670             }
2671             else if (string.Compare(baseType, "System.Object", StringComparison.OrdinalIgnoreCase) == 0) {
2672                 return "Object";
2673             }
2674             else {
2675                 StringBuilder sb = new StringBuilder(baseType.Length + 10);
2676                 if((typeRef.Options & CodeTypeReferenceOptions.GlobalReference) != 0) {
2677                     sb.Append("Global.");
2678                 }
2679
2680                 int lastIndex = 0;
2681                 int currentTypeArgStart = 0;
2682                 for (int i=0; i<baseType.Length; i++) {
2683                     switch (baseType[i]) {
2684                     case '+':
2685                     case '.':
2686                         sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex, i-lastIndex)));
2687                         sb.Append('.');
2688                         i++;
2689                         lastIndex = i;
2690                         break;
2691                         
2692                     case '`':
2693                         sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex, i-lastIndex)));
2694                         i++;    // skip the '
2695                         int numTypeArgs = 0;
2696                         while (i < baseType.Length && baseType[i] >= '0' && baseType[i] <='9') {
2697                             numTypeArgs = numTypeArgs*10 + (baseType[i] - '0');
2698                             i++;
2699                         }
2700                 
2701                         GetTypeArgumentsOutput(typeRef.TypeArguments, currentTypeArgStart, numTypeArgs, sb);
2702                         currentTypeArgStart += numTypeArgs;
2703                 
2704                         // Arity can be in the middle of a nested type name, so we might have a . or + after it. 
2705                         // Skip it if so. 
2706                         if (i < baseType.Length &&  (baseType[i] =='+' || baseType[i] == '.')) {
2707                             sb.Append('.');
2708                             i++;
2709                         }
2710                             
2711                         lastIndex = i;
2712                         break;
2713                     }
2714                 }
2715                 
2716                 if (lastIndex < baseType.Length)
2717                     sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex)));
2718
2719                 return sb.ToString();                
2720             }
2721         }
2722
2723         private string GetTypeOutputWithoutArrayPostFix(CodeTypeReference typeRef) {
2724             StringBuilder sb = new StringBuilder(); 
2725
2726             while( typeRef.ArrayElementType != null) {
2727                 typeRef = typeRef.ArrayElementType;
2728             }
2729             
2730             sb.Append(GetBaseTypeOutput(typeRef));
2731             return sb.ToString();
2732         }
2733
2734         private String GetTypeArgumentsOutput(CodeTypeReferenceCollection typeArguments) {
2735             StringBuilder sb = new StringBuilder(128);
2736             GetTypeArgumentsOutput(typeArguments, 0, typeArguments.Count, sb);
2737             return sb.ToString();
2738         }
2739             
2740
2741         private void GetTypeArgumentsOutput(CodeTypeReferenceCollection typeArguments, int start, int length, StringBuilder sb) {
2742             sb.Append("(Of ");
2743             bool first = true;
2744             for( int i = start; i < start+length; i++) {
2745                 if( first) {
2746                     first = false;
2747                 }
2748                 else {
2749                     sb.Append(", ");
2750                 }                
2751
2752                 // it's possible that we call GetTypeArgumentsOutput with an empty typeArguments collection.  This is the case
2753                 // for open types, so we want to just output the brackets and commas. 
2754                 if (i < typeArguments.Count)
2755                     sb.Append(GetTypeOutput(typeArguments[i]));                 
2756             }
2757             sb.Append(')');
2758         }
2759
2760         protected override string GetTypeOutput(CodeTypeReference typeRef) {
2761             string s = String.Empty;            
2762             s += GetTypeOutputWithoutArrayPostFix(typeRef);
2763             
2764             if (typeRef.ArrayRank > 0) {
2765                 s += GetArrayPostfix(typeRef);
2766             }
2767             return s;
2768         }
2769
2770         protected override void ContinueOnNewLine(string st) {
2771             Output.Write(st);
2772             Output.WriteLine(" _");
2773         }
2774         
2775         private bool IsGeneratingStatements() {
2776             Debug.Assert(statementDepth >= 0, "statementDepth >= 0");
2777             return (statementDepth > 0);
2778         }
2779         
2780         private void GenerateVBStatements(CodeStatementCollection stms) {
2781             statementDepth++;
2782             try {
2783                 GenerateStatements(stms);
2784             }
2785             finally {
2786                 statementDepth--;
2787             }
2788         }
2789         
2790         [ResourceExposure(ResourceScope.Machine)]
2791         [ResourceConsumption(ResourceScope.Machine)]
2792         protected override CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames) {
2793             if( options == null) {
2794                 throw new ArgumentNullException("options");
2795             }
2796             if (fileNames == null)
2797                 throw new ArgumentNullException("fileNames");
2798
2799             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
2800
2801             string outputFile = null;
2802             int retValue = 0;
2803
2804             CompilerResults results = new CompilerResults(options.TempFiles);
2805             SecurityPermission perm1 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
2806             perm1.Assert();
2807             try {
2808 #pragma warning disable 618
2809                results.Evidence = options.Evidence;
2810 #pragma warning restore 618
2811             }
2812             finally {
2813                  SecurityPermission.RevertAssert();
2814             }
2815             bool createdEmptyAssembly = false;
2816             
2817             string extension = (options.GenerateExecutable) ? "exe" : "dll";
2818             string extensionWithDot = '.' + extension;
2819
2820             if (options.OutputAssembly == null || options.OutputAssembly.Length == 0) {
2821                 options.OutputAssembly = results.TempFiles.AddExtension(extension, !options.GenerateInMemory);
2822
2823                 // Create an empty assembly.  This is so that the file will have permissions that
2824                 // we can later access with our current credential.<
2825
2826                 new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite).Close();
2827                 createdEmptyAssembly = true;
2828             }
2829             
2830             String outputAssemblyFile = options.OutputAssembly;
2831             
2832             if (!Path.GetExtension(outputAssemblyFile).Equals(extensionWithDot, StringComparison.OrdinalIgnoreCase)) {
2833                 // The vb compiler automatically appends the 'dll' or 'exe' extension if it's not present. 
2834                 // We similarly determine the file name, so we can find it later.
2835                 outputAssemblyFile += extensionWithDot;
2836             }
2837
2838 #if FEATURE_PAL
2839             string pdbname = "ildb";
2840 #else
2841             string pdbname = "pdb";
2842 #endif
2843
2844             // hack so that we don't delete pdbs when debug=false but they have specified pdbonly. 
2845             if (options.CompilerOptions!= null && options.CompilerOptions.IndexOf("/debug:pdbonly", StringComparison.OrdinalIgnoreCase) != -1)
2846                 results.TempFiles.AddExtension(pdbname, true);
2847             else
2848                 results.TempFiles.AddExtension(pdbname);
2849
2850             string args = CmdArgsFromParameters(options) + " " + JoinStringArray(fileNames, " ");
2851
2852             // Use a response file if the compiler supports it
2853             string responseFileArgs = GetResponseFileCmdArgs(options, args);
2854             string trueArgs = null;
2855             if (responseFileArgs != null) {
2856                 trueArgs = args;
2857                 args = responseFileArgs;
2858             }
2859
2860             Compile(options,
2861                 RedistVersionInfo.GetCompilerPath(provOptions, CompilerName),
2862                 CompilerName, 
2863                 args, 
2864                 ref outputFile, 
2865                 ref retValue, 
2866                 trueArgs);
2867
2868             results.NativeCompilerReturnValue = retValue;
2869
2870             // only look for errors/warnings if the compile failed or the caller set the warning level
2871             if (retValue != 0 || options.WarningLevel > 0) {
2872
2873                 // The VB Compiler generates multi-line error messages. Currently, the best way to obtain the
2874                 // full message without going too far, is to use the distinction between \n and \r\n. 
2875                 // For multi-line error messages, the former is always output between lines of an error message, 
2876                 // and the latter is output at the end. So this rearranges the output of File.ReadAllLines 
2877                 // so that an error message is contained on a line.
2878                 // 
2879                 // As of now, this is the best way to match a full error message. This is because the compiler 
2880                 // may output other trailing data which isn't an error msg or warning, but doesn't belong to 
2881                 // the error message. So trailing data could get tacked on since the message doesn't always end 
2882                 // with punctuation or some other marker. I confirmed this with the VBC group.
2883                 byte[] fileBytes = ReadAllBytes(outputFile, FileShare.ReadWrite);
2884
2885                 // The output of the compiler is in UTF8
2886                 string fileStr = Encoding.UTF8.GetString(fileBytes);
2887
2888                 // Split lines only around \r\n (see above)
2889                 string[] lines = Regex.Split(fileStr, @"\r\n");
2890
2891                 foreach (string line in lines) {
2892                     results.Output.Add(line);
2893
2894                     ProcessCompilerOutputLine(results, line);
2895                 }
2896
2897                 // Delete the empty assembly if we created one
2898                 if (retValue != 0 && createdEmptyAssembly)
2899                     File.Delete(outputAssemblyFile);
2900             }
2901
2902             if (!results.Errors.HasErrors && options.GenerateInMemory) {
2903                 FileStream fs = new FileStream(outputAssemblyFile, FileMode.Open, FileAccess.Read, FileShare.Read);
2904                 try {
2905                     int fileLen = (int)fs.Length;
2906                     byte[] b = new byte[fileLen];
2907                     fs.Read(b, 0, fileLen);
2908                     SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
2909                     perm.Assert();
2910                     try {
2911 #pragma warning disable 618 // Load with evidence is obsolete - this warning is passed on via the options.Evidence parameter
2912                        results.CompiledAssembly = Assembly.Load(b,null,options.Evidence);
2913 #pragma warning restore 618
2914                     }
2915                     finally {
2916                        SecurityPermission.RevertAssert();
2917                     }
2918                 }
2919                 finally {
2920                     fs.Close();
2921                 }
2922             }
2923             else {
2924
2925                 results.PathToAssembly = outputAssemblyFile;
2926             }
2927
2928             return results;
2929         }
2930
2931         private static byte[] ReadAllBytes(String file, FileShare share)
2932         {
2933             byte[] bytes;
2934             using(FileStream stream = File.Open(file, FileMode.Open, FileAccess.Read, share))
2935             {
2936                 int index = 0;
2937                 long fileLength = stream.Length;
2938                 if (fileLength > Int32.MaxValue)
2939                     throw new ArgumentOutOfRangeException("file");
2940
2941                 int count = (int) fileLength;
2942                 bytes = new byte[count];
2943                 while(count > 0) {
2944                     int n = stream.Read(bytes, index, count);
2945                     if (n == 0)
2946                         throw new EndOfStreamException();
2947                     index += n;
2948                     count -= n;
2949                 }
2950             }
2951             return bytes;
2952         }
2953     }  // VBCodeGenerator
2954
2955     #endregion class VBCodeGenerator
2956
2957
2958     #region class VBMemberAttributeConverter
2959
2960     internal class VBMemberAttributeConverter : VBModifierAttributeConverter {
2961         
2962         private static volatile string[] names;
2963         private static volatile object[] values;
2964         private static volatile VBMemberAttributeConverter defaultConverter;
2965
2966         
2967         private VBMemberAttributeConverter() {
2968             // no  need to create an instance; use Default
2969         }             
2970
2971         public static VBMemberAttributeConverter Default {
2972             get {
2973                 if (defaultConverter == null) {
2974                     defaultConverter = new VBMemberAttributeConverter();
2975                 }
2976                 return defaultConverter;
2977             }
2978         }
2979     
2980         /// <devdoc>
2981         ///      Retrieves an array of names for attributes.
2982         /// </devdoc>
2983         protected override string[] Names {
2984             get {
2985                 if (names == null) {
2986                     names = new string[] {
2987                         "Public",
2988                         "Protected",
2989                         "Protected Friend",
2990                         "Friend",
2991                         "Private"
2992                     };
2993                 }
2994                 
2995                 return names;
2996             }
2997         }
2998         
2999         /// <devdoc>
3000         ///      Retrieves an array of values for attributes.
3001         /// </devdoc>
3002         protected override object[] Values {
3003             get {
3004                 if (values == null) {
3005                     values = new object[] {
3006                         (object)MemberAttributes.Public,
3007                         (object)MemberAttributes.Family,
3008                         (object)MemberAttributes.FamilyOrAssembly,
3009                         (object)MemberAttributes.Assembly,
3010                         (object)MemberAttributes.Private
3011                     };
3012                 }
3013                 
3014                 return values;
3015             }
3016         }
3017
3018         protected override object DefaultValue {
3019             get {
3020                 return MemberAttributes.Private;                
3021             }
3022         }
3023     }  // VBMemberAttributeConverter
3024
3025     #endregion class VBMemberAttributeConverter
3026
3027
3028     #region class VBTypeAttributeConverter
3029
3030     internal class VBTypeAttributeConverter : VBModifierAttributeConverter {       
3031         private static volatile VBTypeAttributeConverter defaultConverter;
3032         private static volatile string[] names;
3033         private static volatile object[] values;
3034
3035         private VBTypeAttributeConverter() {
3036             // no  need to create an instance; use Default
3037         }
3038
3039         public static VBTypeAttributeConverter Default {
3040             get {
3041                 if (defaultConverter == null) {
3042                     defaultConverter = new VBTypeAttributeConverter();
3043                 }
3044                 return defaultConverter;
3045             }
3046         }
3047     
3048         /// <devdoc>
3049         ///      Retrieves an array of names for attributes.
3050         /// </devdoc>
3051         protected override string[] Names {
3052             get {
3053                 if (names == null) {
3054                     names = new string[] {
3055                         "Public",
3056                         "Friend"
3057                     };
3058                 }
3059                 
3060                 return names;
3061             }
3062         }
3063         
3064         /// <devdoc>
3065         ///      Retrieves an array of values for attributes.
3066         /// </devdoc>
3067         protected override object[] Values {
3068             get {
3069                 if (values == null) {
3070                     values = new object[] {
3071                         (object)TypeAttributes.Public,
3072                         (object)TypeAttributes.NotPublic                       
3073                     };
3074                 }
3075                 
3076                 return values;
3077             }
3078         }
3079
3080         protected override object DefaultValue {
3081             get {
3082                 return TypeAttributes.Public;
3083             }
3084         }
3085     }  // VBTypeAttributeConverter
3086
3087     #endregion class VBTypeAttributeConverter
3088
3089
3090     #region class VBModifierAttributeConverter
3091
3092     /// <devdoc>
3093     ///      This type converter provides common values for MemberAttributes
3094     /// </devdoc>
3095     internal abstract class VBModifierAttributeConverter : TypeConverter {
3096     
3097         protected abstract object[] Values { get; }
3098         protected abstract string[] Names  { get; }
3099         protected abstract object DefaultValue { get; }
3100     
3101         /// <devdoc>
3102         ///      We override this because we can convert from string types.
3103         /// </devdoc>
3104         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
3105             if (sourceType == typeof(string)) {
3106                 return true;
3107             }
3108             
3109             return base.CanConvertFrom(context, sourceType);
3110         }
3111
3112         /// <devdoc>
3113         ///      Converts the given object to the converter's native type.
3114         /// </devdoc>
3115         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
3116             if (value is string) {
3117                 string name = (string)value;
3118                 string[] names = Names;
3119                 for (int i = 0; i < names.Length; i++) {
3120                     if (names[i].Equals(name, StringComparison.OrdinalIgnoreCase)) {
3121                         return Values[i];
3122                     }
3123                 }
3124             }
3125             
3126             return DefaultValue;
3127         }
3128
3129         /// <devdoc>
3130         ///      Converts the given object to another type.  The most common types to convert
3131         ///      are to and from a string object.  The default implementation will make a call
3132         ///      to ToString on the object if the object is valid and if the destination
3133         ///      type is string.  If this cannot convert to the desitnation type, this will
3134         ///      throw a NotSupportedException.
3135         /// </devdoc>
3136         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {
3137             if (destinationType == null) {
3138                 throw new ArgumentNullException("destinationType");
3139             }
3140             
3141             if (destinationType == typeof(string)) {
3142                 object[] modifiers = Values;
3143                 for (int i = 0; i < modifiers.Length; i++) {
3144                     if (modifiers[i].Equals(value)) {
3145                         return Names[i];
3146                     }
3147                 }
3148                 
3149                 return SR.GetString(SR.toStringUnknown);
3150             }
3151
3152             return base.ConvertTo(context, culture, value, destinationType);
3153         }
3154
3155         /// <devdoc>
3156         ///      Determines if the list of standard values returned from
3157         ///      GetStandardValues is an exclusive list.  If the list
3158         ///      is exclusive, then no other values are valid, such as
3159         ///      in an enum data type.  If the list is not exclusive,
3160         ///      then there are other valid values besides the list of
3161         ///      standard values GetStandardValues provides.
3162         /// </devdoc>
3163         public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) {
3164             return true;
3165         }
3166         
3167         /// <devdoc>
3168         ///      Determines if this object supports a standard set of values
3169         ///      that can be picked from a list.
3170         /// </devdoc>
3171         public override bool GetStandardValuesSupported(ITypeDescriptorContext context) {
3172             return true;
3173         }
3174         
3175         /// <devdoc>
3176         ///      Retrieves a collection containing a set of standard values
3177         ///      for the data type this validator is designed for.  This
3178         ///      will return null if the data type does not support a
3179         ///      standard set of values.
3180         /// </devdoc>
3181         public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context) { 
3182             return new StandardValuesCollection(Values);
3183         }
3184     }  // VBModifierAttributeConverter
3185
3186     #endregion class VBModifierAttributeConverter
3187 }  // namespace
3188