The Labs \ Source Viewer \ SSCLI \ Microsoft.CSharp \ CSharpMemberAttributeConverter

  1. //------------------------------------------------------------------------------
  2. // <copyright file="CSharpCodeProvider.cs" company="Microsoft">
  3. //
  4. // Copyright (c) 2006 Microsoft Corporation. All rights reserved.
  5. //
  6. // The use and distribution terms for this software are contained in the file
  7. // named license.txt, which can be found in the root of this distribution.
  8. // By using this software in any fashion, you are agreeing to be bound by the
  9. // terms of this license.
  10. //
  11. // You must not remove this notice, or any other, from this software.
  12. //
  13. // </copyright>
  14. //------------------------------------------------------------------------------
  15. namespace Microsoft.CSharp
  16. {
  17.    
  18.     using System.Diagnostics;
  19.     using System;
  20.     using System.IO;
  21.     using System.Collections;
  22.     using System.Collections.Specialized;
  23.     using System.ComponentModel;
  24.     using System.Reflection;
  25.     using System.CodeDom;
  26.     using System.CodeDom.Compiler;
  27.     using System.Text;
  28.     using System.Text.RegularExpressions;
  29.     using System.Globalization;
  30.     using System.Security.Permissions;
  31.     using System.Security.Principal;
  32.    
  33.     /// <devdoc>
  34.     /// <para>[To be supplied.]</para>
  35.     /// </devdoc>
  36.     [PermissionSet(SecurityAction.LinkDemand, Name = "FullTrust")]
  37.     [PermissionSet(SecurityAction.InheritanceDemand, Name = "FullTrust")]
  38.     public class CSharpCodeProvider : CodeDomProvider
  39.     {
  40.         private CSharpCodeGenerator generator = new CSharpCodeGenerator();
  41.        
  42.         /// <devdoc>
  43.         /// <para>Retrieves the default extension to use when saving files using this code dom provider.</para>
  44.         /// </devdoc>
  45.         public override string FileExtension {
  46.             get { return "cs"; }
  47.         }
  48.        
  49.         [Obsolete("Callers should not use the ICodeGenerator interface and should instead use the methods directly on the CodeDomProvider class.")]
  50.         public override ICodeGenerator CreateGenerator()
  51.         {
  52.             return (ICodeGenerator)generator;
  53.         }
  54.        
  55.         [Obsolete("Callers should not use the ICodeCompiler interface and should instead use the methods directly on the CodeDomProvider class.")]
  56.         public override ICodeCompiler CreateCompiler()
  57.         {
  58.             return (ICodeCompiler)generator;
  59.         }
  60.        
  61.         /// <devdoc>
  62.         /// This method allows a code dom provider implementation to provide a different type converter
  63.         /// for a given data type. At design time, a designer may pass data types through this
  64.         /// method to see if the code dom provider wants to provide an additional converter.
  65.         /// A typical way this would be used is if the language this code dom provider implements
  66.         /// does not support all of the values of the MemberAttributes enumeration, or if the language
  67.         /// uses different names (Protected instead of Family, for example). The default
  68.         /// implementation just calls TypeDescriptor.GetConverter for the given type.
  69.         /// </devdoc>
  70.         public override TypeConverter GetConverter(Type type)
  71.         {
  72.             if (type == typeof(MemberAttributes)) {
  73.                 return CSharpMemberAttributeConverter.Default;
  74.             }
  75.             else if (type == typeof(TypeAttributes)) {
  76.                 return CSharpTypeAttributeConverter.Default;
  77.             }
  78.            
  79.             return base.GetConverter(type);
  80.         }
  81.        
  82.         public override void GenerateCodeFromMember(CodeTypeMember member, TextWriter writer, CodeGeneratorOptions options)
  83.         {
  84.             generator.GenerateCodeFromMember(member, writer, options);
  85.         }
  86.        
  87.     }
  88.    
  89.     /// <devdoc>
  90.     /// <para>
  91.     /// C# (C Sharp) Code Generator.
  92.     /// </para>
  93.     /// </devdoc>
  94.     internal class CSharpCodeGenerator : ICodeCompiler, ICodeGenerator
  95.     {
  96.         private IndentedTextWriter output;
  97.         private CodeGeneratorOptions options;
  98.         private CodeTypeDeclaration currentClass;
  99.         private CodeTypeMember currentMember;
  100.         private bool inNestedBinary = false;
  101.        
  102.         private const int ParameterMultilineThreshold = 15;
  103.         private const int MaxLineLength = 80;
  104.         private const GeneratorSupport LanguageSupport = GeneratorSupport.ArraysOfArrays | GeneratorSupport.EntryPointMethod | GeneratorSupport.GotoStatements | GeneratorSupport.MultidimensionalArrays | GeneratorSupport.StaticConstructors | GeneratorSupport.TryCatchStatements | GeneratorSupport.ReturnTypeAttributes | GeneratorSupport.AssemblyAttributes | GeneratorSupport.DeclareValueTypes | GeneratorSupport.DeclareEnums | GeneratorSupport.DeclareEvents | GeneratorSupport.DeclareDelegates | GeneratorSupport.DeclareInterfaces | GeneratorSupport.ParameterAttributes | GeneratorSupport.ReferenceParameters | GeneratorSupport.ChainedConstructorArguments | GeneratorSupport.NestedTypes | GeneratorSupport.MultipleInterfaceMembers | GeneratorSupport.PublicStaticMembers | GeneratorSupport.ComplexExpressions | GeneratorSupport.Resources | GeneratorSupport.PartialTypes | GeneratorSupport.GenericTypeReference | GeneratorSupport.GenericTypeDeclaration | GeneratorSupport.DeclareIndexerProperties;
  105.         private static Regex outputReg;
  106.        
  107.         private static readonly string[][] keywords = new string[][] {null, new string[] {"as", "do", "if", "in", "is"}, new string[] {"for", "int", "new", "out", "ref", "try"}, new string[] {"base", "bool", "byte", "case", "char", "else", "enum", "goto", "lock", "long",
  108.         "null", "this", "true", "uint", "void"}, new string[] {"break", "catch", "class", "const", "event", "false", "fixed", "float", "sbyte", "short",
  109.         "throw", "ulong", "using", "where", "while", "yield"}, new string[] {"double", "extern", "object", "params", "public", "return", "sealed", "sizeof", "static", "string",
  110.         "struct", "switch", "typeof", "unsafe", "ushort"}, new string[] {"checked", "decimal", "default", "finally", "foreach", "partial", "private", "virtual"}, new string[] {"abstract", "continue", "delegate", "explicit", "implicit", "internal", "operator", "override", "readonly", "volatile"
  111.         }, new string[] {"__arglist", "__makeref", "__reftype", "interface", "namespace", "protected", "unchecked"}, new string[] {"__refvalue", "stackalloc"}
  112.             // 1 character
  113.             // 2 characters
  114.             // 3 characters
  115.             // 4 characters
  116.             // 5 characters
  117.             // 6 characters
  118.             // 7 characters
  119.             // 8 characters
  120.             // 9 characters
  121.             // 10 characters
  122.         };
  123.        
  124.         #if DEBUG
  125.         static CSharpCodeGenerator()
  126.         {
  127.             FixedStringLookup.VerifyLookupTable(keywords, false);
  128.            
  129.             // Sanity check: try some values;
  130.             Debug.Assert(IsKeyword("for"));
  131.             Debug.Assert(!IsKeyword("foR"));
  132.             Debug.Assert(IsKeyword("operator"));
  133.             Debug.Assert(!IsKeyword("blah"));
  134.         }
  135.         #endif
  136.        
  137.         private bool generatingForLoop = false;
  138.        
  139.         /// <devdoc>
  140.         /// <para>
  141.         /// Gets
  142.         /// or sets the file extension to use for source files.
  143.         /// </para>
  144.         /// </devdoc>
  145.         private string FileExtension {
  146.             get { return ".cs"; }
  147.         }
  148.        
  149.         /// <devdoc>
  150.         /// <para>
  151.         /// Gets or
  152.         /// sets the name of the compiler executable.
  153.         /// </para>
  154.         /// </devdoc>
  155.         #if !PLATFORM_UNIX
  156.         private string CompilerName {
  157.             get { return "csc.exe"; }
  158.         }
  159.         #else // !PLATFORM_UNIX
  160.         private string CompilerName {
  161.             get { return "csc"; }
  162.         }
  163.         #endif // !PLATFORM_UNIX
  164.        
  165.         /// <devdoc>
  166.         /// <para>
  167.         /// Gets or sets the current class name.
  168.         /// </para>
  169.         /// </devdoc>
  170.         private string CurrentTypeName {
  171.             get {
  172.                 if (currentClass != null) {
  173.                     return currentClass.Name;
  174.                 }
  175.                 return "<% unknown %>";
  176.             }
  177.         }
  178.        
  179.         private int Indent {
  180.             get { return output.Indent; }
  181.             set { output.Indent = value; }
  182.         }
  183.        
  184.         /// <devdoc>
  185.         /// <para>
  186.         /// Gets or sets a value indicating whether the current object being
  187.         /// generated is an interface.
  188.         /// </para>
  189.         /// </devdoc>
  190.         private bool IsCurrentInterface {
  191.             get {
  192.                 if (currentClass != null && !(currentClass is CodeTypeDelegate)) {
  193.                     return currentClass.IsInterface;
  194.                 }
  195.                 return false;
  196.             }
  197.         }
  198.        
  199.         /// <devdoc>
  200.         /// <para>
  201.         /// Gets or sets a value indicating whether the current object being generated
  202.         /// is a class.
  203.         /// </para>
  204.         /// </devdoc>
  205.         private bool IsCurrentClass {
  206.             get {
  207.                 if (currentClass != null && !(currentClass is CodeTypeDelegate)) {
  208.                     return currentClass.IsClass;
  209.                 }
  210.                 return false;
  211.             }
  212.         }
  213.        
  214.         /// <devdoc>
  215.         /// <para>
  216.         /// Gets or sets a value indicating whether the current object being generated
  217.         /// is a struct.
  218.         /// </para>
  219.         /// </devdoc>
  220.         private bool IsCurrentStruct {
  221.             get {
  222.                 if (currentClass != null && !(currentClass is CodeTypeDelegate)) {
  223.                     return currentClass.IsStruct;
  224.                 }
  225.                 return false;
  226.             }
  227.         }
  228.        
  229.         /// <devdoc>
  230.         /// <para>
  231.         /// Gets or sets a value indicating whether the current object being generated
  232.         /// is an enumeration.
  233.         /// </para>
  234.         /// </devdoc>
  235.         private bool IsCurrentEnum {
  236.             get {
  237.                 if (currentClass != null && !(currentClass is CodeTypeDelegate)) {
  238.                     return currentClass.IsEnum;
  239.                 }
  240.                 return false;
  241.             }
  242.         }
  243.        
  244.         /// <devdoc>
  245.         /// <para>
  246.         /// Gets or sets a value indicating whether the current object being generated
  247.         /// is a delegate.
  248.         /// </para>
  249.         /// </devdoc>
  250.         private bool IsCurrentDelegate {
  251.             get {
  252.                 if (currentClass != null && currentClass is CodeTypeDelegate) {
  253.                     return true;
  254.                 }
  255.                 return false;
  256.             }
  257.         }
  258.        
  259.         /// <devdoc>
  260.         /// <para>
  261.         /// Gets the token used to represent <see langword='null'/>.
  262.         /// </para>
  263.         /// </devdoc>
  264.         private string NullToken {
  265.             get { return "null"; }
  266.         }
  267.        
  268.         /// <devdoc>
  269.         /// <para>[To be supplied.]</para>
  270.         /// </devdoc>
  271.         private CodeGeneratorOptions Options {
  272.             get { return options; }
  273.         }
  274.        
  275.         private TextWriter Output {
  276.             get { return output; }
  277.         }
  278.        
  279.         /// <devdoc>
  280.         /// <para>
  281.         /// Provides conversion to C-style formatting with escape codes.
  282.         /// </para>
  283.         /// </devdoc>
  284.         private string QuoteSnippetStringCStyle(string value)
  285.         {
  286.             StringBuilder b = new StringBuilder(value.Length + 5);
  287.             Indentation indentObj = new Indentation((IndentedTextWriter)Output, Indent + 1);
  288.            
  289.             b.Append("\"");
  290.            
  291.             int i = 0;
  292.             while (i < value.Length) {
  293.                 switch (value[i]) {
  294.                     case '\r':
  295.                         b.Append("\\r");
  296.                         break;
  297.                     case '\t':
  298.                         b.Append("\\t");
  299.                         break;
  300.                     case '"':
  301.                         b.Append("\\\"");
  302.                         break;
  303.                     case '\'':
  304.                         b.Append("\\'");
  305.                         break;
  306.                     case '\\':
  307.                         b.Append("\\\\");
  308.                         break;
  309.                     case '\0':
  310.                         b.Append("\\0");
  311.                         break;
  312.                     case '\n':
  313.                         b.Append("\\n");
  314.                         break;
  315.                     case '
':
  316.                     case '
':
  317.                         AppendEscapedChar(b, value[i]);
  318.                         break;
  319.                     default:
  320.                        
  321.                         b.Append(value[i]);
  322.                         break;
  323.                 }
  324.                
  325.                 if (i > 0 && i % MaxLineLength == 0) {
  326.                     //
  327.                     // If current character is a high surrogate and the following
  328.                     // character is a low surrogate, don't break them.
  329.                     // Otherwise when we write the string to a file, we might lose
  330.                     // the characters.
  331.                     //
  332.                     if (Char.IsHighSurrogate(value[i]) && (i < value.Length - 1) && Char.IsLowSurrogate(value[i + 1])) {
  333.                         b.Append(value[++i]);
  334.                     }
  335.                    
  336.                     b.Append("\" +\r\n");
  337.                     b.Append(indentObj.IndentationString);
  338.                     b.Append('"');
  339.                 }
  340.                 ++i;
  341.             }
  342.            
  343.             b.Append("\"");
  344.            
  345.             return b.ToString();
  346.         }
  347.        
  348.         private string QuoteSnippetStringVerbatimStyle(string value)
  349.         {
  350.             StringBuilder b = new StringBuilder(value.Length + 5);
  351.            
  352.             b.Append("@\"");
  353.            
  354.             for (int i = 0; i < value.Length; i++) {
  355.                 if (value[i] == '"')
  356.                     b.Append("\"\"");
  357.                 else
  358.                     b.Append(value[i]);
  359.             }
  360.            
  361.             b.Append("\"");
  362.            
  363.             return b.ToString();
  364.         }
  365.        
  366.         /// <devdoc>
  367.         /// <para>
  368.         /// Provides conversion to formatting with escape codes.
  369.         /// </para>
  370.         /// </devdoc>
  371.         private string QuoteSnippetString(string value)
  372.         {
  373.             if (value.Length < 256 || value.Length > 1500 || (value.IndexOf('\0') != -1))
  374.                 return QuoteSnippetStringCStyle(value);
  375.            
  376.             // Otherwise, use 'verbatim' style quoting (e.g. @"foo")
  377.             return QuoteSnippetStringVerbatimStyle(value);
  378.         }
  379.        
  380.         /// <devdoc>
  381.         /// <para>
  382.         /// Processes the <see cref='System.CodeDom.Compiler.CompilerResults'/> returned from compilation.
  383.         /// </para>
  384.         /// </devdoc>
  385.         private void ProcessCompilerOutputLine(CompilerResults results, string line)
  386.         {
  387.             if (outputReg == null)
  388.                 outputReg = new Regex("(^([^(]+)(\\(([0-9]+),([0-9]+)\\))?: )?(error|warning) ([A-Z]+[0-9]+) ?: (.*)");
  389.            
  390.             Match m = outputReg.Match(line);
  391.             if (m.Success) {
  392.                 CompilerError ce = new CompilerError();
  393.                 // The second element is the optional section if the error can be traced to a file.
  394.                 // Without it, the file name is meaningless.
  395.                 if (m.Groups[3].Success) {
  396.                     ce.FileName = m.Groups[2].Value;
  397.                     ce.Line = int.Parse(m.Groups[4].Value, CultureInfo.InvariantCulture);
  398.                     ce.Column = int.Parse(m.Groups[5].Value, CultureInfo.InvariantCulture);
  399.                 }
  400.                 if (string.Compare(m.Groups[6].Value, "warning", StringComparison.OrdinalIgnoreCase) == 0) {
  401.                     ce.IsWarning = true;
  402.                 }
  403.                 ce.ErrorNumber = m.Groups[7].Value;
  404.                 ce.ErrorText = m.Groups[8].Value;
  405.                
  406.                 results.Errors.Add(ce);
  407.             }
  408.         }
  409.        
  410.         /// <devdoc>
  411.         /// <para>
  412.         /// Gets the command arguments from the specified <see cref='System.CodeDom.Compiler.CompilerParameters'/>.
  413.         /// </para>
  414.         /// </devdoc>
  415.         private string CmdArgsFromParameters(CompilerParameters options)
  416.         {
  417.             StringBuilder sb = new StringBuilder(128);
  418.             if (options.GenerateExecutable) {
  419.                 sb.Append("/t:exe ");
  420.                 if (options.MainClass != null && options.MainClass.Length > 0) {
  421.                     sb.Append("/main:");
  422.                     sb.Append(options.MainClass);
  423.                     sb.Append(" ");
  424.                 }
  425.             }
  426.             else {
  427.                 sb.Append("/t:library ");
  428.             }
  429.            
  430.             // Get UTF8 output from the compiler
  431.             sb.Append("/utf8output ");
  432.            
  433.             foreach (string s in options.ReferencedAssemblies) {
  434.                 sb.Append("/R:");
  435.                 sb.Append("\"");
  436.                 sb.Append(s);
  437.                 sb.Append("\"");
  438.                 sb.Append(" ");
  439.             }
  440.            
  441.             sb.Append("/out:");
  442.             sb.Append("\"");
  443.             sb.Append(options.OutputAssembly);
  444.             sb.Append("\"");
  445.             sb.Append(" ");
  446.            
  447.             if (options.IncludeDebugInformation) {
  448.                 sb.Append("/D:DEBUG ");
  449.                 sb.Append("/debug+ ");
  450.                 sb.Append("/optimize- ");
  451.             }
  452.             else {
  453.                 sb.Append("/debug- ");
  454.                 sb.Append("/optimize+ ");
  455.             }
  456.            
  457.            
  458.             foreach (string s in options.EmbeddedResources) {
  459.                 sb.Append("/res:\"");
  460.                 sb.Append(s);
  461.                 sb.Append("\" ");
  462.             }
  463.            
  464.             foreach (string s in options.LinkedResources) {
  465.                 sb.Append("/linkres:\"");
  466.                 sb.Append(s);
  467.                 sb.Append("\" ");
  468.             }
  469.            
  470.             if (options.TreatWarningsAsErrors) {
  471.                 sb.Append("/warnaserror ");
  472.             }
  473.            
  474.             if (options.WarningLevel >= 0) {
  475.                 sb.Append("/w:" + options.WarningLevel + " ");
  476.             }
  477.            
  478.             if (options.CompilerOptions != null) {
  479.                 sb.Append(options.CompilerOptions + " ");
  480.             }
  481.            
  482.             return sb.ToString();
  483.         }
  484.        
  485.         /// <devdoc>
  486.         /// <para>[To be supplied.]</para>
  487.         /// </devdoc>
  488.         private void ContinueOnNewLine(string st)
  489.         {
  490.             Output.WriteLine(st);
  491.         }
  492.        
  493.         /// <devdoc>
  494.         /// <para>[To be supplied.]</para>
  495.         /// </devdoc>
  496.         private string GetResponseFileCmdArgs(CompilerParameters options, string cmdArgs)
  497.         {
  498.            
  499.             string responseFileName = options.TempFiles.AddExtension("cmdline");
  500.            
  501.             Stream temp = new FileStream(responseFileName, FileMode.Create, FileAccess.Write, FileShare.Read);
  502.             try {
  503.                 using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)) {
  504.                     sw.Write(cmdArgs);
  505.                     sw.Flush();
  506.                 }
  507.             }
  508.             finally {
  509.                 temp.Close();
  510.             }
  511.            
  512.             // Always specify the /noconfig flag (outside of the response file)
  513.             return "/noconfig /fullpaths @\"" + responseFileName + "\"";
  514.         }
  515.        
  516.         private void OutputIdentifier(string ident)
  517.         {
  518.             Output.Write(CreateEscapedIdentifier(ident));
  519.         }
  520.        
  521.         /// <devdoc>
  522.         /// <para>
  523.         /// Sets the output type.
  524.         /// </para>
  525.         /// </devdoc>
  526.         private void OutputType(CodeTypeReference typeRef)
  527.         {
  528.             Output.Write(GetTypeOutput(typeRef));
  529.         }
  530.        
  531.        
  532.        
  533.         /// <devdoc>
  534.         /// <para>
  535.         /// Generates code for
  536.         /// the specified CodeDom based array creation expression representation.
  537.         /// </para>
  538.         /// </devdoc>
  539.         private void GenerateArrayCreateExpression(CodeArrayCreateExpression e)
  540.         {
  541.             Output.Write("new ");
  542.            
  543.             CodeExpressionCollection init = e.Initializers;
  544.             if (init.Count > 0) {
  545.                 OutputType(e.CreateType);
  546.                 if (e.CreateType.ArrayRank == 0) {
  547.                     Output.Write("[]");
  548.                 }
  549.                 Output.WriteLine(" {");
  550.                 Indent++;
  551.                     /*newlineBetweenItems*/                OutputExpressionList(init, true);
  552.                 Indent--;
  553.                 Output.Write("}");
  554.             }
  555.             else {
  556.                 Output.Write(GetBaseTypeOutput(e.CreateType));
  557.                
  558.                 Output.Write("[");
  559.                 if (e.SizeExpression != null) {
  560.                     GenerateExpression(e.SizeExpression);
  561.                 }
  562.                 else {
  563.                     Output.Write(e.Size);
  564.                 }
  565.                 Output.Write("]");
  566.             }
  567.         }
  568.         /// <devdoc>
  569.         /// <para>
  570.         /// Generates
  571.         /// code for the specified CodeDom based base reference expression
  572.         /// representation.
  573.         /// </para>
  574.         /// </devdoc>
  575.         private void GenerateBaseReferenceExpression(CodeBaseReferenceExpression e)
  576.         {
  577.             Output.Write("base");
  578.         }
  579.        
  580.         /// <devdoc>
  581.         /// <para>
  582.         /// Generates code for the specified CodeDom based binary operator
  583.         /// expression representation.
  584.         /// </para>
  585.         /// </devdoc>
  586.         private void GenerateBinaryOperatorExpression(CodeBinaryOperatorExpression e)
  587.         {
  588.             bool indentedExpression = false;
  589.             Output.Write("(");
  590.            
  591.             GenerateExpression(e.Left);
  592.             Output.Write(" ");
  593.            
  594.             if (e.Left is CodeBinaryOperatorExpression || e.Right is CodeBinaryOperatorExpression) {
  595.                 // In case the line gets too long with nested binary operators, we need to output them on
  596.                 // different lines. However we want to indent them to maintain readability, but this needs
  597.                 // to be done only once;
  598.                 if (!inNestedBinary) {
  599.                     indentedExpression = true;
  600.                     inNestedBinary = true;
  601.                     Indent += 3;
  602.                 }
  603.                 ContinueOnNewLine("");
  604.             }
  605.            
  606.             OutputOperator(e.Operator);
  607.            
  608.             Output.Write(" ");
  609.             GenerateExpression(e.Right);
  610.            
  611.             Output.Write(")");
  612.             if (indentedExpression) {
  613.                 Indent -= 3;
  614.                 inNestedBinary = false;
  615.             }
  616.         }
  617.        
  618.         /// <devdoc>
  619.         /// <para>
  620.         /// Generates code for the specified CodeDom based cast expression
  621.         /// representation.
  622.         /// </para>
  623.         /// </devdoc>
  624.         private void GenerateCastExpression(CodeCastExpression e)
  625.         {
  626.             Output.Write("((");
  627.             OutputType(e.TargetType);
  628.             Output.Write(")(");
  629.             GenerateExpression(e.Expression);
  630.             Output.Write("))");
  631.         }
  632.        
  633.         public void GenerateCodeFromMember(CodeTypeMember member, TextWriter writer, CodeGeneratorOptions options)
  634.         {
  635.             if (this.output != null) {
  636.                 throw new InvalidOperationException(SR.GetString(SR.CodeGenReentrance));
  637.             }
  638.             this.options = (options == null) ? new CodeGeneratorOptions() : options;
  639.             this.output = new IndentedTextWriter(writer, this.options.IndentString);
  640.            
  641.             try {
  642.                 CodeTypeDeclaration dummyClass = new CodeTypeDeclaration();
  643.                 this.currentClass = dummyClass;
  644.                 GenerateTypeMember(member, dummyClass);
  645.             }
  646.             finally {
  647.                 this.currentClass = null;
  648.                 this.output = null;
  649.                 this.options = null;
  650.             }
  651.         }
  652.        
  653.         private void GenerateDefaultValueExpression(CodeDefaultValueExpression e)
  654.         {
  655.             Output.Write("default(");
  656.             OutputType(e.Type);
  657.             Output.Write(")");
  658.         }
  659.        
  660.         /// <devdoc>
  661.         /// <para>
  662.         /// Generates code for the specified CodeDom based delegate creation
  663.         /// expression representation.
  664.         /// </para>
  665.         /// </devdoc>
  666.         private void GenerateDelegateCreateExpression(CodeDelegateCreateExpression e)
  667.         {
  668.             Output.Write("new ");
  669.             OutputType(e.DelegateType);
  670.             Output.Write("(");
  671.             GenerateExpression(e.TargetObject);
  672.             Output.Write(".");
  673.             OutputIdentifier(e.MethodName);
  674.             Output.Write(")");
  675.         }
  676.        
  677.         private void GenerateEvents(CodeTypeDeclaration e)
  678.         {
  679.             IEnumerator en = e.Members.GetEnumerator();
  680.             while (en.MoveNext()) {
  681.                 if (en.Current is CodeMemberEvent) {
  682.                     currentMember = (CodeTypeMember)en.Current;
  683.                    
  684.                     if (options.BlankLinesBetweenMembers) {
  685.                         Output.WriteLine();
  686.                     }
  687.                     if (currentMember.StartDirectives.Count > 0) {
  688.                         GenerateDirectives(currentMember.StartDirectives);
  689.                     }
  690.                     GenerateCommentStatements(currentMember.Comments);
  691.                     CodeMemberEvent imp = (CodeMemberEvent)en.Current;
  692.                     if (imp.LinePragma != null)
  693.                         GenerateLinePragmaStart(imp.LinePragma);
  694.                     GenerateEvent(imp, e);
  695.                     if (imp.LinePragma != null)
  696.                         GenerateLinePragmaEnd(imp.LinePragma);
  697.                     if (currentMember.EndDirectives.Count > 0) {
  698.                         GenerateDirectives(currentMember.EndDirectives);
  699.                     }
  700.                 }
  701.             }
  702.         }
  703.        
  704.        
  705.         private void GenerateFields(CodeTypeDeclaration e)
  706.         {
  707.             IEnumerator en = e.Members.GetEnumerator();
  708.             while (en.MoveNext()) {
  709.                 if (en.Current is CodeMemberField) {
  710.                     currentMember = (CodeTypeMember)en.Current;
  711.                    
  712.                     if (options.BlankLinesBetweenMembers) {
  713.                         Output.WriteLine();
  714.                     }
  715.                     if (currentMember.StartDirectives.Count > 0) {
  716.                         GenerateDirectives(currentMember.StartDirectives);
  717.                     }
  718.                     GenerateCommentStatements(currentMember.Comments);
  719.                     CodeMemberField imp = (CodeMemberField)en.Current;
  720.                     if (imp.LinePragma != null)
  721.                         GenerateLinePragmaStart(imp.LinePragma);
  722.                     GenerateField(imp);
  723.                     if (imp.LinePragma != null)
  724.                         GenerateLinePragmaEnd(imp.LinePragma);
  725.                     if (currentMember.EndDirectives.Count > 0) {
  726.                         GenerateDirectives(currentMember.EndDirectives);
  727.                     }
  728.                 }
  729.             }
  730.         }
  731.        
  732.         /// <devdoc>
  733.         /// <para>
  734.         /// Generates code for the specified CodeDom based field reference expression
  735.         /// representation.
  736.         /// </para>
  737.         /// </devdoc>
  738.         private void GenerateFieldReferenceExpression(CodeFieldReferenceExpression e)
  739.         {
  740.             if (e.TargetObject != null) {
  741.                 GenerateExpression(e.TargetObject);
  742.                 Output.Write(".");
  743.             }
  744.             OutputIdentifier(e.FieldName);
  745.         }
  746.        
  747.         private void GenerateArgumentReferenceExpression(CodeArgumentReferenceExpression e)
  748.         {
  749.             OutputIdentifier(e.ParameterName);
  750.         }
  751.        
  752.         private void GenerateVariableReferenceExpression(CodeVariableReferenceExpression e)
  753.         {
  754.             OutputIdentifier(e.VariableName);
  755.         }
  756.        
  757.         /// <devdoc>
  758.         /// <para>
  759.         /// Generates code for the specified CodeDom based indexer expression
  760.         /// representation.
  761.         /// </para>
  762.         /// </devdoc>
  763.         private void GenerateIndexerExpression(CodeIndexerExpression e)
  764.         {
  765.             GenerateExpression(e.TargetObject);
  766.             Output.Write("[");
  767.             bool first = true;
  768.             foreach (CodeExpression exp in e.Indices) {
  769.                 if (first) {
  770.                     first = false;
  771.                 }
  772.                 else {
  773.                     Output.Write(", ");
  774.                 }
  775.                 GenerateExpression(exp);
  776.             }
  777.             Output.Write("]");
  778.            
  779.         }
  780.        
  781.         private void GenerateArrayIndexerExpression(CodeArrayIndexerExpression e)
  782.         {
  783.             GenerateExpression(e.TargetObject);
  784.             Output.Write("[");
  785.             bool first = true;
  786.             foreach (CodeExpression exp in e.Indices) {
  787.                 if (first) {
  788.                     first = false;
  789.                 }
  790.                 else {
  791.                     Output.Write(", ");
  792.                 }
  793.                 GenerateExpression(exp);
  794.             }
  795.             Output.Write("]");
  796.            
  797.         }
  798.        
  799.         /// <devdoc>
  800.         /// <para> Generates code for the specified snippet code block
  801.         /// </para>
  802.         /// </devdoc>
  803.         private void GenerateSnippetCompileUnit(CodeSnippetCompileUnit e)
  804.         {
  805.            
  806.             GenerateDirectives(e.StartDirectives);
  807.            
  808.             if (e.LinePragma != null)
  809.                 GenerateLinePragmaStart(e.LinePragma);
  810.             Output.WriteLine(e.Value);
  811.             if (e.LinePragma != null)
  812.                 GenerateLinePragmaEnd(e.LinePragma);
  813.            
  814.             if (e.EndDirectives.Count > 0) {
  815.                 GenerateDirectives(e.EndDirectives);
  816.             }
  817.         }
  818.        
  819.         /// <devdoc>
  820.         /// <para>
  821.         /// Generates code for the specified CodeDom based snippet expression
  822.         /// representation.
  823.         /// </para>
  824.         /// </devdoc>
  825.         private void GenerateSnippetExpression(CodeSnippetExpression e)
  826.         {
  827.             Output.Write(e.Value);
  828.         }
  829.         /// <devdoc>
  830.         /// <para>
  831.         /// Generates code for the specified CodeDom based method invoke expression
  832.         /// representation.
  833.         /// </para>
  834.         /// </devdoc>
  835.         private void GenerateMethodInvokeExpression(CodeMethodInvokeExpression e)
  836.         {
  837.             GenerateMethodReferenceExpression(e.Method);
  838.             Output.Write("(");
  839.             OutputExpressionList(e.Parameters);
  840.             Output.Write(")");
  841.         }
  842.        
  843.         private void GenerateMethodReferenceExpression(CodeMethodReferenceExpression e)
  844.         {
  845.             if (e.TargetObject != null) {
  846.                 if (e.TargetObject is CodeBinaryOperatorExpression) {
  847.                     Output.Write("(");
  848.                     GenerateExpression(e.TargetObject);
  849.                     Output.Write(")");
  850.                 }
  851.                 else {
  852.                     GenerateExpression(e.TargetObject);
  853.                 }
  854.                 Output.Write(".");
  855.             }
  856.             OutputIdentifier(e.MethodName);
  857.            
  858.             if (e.TypeArguments.Count > 0) {
  859.                 Output.Write(GetTypeArgumentsOutput(e.TypeArguments));
  860.             }
  861.            
  862.         }
  863.        
  864.         private bool GetUserData(CodeObject e, string property, bool defaultValue)
  865.         {
  866.             object o = e.UserData[property];
  867.             if (o != null && o is bool) {
  868.                 return (bool)o;
  869.             }
  870.             return defaultValue;
  871.         }
  872.        
  873.         private void GenerateNamespace(CodeNamespace e)
  874.         {
  875.             GenerateCommentStatements(e.Comments);
  876.             GenerateNamespaceStart(e);
  877.            
  878.             if (GetUserData(e, "GenerateImports", true)) {
  879.                 GenerateNamespaceImports(e);
  880.             }
  881.            
  882.             Output.WriteLine("");
  883.            
  884.             GenerateTypes(e);
  885.             GenerateNamespaceEnd(e);
  886.         }
  887.        
  888.         /// <devdoc>
  889.         /// <para>
  890.         /// Generates code for
  891.         /// the specified CodeDom based statement representation.
  892.         /// </para>
  893.         /// </devdoc>
  894.         private void GenerateStatement(CodeStatement e)
  895.         {
  896.             if (e.StartDirectives.Count > 0) {
  897.                 GenerateDirectives(e.StartDirectives);
  898.             }
  899.            
  900.             if (e.LinePragma != null) {
  901.                 GenerateLinePragmaStart(e.LinePragma);
  902.             }
  903.            
  904.             if (e is CodeCommentStatement) {
  905.                 GenerateCommentStatement((CodeCommentStatement)e);
  906.             }
  907.             else if (e is CodeMethodReturnStatement) {
  908.                 GenerateMethodReturnStatement((CodeMethodReturnStatement)e);
  909.             }
  910.             else if (e is CodeConditionStatement) {
  911.                 GenerateConditionStatement((CodeConditionStatement)e);
  912.             }
  913.             else if (e is CodeTryCatchFinallyStatement) {
  914.                 GenerateTryCatchFinallyStatement((CodeTryCatchFinallyStatement)e);
  915.             }
  916.             else if (e is CodeAssignStatement) {
  917.                 GenerateAssignStatement((CodeAssignStatement)e);
  918.             }
  919.             else if (e is CodeExpressionStatement) {
  920.                 GenerateExpressionStatement((CodeExpressionStatement)e);
  921.             }
  922.             else if (e is CodeIterationStatement) {
  923.                 GenerateIterationStatement((CodeIterationStatement)e);
  924.             }
  925.             else if (e is CodeThrowExceptionStatement) {
  926.                 GenerateThrowExceptionStatement((CodeThrowExceptionStatement)e);
  927.             }
  928.             else if (e is CodeSnippetStatement) {
  929.                 // Don't indent snippet statements, in order to preserve the column
  930.                 // information from the original code. This improves the debugging
  931.                 // experience.
  932.                 int savedIndent = Indent;
  933.                 Indent = 0;
  934.                
  935.                 GenerateSnippetStatement((CodeSnippetStatement)e);
  936.                
  937.                 // Restore the indent
  938.                 Indent = savedIndent;
  939.             }
  940.             else if (e is CodeVariableDeclarationStatement) {
  941.                 GenerateVariableDeclarationStatement((CodeVariableDeclarationStatement)e);
  942.             }
  943.             else if (e is CodeAttachEventStatement) {
  944.                 GenerateAttachEventStatement((CodeAttachEventStatement)e);
  945.             }
  946.             else if (e is CodeRemoveEventStatement) {
  947.                 GenerateRemoveEventStatement((CodeRemoveEventStatement)e);
  948.             }
  949.             else if (e is CodeGotoStatement) {
  950.                 GenerateGotoStatement((CodeGotoStatement)e);
  951.             }
  952.             else if (e is CodeLabeledStatement) {
  953.                 GenerateLabeledStatement((CodeLabeledStatement)e);
  954.             }
  955.             else {
  956.                 throw new ArgumentException(SR.GetString(SR.InvalidElementType, e.GetType().FullName), "e");
  957.             }
  958.            
  959.             if (e.LinePragma != null) {
  960.                 GenerateLinePragmaEnd(e.LinePragma);
  961.             }
  962.             if (e.EndDirectives.Count > 0) {
  963.                 GenerateDirectives(e.EndDirectives);
  964.             }
  965.         }
  966.        
  967.         /// <devdoc>
  968.         /// <para>
  969.         /// Generates code for the specified CodeDom based statement representations.
  970.         /// </para>
  971.         /// </devdoc>
  972.         private void GenerateStatements(CodeStatementCollection stms)
  973.         {
  974.             IEnumerator en = stms.GetEnumerator();
  975.             while (en.MoveNext()) {
  976.                 ((ICodeGenerator)this).GenerateCodeFromStatement((CodeStatement)en.Current, output.InnerWriter, options);
  977.             }
  978.         }
  979.        
  980.         /// <devdoc>
  981.         /// <para>
  982.         /// Generates code for the specified CodeDom based namespace import
  983.         /// representation.
  984.         /// </para>
  985.         /// </devdoc>
  986.         private void GenerateNamespaceImports(CodeNamespace e)
  987.         {
  988.             IEnumerator en = e.Imports.GetEnumerator();
  989.             while (en.MoveNext()) {
  990.                 CodeNamespaceImport imp = (CodeNamespaceImport)en.Current;
  991.                 if (imp.LinePragma != null)
  992.                     GenerateLinePragmaStart(imp.LinePragma);
  993.                 GenerateNamespaceImport(imp);
  994.                 if (imp.LinePragma != null)
  995.                     GenerateLinePragmaEnd(imp.LinePragma);
  996.             }
  997.         }
  998.        
  999.         private void GenerateEventReferenceExpression(CodeEventReferenceExpression e)
  1000.         {
  1001.             if (e.TargetObject != null) {
  1002.                 GenerateExpression(e.TargetObject);
  1003.                 Output.Write(".");
  1004.             }
  1005.             OutputIdentifier(e.EventName);
  1006.         }
  1007.        
  1008.         /// <devdoc>
  1009.         /// <para>
  1010.         /// Generates code for the specified CodeDom based delegate invoke
  1011.         /// expression representation.
  1012.         /// </para>
  1013.         /// </devdoc>
  1014.         private void GenerateDelegateInvokeExpression(CodeDelegateInvokeExpression e)
  1015.         {
  1016.             if (e.TargetObject != null) {
  1017.                 GenerateExpression(e.TargetObject);
  1018.             }
  1019.             Output.Write("(");
  1020.             OutputExpressionList(e.Parameters);
  1021.             Output.Write(")");
  1022.         }
  1023.         /// <devdoc>
  1024.         /// <para>
  1025.         /// Generates code for the specified CodeDom based object creation expression
  1026.         /// representation.
  1027.         /// </para>
  1028.         /// </devdoc>
  1029.         private void GenerateObjectCreateExpression(CodeObjectCreateExpression e)
  1030.         {
  1031.             Output.Write("new ");
  1032.             OutputType(e.CreateType);
  1033.             Output.Write("(");
  1034.             OutputExpressionList(e.Parameters);
  1035.             Output.Write(")");
  1036.         }
  1037.        
  1038.         /// <devdoc>
  1039.         /// <para>
  1040.         /// Generates code for the specified CodeDom based primitive expression
  1041.         /// representation.
  1042.         /// </para>
  1043.         /// </devdoc>
  1044.         private void GeneratePrimitiveExpression(CodePrimitiveExpression e)
  1045.         {
  1046.             if (e.Value is char) {
  1047.                 GeneratePrimitiveChar((char)e.Value);
  1048.             }
  1049.             else if (e.Value is sbyte) {
  1050.                 // C# has no literal marker for types smaller than Int32
  1051.                 Output.Write(((sbyte)e.Value).ToString(CultureInfo.InvariantCulture));
  1052.             }
  1053.             else if (e.Value is UInt16) {
  1054.                 // C# has no literal marker for types smaller than Int32, and you will
  1055.                 // get a conversion error if you use "u" here.
  1056.                 Output.Write(((UInt16)e.Value).ToString(CultureInfo.InvariantCulture));
  1057.             }
  1058.             else if (e.Value is UInt32) {
  1059.                 Output.Write(((UInt32)e.Value).ToString(CultureInfo.InvariantCulture));
  1060.                 Output.Write("u");
  1061.             }
  1062.             else if (e.Value is UInt64) {
  1063.                 Output.Write(((UInt64)e.Value).ToString(CultureInfo.InvariantCulture));
  1064.                 Output.Write("ul");
  1065.             }
  1066.             else {
  1067.                 GeneratePrimitiveExpressionBase(e);
  1068.             }
  1069.         }
  1070.        
  1071.         /// <devdoc>
  1072.         /// <para>
  1073.         /// Generates code for the specified CodeDom based primitive expression
  1074.         /// representation.
  1075.         /// </para>
  1076.         /// </devdoc>
  1077.         private void GeneratePrimitiveExpressionBase(CodePrimitiveExpression e)
  1078.         {
  1079.             if (e.Value == null) {
  1080.                 Output.Write(NullToken);
  1081.             }
  1082.             else if (e.Value is string) {
  1083.                 Output.Write(QuoteSnippetString((string)e.Value));
  1084.             }
  1085.             else if (e.Value is char) {
  1086.                 Output.Write("'" + e.Value.ToString() + "'");
  1087.             }
  1088.             else if (e.Value is byte) {
  1089.                 Output.Write(((byte)e.Value).ToString(CultureInfo.InvariantCulture));
  1090.             }
  1091.             else if (e.Value is Int16) {
  1092.                 Output.Write(((Int16)e.Value).ToString(CultureInfo.InvariantCulture));
  1093.             }
  1094.             else if (e.Value is Int32) {
  1095.                 Output.Write(((Int32)e.Value).ToString(CultureInfo.InvariantCulture));
  1096.             }
  1097.             else if (e.Value is Int64) {
  1098.                 Output.Write(((Int64)e.Value).ToString(CultureInfo.InvariantCulture));
  1099.             }
  1100.             else if (e.Value is float) {
  1101.                 GenerateSingleFloatValue((float)e.Value);
  1102.             }
  1103.             else if (e.Value is double) {
  1104.                 GenerateDoubleValue((double)e.Value);
  1105.             }
  1106.             else if (e.Value is decimal) {
  1107.                 GenerateDecimalValue((decimal)e.Value);
  1108.             }
  1109.             else if (e.Value is bool) {
  1110.                 if ((bool)e.Value) {
  1111.                     Output.Write("true");
  1112.                 }
  1113.                 else {
  1114.                     Output.Write("false");
  1115.                 }
  1116.             }
  1117.             else {
  1118.                 throw new ArgumentException(SR.GetString(SR.InvalidPrimitiveType, e.Value.GetType().ToString()));
  1119.             }
  1120.         }
  1121.        
  1122.         private void GeneratePrimitiveChar(char c)
  1123.         {
  1124.             Output.Write('\'');
  1125.             switch (c) {
  1126.                 case '\r':
  1127.                     Output.Write("\\r");
  1128.                     break;
  1129.                 case '\t':
  1130.                     Output.Write("\\t");
  1131.                     break;
  1132.                 case '"':
  1133.                     Output.Write("\\\"");
  1134.                     break;
  1135.                 case '\'':
  1136.                     Output.Write("\\'");
  1137.                     break;
  1138.                 case '\\':
  1139.                     Output.Write("\\\\");
  1140.                     break;
  1141.                 case '\0':
  1142.                     Output.Write("\\0");
  1143.                     break;
  1144.                 case '\n':
  1145.                     Output.Write("\\n");
  1146.                     break;
  1147.                 case '
':
  1148.                 case '
':
  1149.                 case '\u132':
  1150.                 case '\u133':
  1151.                     AppendEscapedChar(null, c);
  1152.                     break;
  1153.                 default:
  1154.                    
  1155.                     if (Char.IsSurrogate(c)) {
  1156.                         AppendEscapedChar(null, c);
  1157.                     }
  1158.                     else {
  1159.                         Output.Write(c);
  1160.                     }
  1161.                     break;
  1162.             }
  1163.             Output.Write('\'');
  1164.         }
  1165.        
  1166.         private void AppendEscapedChar(StringBuilder b, char value)
  1167.         {
  1168.             if (b == null) {
  1169.                 Output.Write("\\u");
  1170.                 Output.Write(((int)value).ToString("X4", CultureInfo.InvariantCulture));
  1171.             }
  1172.             else {
  1173.                 b.Append("\\u");
  1174.                 b.Append(((int)value).ToString("X4", CultureInfo.InvariantCulture));
  1175.             }
  1176.         }
  1177.        
  1178.         private void GeneratePropertySetValueReferenceExpression(CodePropertySetValueReferenceExpression e)
  1179.         {
  1180.             Output.Write("value");
  1181.         }
  1182.        
  1183.         /// <devdoc>
  1184.         /// <para>
  1185.         /// Generates code for the specified CodeDom based this reference expression
  1186.         /// representation.
  1187.         /// </para>
  1188.         /// </devdoc>
  1189.         private void GenerateThisReferenceExpression(CodeThisReferenceExpression e)
  1190.         {
  1191.             Output.Write("this");
  1192.         }
  1193.        
  1194.         /// <devdoc>
  1195.         /// <para>
  1196.         /// Generates code for the specified CodeDom based method invoke statement
  1197.         /// representation.
  1198.         /// </para>
  1199.         /// </devdoc>
  1200.         private void GenerateExpressionStatement(CodeExpressionStatement e)
  1201.         {
  1202.             GenerateExpression(e.Expression);
  1203.             if (!generatingForLoop) {
  1204.                 Output.WriteLine(";");
  1205.             }
  1206.         }
  1207.        
  1208.         /// <devdoc>
  1209.         /// <para>
  1210.         /// Generates code for the specified CodeDom based for loop statement
  1211.         /// representation.
  1212.         /// </para>
  1213.         /// </devdoc>
  1214.         private void GenerateIterationStatement(CodeIterationStatement e)
  1215.         {
  1216.             generatingForLoop = true;
  1217.             Output.Write("for (");
  1218.             GenerateStatement(e.InitStatement);
  1219.             Output.Write("; ");
  1220.             GenerateExpression(e.TestExpression);
  1221.             Output.Write("; ");
  1222.             GenerateStatement(e.IncrementStatement);
  1223.             Output.Write(")");
  1224.             OutputStartingBrace();
  1225.             generatingForLoop = false;
  1226.             Indent++;
  1227.             GenerateStatements(e.Statements);
  1228.             Indent--;
  1229.             Output.WriteLine("}");
  1230.         }
  1231.         /// <devdoc>
  1232.         /// <para>
  1233.         /// Generates code for the specified CodeDom based throw exception statement
  1234.         /// representation.
  1235.         /// </para>
  1236.         /// </devdoc>
  1237.         private void GenerateThrowExceptionStatement(CodeThrowExceptionStatement e)
  1238.         {
  1239.             Output.Write("throw");
  1240.             if (e.ToThrow != null) {
  1241.                 Output.Write(" ");
  1242.                 GenerateExpression(e.ToThrow);
  1243.             }
  1244.             Output.WriteLine(";");
  1245.         }
  1246.        
  1247.         private void GenerateComment(CodeComment e)
  1248.         {
  1249.             string commentLineStart = e.DocComment ? "///" : "//";
  1250.             Output.Write(commentLineStart);
  1251.             Output.Write(" ");
  1252.            
  1253.             string value = e.Text;
  1254.             for (int i = 0; i < value.Length; i++) {
  1255.                 if (value[i] == '\0') {
  1256.                     continue;
  1257.                 }
  1258.                 Output.Write(value[i]);
  1259.                
  1260.                 if (value[i] == '\r') {
  1261.                     if (i < value.Length - 1 && value[i + 1] == '\n') {
  1262.                         // if next char is '\n', skip it
  1263.                         Output.Write('\n');
  1264.                         i++;
  1265.                     }
  1266.                     ((IndentedTextWriter)Output).InternalOutputTabs();
  1267.                     Output.Write(commentLineStart);
  1268.                 }
  1269.                 else if (value[i] == '\n') {
  1270.                     ((IndentedTextWriter)Output).InternalOutputTabs();
  1271.                     Output.Write(commentLineStart);
  1272.                 }
  1273.                 else if (value[i] == '
' || value[i] == '
' || value[i] == '\u133') {
  1274.                     Output.Write(commentLineStart);
  1275.                 }
  1276.             }
  1277.             Output.WriteLine();
  1278.         }
  1279.        
  1280.         /// <devdoc>
  1281.         /// <para>
  1282.         /// Generates code for the specified CodeDom based comment statement
  1283.         /// representation.
  1284.         /// </para>
  1285.         /// </devdoc>
  1286.         private void GenerateCommentStatement(CodeCommentStatement e)
  1287.         {
  1288.             GenerateComment(e.Comment);
  1289.         }
  1290.        
  1291.         /// <devdoc>
  1292.         /// <para>[To be supplied.]</para>
  1293.         /// </devdoc>
  1294.         private void GenerateCommentStatements(CodeCommentStatementCollection e)
  1295.         {
  1296.             foreach (CodeCommentStatement comment in e) {
  1297.                 GenerateCommentStatement(comment);
  1298.             }
  1299.         }
  1300.        
  1301.         /// <devdoc>
  1302.         /// <para>
  1303.         /// Generates code for the specified CodeDom based method return statement
  1304.         /// representation.
  1305.         /// </para>
  1306.         /// </devdoc>
  1307.         private void GenerateMethodReturnStatement(CodeMethodReturnStatement e)
  1308.         {
  1309.             Output.Write("return");
  1310.             if (e.Expression != null) {
  1311.                 Output.Write(" ");
  1312.                 GenerateExpression(e.Expression);
  1313.             }
  1314.             Output.WriteLine(";");
  1315.         }
  1316.         /// <devdoc>
  1317.         /// <para>
  1318.         /// Generates code for the specified CodeDom based if statement
  1319.         /// representation.
  1320.         /// </para>
  1321.         /// </devdoc>
  1322.         private void GenerateConditionStatement(CodeConditionStatement e)
  1323.         {
  1324.             Output.Write("if (");
  1325.             GenerateExpression(e.Condition);
  1326.             Output.Write(")");
  1327.             OutputStartingBrace();
  1328.             Indent++;
  1329.             GenerateStatements(e.TrueStatements);
  1330.             Indent--;
  1331.            
  1332.             CodeStatementCollection falseStatemetns = e.FalseStatements;
  1333.             if (falseStatemetns.Count > 0) {
  1334.                 Output.Write("}");
  1335.                 if (Options.ElseOnClosing) {
  1336.                     Output.Write(" ");
  1337.                 }
  1338.                 else {
  1339.                     Output.WriteLine("");
  1340.                 }
  1341.                 Output.Write("else");
  1342.                 OutputStartingBrace();
  1343.                 Indent++;
  1344.                 GenerateStatements(e.FalseStatements);
  1345.                 Indent--;
  1346.             }
  1347.             Output.WriteLine("}");
  1348.         }
  1349.         /// <devdoc>
  1350.         /// <para>
  1351.         /// Generates code for the specified CodeDom based try catch finally
  1352.         /// statement representation.
  1353.         /// </para>
  1354.         /// </devdoc>
  1355.         private void GenerateTryCatchFinallyStatement(CodeTryCatchFinallyStatement e)
  1356.         {
  1357.             Output.Write("try");
  1358.             OutputStartingBrace();
  1359.             Indent++;
  1360.             GenerateStatements(e.TryStatements);
  1361.             Indent--;
  1362.             CodeCatchClauseCollection catches = e.CatchClauses;
  1363.             if (catches.Count > 0) {
  1364.                 IEnumerator en = catches.GetEnumerator();
  1365.                 while (en.MoveNext()) {
  1366.                     Output.Write("}");
  1367.                     if (Options.ElseOnClosing) {
  1368.                         Output.Write(" ");
  1369.                     }
  1370.                     else {
  1371.                         Output.WriteLine("");
  1372.                     }
  1373.                     CodeCatchClause current = (CodeCatchClause)en.Current;
  1374.                     Output.Write("catch (");
  1375.                     OutputType(current.CatchExceptionType);
  1376.                     Output.Write(" ");
  1377.                     OutputIdentifier(current.LocalName);
  1378.                     Output.Write(")");
  1379.                     OutputStartingBrace();
  1380.                     Indent++;
  1381.                     GenerateStatements(current.Statements);
  1382.                     Indent--;
  1383.                 }
  1384.             }
  1385.            
  1386.             CodeStatementCollection finallyStatements = e.FinallyStatements;
  1387.             if (finallyStatements.Count > 0) {
  1388.                 Output.Write("}");
  1389.                 if (Options.ElseOnClosing) {
  1390.                     Output.Write(" ");
  1391.                 }
  1392.                 else {
  1393.                     Output.WriteLine("");
  1394.                 }
  1395.                 Output.Write("finally");
  1396.                 OutputStartingBrace();
  1397.                 Indent++;
  1398.                 GenerateStatements(finallyStatements);
  1399.                 Indent--;
  1400.             }
  1401.             Output.WriteLine("}");
  1402.         }
  1403.         /// <devdoc>
  1404.         /// <para>
  1405.         /// Generates code for the specified CodeDom based assignment statement
  1406.         /// representation.
  1407.         /// </para>
  1408.         /// </devdoc>
  1409.         private void GenerateAssignStatement(CodeAssignStatement e)
  1410.         {
  1411.             GenerateExpression(e.Left);
  1412.             Output.Write(" = ");
  1413.             GenerateExpression(e.Right);
  1414.             if (!generatingForLoop) {
  1415.                 Output.WriteLine(";");
  1416.             }
  1417.         }
  1418.        
  1419.         /// <devdoc>
  1420.         /// <para>
  1421.         /// Generates code for the specified CodeDom based attach event statement
  1422.         /// representation.
  1423.         /// </para>
  1424.         /// </devdoc>
  1425.         private void GenerateAttachEventStatement(CodeAttachEventStatement e)
  1426.         {
  1427.             GenerateEventReferenceExpression(e.Event);
  1428.             Output.Write(" += ");
  1429.             GenerateExpression(e.Listener);
  1430.             Output.WriteLine(";");
  1431.         }
  1432.        
  1433.         /// <devdoc>
  1434.         /// <para>
  1435.         /// Generates code for the specified CodeDom based detach event statement
  1436.         /// representation.
  1437.         /// </para>
  1438.         /// </devdoc>
  1439.         private void GenerateRemoveEventStatement(CodeRemoveEventStatement e)
  1440.         {
  1441.             GenerateEventReferenceExpression(e.Event);
  1442.             Output.Write(" -= ");
  1443.             GenerateExpression(e.Listener);
  1444.             Output.WriteLine(";");
  1445.         }
  1446.        
  1447.         private void GenerateSnippetStatement(CodeSnippetStatement e)
  1448.         {
  1449.             Output.WriteLine(e.Value);
  1450.         }
  1451.        
  1452.         private void GenerateGotoStatement(CodeGotoStatement e)
  1453.         {
  1454.             Output.Write("goto ");
  1455.             Output.Write(e.Label);
  1456.             Output.WriteLine(";");
  1457.         }
  1458.        
  1459.         private void GenerateLabeledStatement(CodeLabeledStatement e)
  1460.         {
  1461.             Indent--;
  1462.             Output.Write(e.Label);
  1463.             Output.WriteLine(":");
  1464.             Indent++;
  1465.             if (e.Statement != null) {
  1466.                 GenerateStatement(e.Statement);
  1467.             }
  1468.         }
  1469.        
  1470.         /// <devdoc>
  1471.         /// <para>
  1472.         /// Generates code for the specified CodeDom based variable declaration
  1473.         /// statement representation.
  1474.         /// </para>
  1475.         /// </devdoc>
  1476.         private void GenerateVariableDeclarationStatement(CodeVariableDeclarationStatement e)
  1477.         {
  1478.             OutputTypeNamePair(e.Type, e.Name);
  1479.             if (e.InitExpression != null) {
  1480.                 Output.Write(" = ");
  1481.                 GenerateExpression(e.InitExpression);
  1482.             }
  1483.             if (!generatingForLoop) {
  1484.                 Output.WriteLine(";");
  1485.             }
  1486.         }
  1487.         /// <devdoc>
  1488.         /// <para>
  1489.         /// Generates code for the specified CodeDom based line pragma start
  1490.         /// representation.
  1491.         /// </para>
  1492.         /// </devdoc>
  1493.         private void GenerateLinePragmaStart(CodeLinePragma e)
  1494.         {
  1495.             Output.WriteLine("");
  1496.             Output.Write("#line ");
  1497.             Output.Write(e.LineNumber);
  1498.             Output.Write(" \"");
  1499.             Output.Write(e.FileName);
  1500.             Output.Write("\"");
  1501.             Output.WriteLine("");
  1502.         }
  1503.         /// <devdoc>
  1504.         /// <para>
  1505.         /// Generates code for the specified CodeDom based line pragma end
  1506.         /// representation.
  1507.         /// </para>
  1508.         /// </devdoc>
  1509.         private void GenerateLinePragmaEnd(CodeLinePragma e)
  1510.         {
  1511.             Output.WriteLine();
  1512.             Output.WriteLine("#line default");
  1513.             Output.WriteLine("#line hidden");
  1514.         }
  1515.        
  1516.         private void GenerateEvent(CodeMemberEvent e, CodeTypeDeclaration c)
  1517.         {
  1518.             if (IsCurrentDelegate || IsCurrentEnum)
  1519.                 return;
  1520.            
  1521.             if (e.CustomAttributes.Count > 0) {
  1522.                 GenerateAttributes(e.CustomAttributes);
  1523.             }
  1524.            
  1525.             if (e.PrivateImplementationType == null) {
  1526.                 OutputMemberAccessModifier(e.Attributes);
  1527.             }
  1528.             Output.Write("event ");
  1529.             string name = e.Name;
  1530.             if (e.PrivateImplementationType != null) {
  1531.                 name = e.PrivateImplementationType.BaseType + "." + name;
  1532.             }
  1533.             OutputTypeNamePair(e.Type, name);
  1534.             Output.WriteLine(";");
  1535.         }
  1536.        
  1537.         /// <devdoc>
  1538.         /// <para>Generates code for the specified CodeDom code expression representation.</para>
  1539.         /// </devdoc>
  1540.         private void GenerateExpression(CodeExpression e)
  1541.         {
  1542.             if (e is CodeArrayCreateExpression) {
  1543.                 GenerateArrayCreateExpression((CodeArrayCreateExpression)e);
  1544.             }
  1545.             else if (e is CodeBaseReferenceExpression) {
  1546.                 GenerateBaseReferenceExpression((CodeBaseReferenceExpression)e);
  1547.             }
  1548.             else if (e is CodeBinaryOperatorExpression) {
  1549.                 GenerateBinaryOperatorExpression((CodeBinaryOperatorExpression)e);
  1550.             }
  1551.             else if (e is CodeCastExpression) {
  1552.                 GenerateCastExpression((CodeCastExpression)e);
  1553.             }
  1554.             else if (e is CodeDelegateCreateExpression) {
  1555.                 GenerateDelegateCreateExpression((CodeDelegateCreateExpression)e);
  1556.             }
  1557.             else if (e is CodeFieldReferenceExpression) {
  1558.                 GenerateFieldReferenceExpression((CodeFieldReferenceExpression)e);
  1559.             }
  1560.             else if (e is CodeArgumentReferenceExpression) {
  1561.                 GenerateArgumentReferenceExpression((CodeArgumentReferenceExpression)e);
  1562.             }
  1563.             else if (e is CodeVariableReferenceExpression) {
  1564.                 GenerateVariableReferenceExpression((CodeVariableReferenceExpression)e);
  1565.             }
  1566.             else if (e is CodeIndexerExpression) {
  1567.                 GenerateIndexerExpression((CodeIndexerExpression)e);
  1568.             }
  1569.             else if (e is CodeArrayIndexerExpression) {
  1570.                 GenerateArrayIndexerExpression((CodeArrayIndexerExpression)e);
  1571.             }
  1572.             else if (e is CodeSnippetExpression) {
  1573.                 GenerateSnippetExpression((CodeSnippetExpression)e);
  1574.             }
  1575.             else if (e is CodeMethodInvokeExpression) {
  1576.                 GenerateMethodInvokeExpression((CodeMethodInvokeExpression)e);
  1577.             }
  1578.             else if (e is CodeMethodReferenceExpression) {
  1579.                 GenerateMethodReferenceExpression((CodeMethodReferenceExpression)e);
  1580.             }
  1581.             else if (e is CodeEventReferenceExpression) {
  1582.                 GenerateEventReferenceExpression((CodeEventReferenceExpression)e);
  1583.             }
  1584.             else if (e is CodeDelegateInvokeExpression) {
  1585.                 GenerateDelegateInvokeExpression((CodeDelegateInvokeExpression)e);
  1586.             }
  1587.             else if (e is CodeObjectCreateExpression) {
  1588.                 GenerateObjectCreateExpression((CodeObjectCreateExpression)e);
  1589.             }
  1590.             else if (e is CodeParameterDeclarationExpression) {
  1591.                 GenerateParameterDeclarationExpression((CodeParameterDeclarationExpression)e);
  1592.             }
  1593.             else if (e is CodeDirectionExpression) {
  1594.                 GenerateDirectionExpression((CodeDirectionExpression)e);
  1595.             }
  1596.             else if (e is CodePrimitiveExpression) {
  1597.                 GeneratePrimitiveExpression((CodePrimitiveExpression)e);
  1598.             }
  1599.             else if (e is CodePropertyReferenceExpression) {
  1600.                 GeneratePropertyReferenceExpression((CodePropertyReferenceExpression)e);
  1601.             }
  1602.             else if (e is CodePropertySetValueReferenceExpression) {
  1603.                 GeneratePropertySetValueReferenceExpression((CodePropertySetValueReferenceExpression)e);
  1604.             }
  1605.             else if (e is CodeThisReferenceExpression) {
  1606.                 GenerateThisReferenceExpression((CodeThisReferenceExpression)e);
  1607.             }
  1608.             else if (e is CodeTypeReferenceExpression) {
  1609.                 GenerateTypeReferenceExpression((CodeTypeReferenceExpression)e);
  1610.             }
  1611.             else if (e is CodeTypeOfExpression) {
  1612.                 GenerateTypeOfExpression((CodeTypeOfExpression)e);
  1613.             }
  1614.             else if (e is CodeDefaultValueExpression) {
  1615.                 GenerateDefaultValueExpression((CodeDefaultValueExpression)e);
  1616.             }
  1617.             else {
  1618.                 if (e == null) {
  1619.                     throw new ArgumentNullException("e");
  1620.                 }
  1621.                 else {
  1622.                     throw new ArgumentException(SR.GetString(SR.InvalidElementType, e.GetType().FullName), "e");
  1623.                 }
  1624.             }
  1625.         }
  1626.        
  1627.         /// <devdoc>
  1628.         /// <para>
  1629.         /// Generates code for the specified CodeDom
  1630.         /// based field representation.
  1631.         /// </para>
  1632.         /// </devdoc>
  1633.         private void GenerateField(CodeMemberField e)
  1634.         {
  1635.             if (IsCurrentDelegate || IsCurrentInterface)
  1636.                 return;
  1637.            
  1638.             if (IsCurrentEnum) {
  1639.                 if (e.CustomAttributes.Count > 0) {
  1640.                     GenerateAttributes(e.CustomAttributes);
  1641.                 }
  1642.                 OutputIdentifier(e.Name);
  1643.                 if (e.InitExpression != null) {
  1644.                     Output.Write(" = ");
  1645.                     GenerateExpression(e.InitExpression);
  1646.                 }
  1647.                 Output.WriteLine(",");
  1648.             }
  1649.             else {
  1650.                 if (e.CustomAttributes.Count > 0) {
  1651.                     GenerateAttributes(e.CustomAttributes);
  1652.                 }
  1653.                
  1654.                 OutputMemberAccessModifier(e.Attributes);
  1655.                 OutputVTableModifier(e.Attributes);
  1656.                 OutputFieldScopeModifier(e.Attributes);
  1657.                 OutputTypeNamePair(e.Type, e.Name);
  1658.                 if (e.InitExpression != null) {
  1659.                     Output.Write(" = ");
  1660.                     GenerateExpression(e.InitExpression);
  1661.                 }
  1662.                 Output.WriteLine(";");
  1663.             }
  1664.         }
  1665.         /// <devdoc>
  1666.         /// <para>
  1667.         /// Generates code for the specified CodeDom based snippet class member
  1668.         /// representation.
  1669.         /// </para>
  1670.         /// </devdoc>
  1671.         private void GenerateSnippetMember(CodeSnippetTypeMember e)
  1672.         {
  1673.             Output.Write(e.Text);
  1674.         }
  1675.        
  1676.         private void GenerateParameterDeclarationExpression(CodeParameterDeclarationExpression e)
  1677.         {
  1678.             if (e.CustomAttributes.Count > 0) {
  1679.                 // Parameter attributes should be in-line for readability
  1680.                 GenerateAttributes(e.CustomAttributes, null, true);
  1681.             }
  1682.            
  1683.             OutputDirection(e.Direction);
  1684.             OutputTypeNamePair(e.Type, e.Name);
  1685.         }
  1686.        
  1687.         private void GenerateEntryPointMethod(CodeEntryPointMethod e, CodeTypeDeclaration c)
  1688.         {
  1689.            
  1690.             if (e.CustomAttributes.Count > 0) {
  1691.                 GenerateAttributes(e.CustomAttributes);
  1692.             }
  1693.             Output.Write("public static ");
  1694.             OutputType(e.ReturnType);
  1695.             Output.Write(" Main()");
  1696.             OutputStartingBrace();
  1697.             Indent++;
  1698.            
  1699.             GenerateStatements(e.Statements);
  1700.            
  1701.             Indent--;
  1702.             Output.WriteLine("}");
  1703.         }
  1704.        
  1705.         private void GenerateMethods(CodeTypeDeclaration e)
  1706.         {
  1707.             IEnumerator en = e.Members.GetEnumerator();
  1708.             while (en.MoveNext()) {
  1709.                 if (en.Current is CodeMemberMethod && !(en.Current is CodeTypeConstructor) && !(en.Current is CodeConstructor)) {
  1710.                     currentMember = (CodeTypeMember)en.Current;
  1711.                    
  1712.                     if (options.BlankLinesBetweenMembers) {
  1713.                         Output.WriteLine();
  1714.                     }
  1715.                     if (currentMember.StartDirectives.Count > 0) {
  1716.                         GenerateDirectives(currentMember.StartDirectives);
  1717.                     }
  1718.                     GenerateCommentStatements(currentMember.Comments);
  1719.                     CodeMemberMethod imp = (CodeMemberMethod)en.Current;
  1720.                     if (imp.LinePragma != null)
  1721.                         GenerateLinePragmaStart(imp.LinePragma);
  1722.                     if (en.Current is CodeEntryPointMethod) {
  1723.                         GenerateEntryPointMethod((CodeEntryPointMethod)en.Current, e);
  1724.                     }
  1725.                     else {
  1726.                         GenerateMethod(imp, e);
  1727.                     }
  1728.                     if (imp.LinePragma != null)
  1729.                         GenerateLinePragmaEnd(imp.LinePragma);
  1730.                     if (currentMember.EndDirectives.Count > 0) {
  1731.                         GenerateDirectives(currentMember.EndDirectives);
  1732.                     }
  1733.                 }
  1734.             }
  1735.         }
  1736.        
  1737.         /// <devdoc>
  1738.         /// <para>
  1739.         /// Generates code for the specified CodeDom based member method
  1740.         /// representation.
  1741.         /// </para>
  1742.         /// </devdoc>
  1743.         private void GenerateMethod(CodeMemberMethod e, CodeTypeDeclaration c)
  1744.         {
  1745.             if (!(IsCurrentClass || IsCurrentStruct || IsCurrentInterface))
  1746.                 return;
  1747.            
  1748.             if (e.CustomAttributes.Count > 0) {
  1749.                 GenerateAttributes(e.CustomAttributes);
  1750.             }
  1751.             if (e.ReturnTypeCustomAttributes.Count > 0) {
  1752.                 GenerateAttributes(e.ReturnTypeCustomAttributes, "return: ");
  1753.             }
  1754.            
  1755.             if (!IsCurrentInterface) {
  1756.                 if (e.PrivateImplementationType == null) {
  1757.                     OutputMemberAccessModifier(e.Attributes);
  1758.                     OutputVTableModifier(e.Attributes);
  1759.                     OutputMemberScopeModifier(e.Attributes);
  1760.                 }
  1761.             }
  1762.             else {
  1763.                 // interfaces still need "new"
  1764.                 OutputVTableModifier(e.Attributes);
  1765.             }
  1766.             OutputType(e.ReturnType);
  1767.             Output.Write(" ");
  1768.             if (e.PrivateImplementationType != null) {
  1769.                 Output.Write(e.PrivateImplementationType.BaseType);
  1770.                 Output.Write(".");
  1771.             }
  1772.             OutputIdentifier(e.Name);
  1773.            
  1774.             OutputTypeParameters(e.TypeParameters);
  1775.            
  1776.             Output.Write("(");
  1777.             OutputParameters(e.Parameters);
  1778.             Output.Write(")");
  1779.            
  1780.             OutputTypeParameterConstraints(e.TypeParameters);
  1781.            
  1782.             if (!IsCurrentInterface && (e.Attributes & MemberAttributes.ScopeMask) != MemberAttributes.Abstract) {
  1783.                
  1784.                 OutputStartingBrace();
  1785.                 Indent++;
  1786.                
  1787.                 GenerateStatements(e.Statements);
  1788.                
  1789.                 Indent--;
  1790.                 Output.WriteLine("}");
  1791.             }
  1792.             else {
  1793.                 Output.WriteLine(";");
  1794.             }
  1795.         }
  1796.        
  1797.         private void GenerateProperties(CodeTypeDeclaration e)
  1798.         {
  1799.             IEnumerator en = e.Members.GetEnumerator();
  1800.             while (en.MoveNext()) {
  1801.                 if (en.Current is CodeMemberProperty) {
  1802.                     currentMember = (CodeTypeMember)en.Current;
  1803.                    
  1804.                     if (options.BlankLinesBetweenMembers) {
  1805.                         Output.WriteLine();
  1806.                     }
  1807.                     if (currentMember.StartDirectives.Count > 0) {
  1808.                         GenerateDirectives(currentMember.StartDirectives);
  1809.                     }
  1810.                     GenerateCommentStatements(currentMember.Comments);
  1811.                     CodeMemberProperty imp = (CodeMemberProperty)en.Current;
  1812.                     if (imp.LinePragma != null)
  1813.                         GenerateLinePragmaStart(imp.LinePragma);
  1814.                     GenerateProperty(imp, e);
  1815.                     if (imp.LinePragma != null)
  1816.                         GenerateLinePragmaEnd(imp.LinePragma);
  1817.                     if (currentMember.EndDirectives.Count > 0) {
  1818.                         GenerateDirectives(currentMember.EndDirectives);
  1819.                     }
  1820.                 }
  1821.             }
  1822.         }
  1823.        
  1824.         /// <devdoc>
  1825.         /// <para>
  1826.         /// Generates code for the specified CodeDom based property representation.
  1827.         /// </para>
  1828.         /// </devdoc>
  1829.         private void GenerateProperty(CodeMemberProperty e, CodeTypeDeclaration c)
  1830.         {
  1831.             if (!(IsCurrentClass || IsCurrentStruct || IsCurrentInterface))
  1832.                 return;
  1833.            
  1834.             if (e.CustomAttributes.Count > 0) {
  1835.                 GenerateAttributes(e.CustomAttributes);
  1836.             }
  1837.            
  1838.             if (!IsCurrentInterface) {
  1839.                 if (e.PrivateImplementationType == null) {
  1840.                     OutputMemberAccessModifier(e.Attributes);
  1841.                     OutputVTableModifier(e.Attributes);
  1842.                     OutputMemberScopeModifier(e.Attributes);
  1843.                 }
  1844.             }
  1845.             else {
  1846.                 OutputVTableModifier(e.Attributes);
  1847.             }
  1848.             OutputType(e.Type);
  1849.             Output.Write(" ");
  1850.            
  1851.             if (e.PrivateImplementationType != null && !IsCurrentInterface) {
  1852.                 Output.Write(e.PrivateImplementationType.BaseType);
  1853.                 Output.Write(".");
  1854.             }
  1855.            
  1856.             if (e.Parameters.Count > 0 && String.Compare(e.Name, "Item", StringComparison.OrdinalIgnoreCase) == 0) {
  1857.                 Output.Write("this[");
  1858.                 OutputParameters(e.Parameters);
  1859.                 Output.Write("]");
  1860.             }
  1861.             else {
  1862.                 OutputIdentifier(e.Name);
  1863.             }
  1864.            
  1865.             OutputStartingBrace();
  1866.             Indent++;
  1867.            
  1868.             if (e.HasGet) {
  1869.                 if (IsCurrentInterface || (e.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract) {
  1870.                     Output.WriteLine("get;");
  1871.                 }
  1872.                 else {
  1873.                     Output.Write("get");
  1874.                     OutputStartingBrace();
  1875.                     Indent++;
  1876.                     GenerateStatements(e.GetStatements);
  1877.                     Indent--;
  1878.                     Output.WriteLine("}");
  1879.                 }
  1880.             }
  1881.             if (e.HasSet) {
  1882.                 if (IsCurrentInterface || (e.Attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract) {
  1883.                     Output.WriteLine("set;");
  1884.                 }
  1885.                 else {
  1886.                     Output.Write("set");
  1887.                     OutputStartingBrace();
  1888.                     Indent++;
  1889.                     GenerateStatements(e.SetStatements);
  1890.                     Indent--;
  1891.                     Output.WriteLine("}");
  1892.                 }
  1893.             }
  1894.            
  1895.             Indent--;
  1896.             Output.WriteLine("}");
  1897.         }
  1898.        
  1899.         private void GenerateSingleFloatValue(float s)
  1900.         {
  1901.             if (float.IsNaN(s)) {
  1902.                 Output.Write("float.NaN");
  1903.             }
  1904.             else if (float.IsNegativeInfinity(s)) {
  1905.                 Output.Write("float.NegativeInfinity");
  1906.             }
  1907.             else if (float.IsPositiveInfinity(s)) {
  1908.                 Output.Write("float.PositiveInfinity");
  1909.             }
  1910.             else {
  1911.                 Output.Write(s.ToString(CultureInfo.InvariantCulture));
  1912.                 Output.Write('F');
  1913.             }
  1914.         }
  1915.        
  1916.         private void GenerateDoubleValue(double d)
  1917.         {
  1918.             if (double.IsNaN(d)) {
  1919.                 Output.Write("double.NaN");
  1920.             }
  1921.             else if (double.IsNegativeInfinity(d)) {
  1922.                 Output.Write("double.NegativeInfinity");
  1923.             }
  1924.             else if (double.IsPositiveInfinity(d)) {
  1925.                 Output.Write("double.PositiveInfinity");
  1926.             }
  1927.             else {
  1928.                 Output.Write(d.ToString("R", CultureInfo.InvariantCulture));
  1929.             }
  1930.         }
  1931.        
  1932.         private void GenerateDecimalValue(decimal d)
  1933.         {
  1934.             Output.Write(d.ToString(CultureInfo.InvariantCulture));
  1935.             Output.Write('m');
  1936.         }
  1937.        
  1938.         private void OutputVTableModifier(MemberAttributes attributes)
  1939.         {
  1940.             switch (attributes & MemberAttributes.VTableMask) {
  1941.                 case MemberAttributes.New:
  1942.                     Output.Write("new ");
  1943.                     break;
  1944.             }
  1945.         }
  1946.        
  1947.         /// <devdoc>
  1948.         /// <para>
  1949.         /// Generates code for the specified member access modifier.
  1950.         /// </para>
  1951.         /// </devdoc>
  1952.         private void OutputMemberAccessModifier(MemberAttributes attributes)
  1953.         {
  1954.             switch (attributes & MemberAttributes.AccessMask) {
  1955.                 case MemberAttributes.Assembly:
  1956.                     Output.Write("internal ");
  1957.                     break;
  1958.                 case MemberAttributes.FamilyAndAssembly:
  1959.                     Output.Write("internal ");
  1960.                     /*FamANDAssem*/break;
  1961.                 case MemberAttributes.Family:
  1962.                     Output.Write("protected ");
  1963.                     break;
  1964.                 case MemberAttributes.FamilyOrAssembly:
  1965.                     Output.Write("protected internal ");
  1966.                     break;
  1967.                 case MemberAttributes.Private:
  1968.                     Output.Write("private ");
  1969.                     break;
  1970.                 case MemberAttributes.Public:
  1971.                     Output.Write("public ");
  1972.                     break;
  1973.             }
  1974.         }
  1975.        
  1976.         private void OutputMemberScopeModifier(MemberAttributes attributes)
  1977.         {
  1978.             switch (attributes & MemberAttributes.ScopeMask) {
  1979.                 case MemberAttributes.Abstract:
  1980.                     Output.Write("abstract ");
  1981.                     break;
  1982.                 case MemberAttributes.Final:
  1983.                     Output.Write("");
  1984.                     break;
  1985.                 case MemberAttributes.Static:
  1986.                     Output.Write("static ");
  1987.                     break;
  1988.                 case MemberAttributes.Override:
  1989.                     Output.Write("override ");
  1990.                     break;
  1991.                 default:
  1992.                     switch (attributes & MemberAttributes.AccessMask) {
  1993.                         case MemberAttributes.Family:
  1994.                         case MemberAttributes.Public:
  1995.                         case MemberAttributes.Assembly:
  1996.                             Output.Write("virtual ");
  1997.                             break;
  1998.                         default:
  1999.                             // nothing;
  2000.                             break;
  2001.                     }
  2002.                     break;
  2003.             }
  2004.         }
  2005.        
  2006.         /// <devdoc>
  2007.         /// <para>
  2008.         /// Generates code for the specified operator.
  2009.         /// </para>
  2010.         /// </devdoc>
  2011.         private void OutputOperator(CodeBinaryOperatorType op)
  2012.         {
  2013.             switch (op) {
  2014.                 case CodeBinaryOperatorType.Add:
  2015.                     Output.Write("+");
  2016.                     break;
  2017.                 case CodeBinaryOperatorType.Subtract:
  2018.                     Output.Write("-");
  2019.                     break;
  2020.                 case CodeBinaryOperatorType.Multiply:
  2021.                     Output.Write("*");
  2022.                     break;
  2023.                 case CodeBinaryOperatorType.Divide:
  2024.                     Output.Write("/");
  2025.                     break;
  2026.                 case CodeBinaryOperatorType.Modulus:
  2027.                     Output.Write("%");
  2028.                     break;
  2029.                 case CodeBinaryOperatorType.Assign:
  2030.                     Output.Write("=");
  2031.                     break;
  2032.                 case CodeBinaryOperatorType.IdentityInequality:
  2033.                     Output.Write("!=");
  2034.                     break;
  2035.                 case CodeBinaryOperatorType.IdentityEquality:
  2036.                     Output.Write("==");
  2037.                     break;
  2038.                 case CodeBinaryOperatorType.ValueEquality:
  2039.                     Output.Write("==");
  2040.                     break;
  2041.                 case CodeBinaryOperatorType.BitwiseOr:
  2042.                     Output.Write("|");
  2043.                     break;
  2044.                 case CodeBinaryOperatorType.BitwiseAnd:
  2045.                     Output.Write("&");
  2046.                     break;
  2047.                 case CodeBinaryOperatorType.BooleanOr:
  2048.                     Output.Write("||");
  2049.                     break;
  2050.                 case CodeBinaryOperatorType.BooleanAnd:
  2051.                     Output.Write("&&");
  2052.                     break;
  2053.                 case CodeBinaryOperatorType.LessThan:
  2054.                     Output.Write("<");
  2055.                     break;
  2056.                 case CodeBinaryOperatorType.LessThanOrEqual:
  2057.                     Output.Write("<=");
  2058.                     break;
  2059.                 case CodeBinaryOperatorType.GreaterThan:
  2060.                     Output.Write(">");
  2061.                     break;
  2062.                 case CodeBinaryOperatorType.GreaterThanOrEqual:
  2063.                     Output.Write(">=");
  2064.                     break;
  2065.             }
  2066.         }
  2067.        
  2068.         private void OutputFieldScopeModifier(MemberAttributes attributes)
  2069.         {
  2070.             switch (attributes & MemberAttributes.ScopeMask) {
  2071.                 case MemberAttributes.Final:
  2072.                     break;
  2073.                 case MemberAttributes.Static:
  2074.                     Output.Write("static ");
  2075.                     break;
  2076.                 case MemberAttributes.Const:
  2077.                     Output.Write("const ");
  2078.                     break;
  2079.                 default:
  2080.                     break;
  2081.             }
  2082.         }
  2083.        
  2084.         /// <devdoc>
  2085.         /// <para>
  2086.         /// Generates code for the specified CodeDom based property reference
  2087.         /// expression representation.
  2088.         /// </para>
  2089.         /// </devdoc>
  2090.         private void GeneratePropertyReferenceExpression(CodePropertyReferenceExpression e)
  2091.         {
  2092.            
  2093.             if (e.TargetObject != null) {
  2094.                 GenerateExpression(e.TargetObject);
  2095.                 Output.Write(".");
  2096.             }
  2097.             OutputIdentifier(e.PropertyName);
  2098.         }
  2099.        
  2100.         private void GenerateConstructors(CodeTypeDeclaration e)
  2101.         {
  2102.             IEnumerator en = e.Members.GetEnumerator();
  2103.             while (en.MoveNext()) {
  2104.                 if (en.Current is CodeConstructor) {
  2105.                     currentMember = (CodeTypeMember)en.Current;
  2106.                    
  2107.                     if (options.BlankLinesBetweenMembers) {
  2108.                         Output.WriteLine();
  2109.                     }
  2110.                     if (currentMember.StartDirectives.Count > 0) {
  2111.                         GenerateDirectives(currentMember.StartDirectives);
  2112.                     }
  2113.                     GenerateCommentStatements(currentMember.Comments);
  2114.                     CodeConstructor imp = (CodeConstructor)en.Current;
  2115.                     if (imp.LinePragma != null)
  2116.                         GenerateLinePragmaStart(imp.LinePragma);
  2117.                     GenerateConstructor(imp, e);
  2118.                     if (imp.LinePragma != null)
  2119.                         GenerateLinePragmaEnd(imp.LinePragma);
  2120.                     if (currentMember.EndDirectives.Count > 0) {
  2121.                         GenerateDirectives(currentMember.EndDirectives);
  2122.                     }
  2123.                 }
  2124.             }
  2125.         }
  2126.        
  2127.         /// <devdoc>
  2128.         /// <para>
  2129.         /// Generates code for the specified CodeDom based constructor
  2130.         /// representation.
  2131.         /// </para>
  2132.         /// </devdoc>
  2133.         private void GenerateConstructor(CodeConstructor e, CodeTypeDeclaration c)
  2134.         {
  2135.             if (!(IsCurrentClass || IsCurrentStruct))
  2136.                 return;
  2137.            
  2138.             if (e.CustomAttributes.Count > 0) {
  2139.                 GenerateAttributes(e.CustomAttributes);
  2140.             }
  2141.            
  2142.             OutputMemberAccessModifier(e.Attributes);
  2143.             OutputIdentifier(CurrentTypeName);
  2144.             Output.Write("(");
  2145.             OutputParameters(e.Parameters);
  2146.             Output.Write(")");
  2147.            
  2148.             CodeExpressionCollection baseArgs = e.BaseConstructorArgs;
  2149.             CodeExpressionCollection thisArgs = e.ChainedConstructorArgs;
  2150.            
  2151.             if (baseArgs.Count > 0) {
  2152.                 Output.WriteLine(" : ");
  2153.                 Indent++;
  2154.                 Indent++;
  2155.                 Output.Write("base(");
  2156.                 OutputExpressionList(baseArgs);
  2157.                 Output.Write(")");
  2158.                 Indent--;
  2159.                 Indent--;
  2160.             }
  2161.            
  2162.             if (thisArgs.Count > 0) {
  2163.                 Output.WriteLine(" : ");
  2164.                 Indent++;
  2165.                 Indent++;
  2166.                 Output.Write("this(");
  2167.                 OutputExpressionList(thisArgs);
  2168.                 Output.Write(")");
  2169.                 Indent--;
  2170.                 Indent--;
  2171.             }
  2172.            
  2173.             OutputStartingBrace();
  2174.             Indent++;
  2175.             GenerateStatements(e.Statements);
  2176.             Indent--;
  2177.             Output.WriteLine("}");
  2178.         }
  2179.         /// <devdoc>
  2180.         /// <para>
  2181.         /// Generates code for the specified CodeDom based class constructor
  2182.         /// representation.
  2183.         /// </para>
  2184.         /// </devdoc>
  2185.         private void GenerateTypeConstructor(CodeTypeConstructor e)
  2186.         {
  2187.             if (!(IsCurrentClass || IsCurrentStruct))
  2188.                 return;
  2189.            
  2190.             if (e.CustomAttributes.Count > 0) {
  2191.                 GenerateAttributes(e.CustomAttributes);
  2192.             }
  2193.             Output.Write("static ");
  2194.             Output.Write(CurrentTypeName);
  2195.             Output.Write("()");
  2196.             OutputStartingBrace();
  2197.             Indent++;
  2198.             GenerateStatements(e.Statements);
  2199.             Indent--;
  2200.             Output.WriteLine("}");
  2201.         }
  2202.        
  2203.         /// <devdoc>
  2204.         /// <para>
  2205.         /// Generates code for the specified CodeDom based type reference expression
  2206.         /// representation.
  2207.         /// </para>
  2208.         /// </devdoc>
  2209.         private void GenerateTypeReferenceExpression(CodeTypeReferenceExpression e)
  2210.         {
  2211.             OutputType(e.Type);
  2212.         }
  2213.        
  2214.         /// <devdoc>
  2215.         /// <para>
  2216.         /// Generates code for the specified CodeDom based type of expression
  2217.         /// representation.
  2218.         /// </para>
  2219.         /// </devdoc>
  2220.         private void GenerateTypeOfExpression(CodeTypeOfExpression e)
  2221.         {
  2222.             Output.Write("typeof(");
  2223.             OutputType(e.Type);
  2224.             Output.Write(")");
  2225.         }
  2226.        
  2227.         private void GenerateType(CodeTypeDeclaration e)
  2228.         {
  2229.             currentClass = e;
  2230.            
  2231.             if (e.StartDirectives.Count > 0) {
  2232.                 GenerateDirectives(e.StartDirectives);
  2233.             }
  2234.            
  2235.             GenerateCommentStatements(e.Comments);
  2236.            
  2237.             if (e.LinePragma != null)
  2238.                 GenerateLinePragmaStart(e.LinePragma);
  2239.            
  2240.             GenerateTypeStart(e);
  2241.            
  2242.             if (Options.VerbatimOrder) {
  2243.                 foreach (CodeTypeMember member in e.Members) {
  2244.                     GenerateTypeMember(member, e);
  2245.                 }
  2246.             }
  2247.             else {
  2248.                
  2249.                 GenerateFields(e);
  2250.                
  2251.                 GenerateSnippetMembers(e);
  2252.                
  2253.                 GenerateTypeConstructors(e);
  2254.                
  2255.                 GenerateConstructors(e);
  2256.                
  2257.                 GenerateProperties(e);
  2258.                
  2259.                 GenerateEvents(e);
  2260.                
  2261.                 GenerateMethods(e);
  2262.                
  2263.                 GenerateNestedTypes(e);
  2264.             }
  2265.             // Nested types clobber the current class, so reset it.
  2266.             currentClass = e;
  2267.            
  2268.             GenerateTypeEnd(e);
  2269.             if (e.LinePragma != null)
  2270.                 GenerateLinePragmaEnd(e.LinePragma);
  2271.            
  2272.             if (e.EndDirectives.Count > 0) {
  2273.                 GenerateDirectives(e.EndDirectives);
  2274.             }
  2275.            
  2276.         }
  2277.        
  2278.         /// <devdoc>
  2279.         /// <para> Generates code for the specified CodeDom namespace representation and the classes it
  2280.         /// contains.</para>
  2281.         /// </devdoc>
  2282.         private void GenerateTypes(CodeNamespace e)
  2283.         {
  2284.             foreach (CodeTypeDeclaration c in e.Types) {
  2285.                 if (options.BlankLinesBetweenMembers) {
  2286.                     Output.WriteLine();
  2287.                 }
  2288.                 ((ICodeGenerator)this).GenerateCodeFromType(c, output.InnerWriter, options);
  2289.             }
  2290.         }
  2291.        
  2292.         /// <devdoc>
  2293.         /// <para>
  2294.         /// Generates code for the specified CodeDom based class start
  2295.         /// representation.
  2296.         /// </para>
  2297.         /// </devdoc>
  2298.         private void GenerateTypeStart(CodeTypeDeclaration e)
  2299.         {
  2300.             if (e.CustomAttributes.Count > 0) {
  2301.                 GenerateAttributes(e.CustomAttributes);
  2302.             }
  2303.            
  2304.             if (IsCurrentDelegate) {
  2305.                 switch (e.TypeAttributes & TypeAttributes.VisibilityMask) {
  2306.                     case TypeAttributes.Public:
  2307.                         Output.Write("public ");
  2308.                         break;
  2309.                     case TypeAttributes.NotPublic:
  2310.                     default:
  2311.                         break;
  2312.                 }
  2313.                
  2314.                 CodeTypeDelegate del = (CodeTypeDelegate)e;
  2315.                 Output.Write("delegate ");
  2316.                 OutputType(del.ReturnType);
  2317.                 Output.Write(" ");
  2318.                 OutputIdentifier(e.Name);
  2319.                 Output.Write("(");
  2320.                 OutputParameters(del.Parameters);
  2321.                 Output.WriteLine(");");
  2322.             }
  2323.             else {
  2324.                 OutputTypeAttributes(e);
  2325.                 OutputIdentifier(e.Name);
  2326.                
  2327.                 OutputTypeParameters(e.TypeParameters);
  2328.                
  2329.                 bool first = true;
  2330.                 foreach (CodeTypeReference typeRef in e.BaseTypes) {
  2331.                     if (first) {
  2332.                         Output.Write(" : ");
  2333.                         first = false;
  2334.                     }
  2335.                     else {
  2336.                         Output.Write(", ");
  2337.                     }
  2338.                     OutputType(typeRef);
  2339.                 }
  2340.                
  2341.                 OutputTypeParameterConstraints(e.TypeParameters);
  2342.                
  2343.                 OutputStartingBrace();
  2344.                 Indent++;
  2345.             }
  2346.         }
  2347.        
  2348.         private void GenerateTypeMember(CodeTypeMember member, CodeTypeDeclaration declaredType)
  2349.         {
  2350.            
  2351.             if (options.BlankLinesBetweenMembers) {
  2352.                 Output.WriteLine();
  2353.             }
  2354.            
  2355.             if (member is CodeTypeDeclaration) {
  2356.                 ((ICodeGenerator)this).GenerateCodeFromType((CodeTypeDeclaration)member, output.InnerWriter, options);
  2357.                
  2358.                 // Nested types clobber the current class, so reset it.
  2359.                 currentClass = declaredType;
  2360.                
  2361.                 // For nested types, comments and line pragmas are handled separately, so return here
  2362.                 return;
  2363.             }
  2364.            
  2365.             if (member.StartDirectives.Count > 0) {
  2366.                 GenerateDirectives(member.StartDirectives);
  2367.             }
  2368.            
  2369.             GenerateCommentStatements(member.Comments);
  2370.            
  2371.             if (member.LinePragma != null) {
  2372.                 GenerateLinePragmaStart(member.LinePragma);
  2373.             }
  2374.            
  2375.             if (member is CodeMemberField) {
  2376.                 GenerateField((CodeMemberField)member);
  2377.             }
  2378.             else if (member is CodeMemberProperty) {
  2379.                 GenerateProperty((CodeMemberProperty)member, declaredType);
  2380.             }
  2381.             else if (member is CodeMemberMethod) {
  2382.                 if (member is CodeConstructor) {
  2383.                     GenerateConstructor((CodeConstructor)member, declaredType);
  2384.                 }
  2385.                 else if (member is CodeTypeConstructor) {
  2386.                     GenerateTypeConstructor((CodeTypeConstructor)member);
  2387.                 }
  2388.                 else if (member is CodeEntryPointMethod) {
  2389.                     GenerateEntryPointMethod((CodeEntryPointMethod)member, declaredType);
  2390.                 }
  2391.                 else {
  2392.                     GenerateMethod((CodeMemberMethod)member, declaredType);
  2393.                 }
  2394.             }
  2395.             else if (member is CodeMemberEvent) {
  2396.                 GenerateEvent((CodeMemberEvent)member, declaredType);
  2397.             }
  2398.             else if (member is CodeSnippetTypeMember) {
  2399.                
  2400.                 // Don't indent snippets, in order to preserve the column
  2401.                 // information from the original code. This improves the debugging
  2402.                 // experience.
  2403.                 int savedIndent = Indent;
  2404.                 Indent = 0;
  2405.                
  2406.                 GenerateSnippetMember((CodeSnippetTypeMember)member);
  2407.                
  2408.                 // Restore the indent
  2409.                 Indent = savedIndent;
  2410.                
  2411.                 // Generate an extra new line at the end of the snippet.
  2412.                 // If the snippet is comment and this type only contains comments.
  2413.                 // The generated code will not compile.
  2414.                 Output.WriteLine();
  2415.             }
  2416.            
  2417.             if (member.LinePragma != null) {
  2418.                 GenerateLinePragmaEnd(member.LinePragma);
  2419.             }
  2420.            
  2421.             if (member.EndDirectives.Count > 0) {
  2422.                 GenerateDirectives(member.EndDirectives);
  2423.             }
  2424.         }
  2425.        
  2426.         private void GenerateTypeConstructors(CodeTypeDeclaration e)
  2427.         {
  2428.             IEnumerator en = e.Members.GetEnumerator();
  2429.             while (en.MoveNext()) {
  2430.                 if (en.Current is CodeTypeConstructor) {
  2431.                     currentMember = (CodeTypeMember)en.Current;
  2432.                    
  2433.                     if (options.BlankLinesBetweenMembers) {
  2434.                         Output.WriteLine();
  2435.                     }
  2436.                     if (currentMember.StartDirectives.Count > 0) {
  2437.                         GenerateDirectives(currentMember.StartDirectives);
  2438.                     }
  2439.                     GenerateCommentStatements(currentMember.Comments);
  2440.                     CodeTypeConstructor imp = (CodeTypeConstructor)en.Current;
  2441.                     if (imp.LinePragma != null)
  2442.                         GenerateLinePragmaStart(imp.LinePragma);
  2443.                     GenerateTypeConstructor(imp);
  2444.                     if (imp.LinePragma != null)
  2445.                         GenerateLinePragmaEnd(imp.LinePragma);
  2446.                     if (currentMember.EndDirectives.Count > 0) {
  2447.                         GenerateDirectives(currentMember.EndDirectives);
  2448.                     }
  2449.                 }
  2450.             }
  2451.         }
  2452.        
  2453.         private void GenerateSnippetMembers(CodeTypeDeclaration e)
  2454.         {
  2455.             IEnumerator en = e.Members.GetEnumerator();
  2456.             bool hasSnippet = false;
  2457.             while (en.MoveNext()) {
  2458.                 if (en.Current is CodeSnippetTypeMember) {
  2459.                     hasSnippet = true;
  2460.                     currentMember = (CodeTypeMember)en.Current;
  2461.                    
  2462.                     if (options.BlankLinesBetweenMembers) {
  2463.                         Output.WriteLine();
  2464.                     }
  2465.                     if (currentMember.StartDirectives.Count > 0) {
  2466.                         GenerateDirectives(currentMember.StartDirectives);
  2467.                     }
  2468.                     GenerateCommentStatements(currentMember.Comments);
  2469.                     CodeSnippetTypeMember imp = (CodeSnippetTypeMember)en.Current;
  2470.                     if (imp.LinePragma != null)
  2471.                         GenerateLinePragmaStart(imp.LinePragma);
  2472.                    
  2473.                     // Don't indent snippets, in order to preserve the column
  2474.                     // information from the original code. This improves the debugging
  2475.                     // experience.
  2476.                     int savedIndent = Indent;
  2477.                     Indent = 0;
  2478.                    
  2479.                     GenerateSnippetMember(imp);
  2480.                    
  2481.                     // Restore the indent
  2482.                     Indent = savedIndent;
  2483.                    
  2484.                     if (imp.LinePragma != null)
  2485.                         GenerateLinePragmaEnd(imp.LinePragma);
  2486.                     if (currentMember.EndDirectives.Count > 0) {
  2487.                         GenerateDirectives(currentMember.EndDirectives);
  2488.                     }
  2489.                    
  2490.                 }
  2491.             }
  2492.             // Generate an extra new line at the end of the snippet.
  2493.             // If the snippet is comment and this type only contains comments.
  2494.             // The generated code will not compile.
  2495.             if (hasSnippet) {
  2496.                 Output.WriteLine();
  2497.             }
  2498.         }
  2499.        
  2500.         private void GenerateNestedTypes(CodeTypeDeclaration e)
  2501.         {
  2502.             IEnumerator en = e.Members.GetEnumerator();
  2503.             while (en.MoveNext()) {
  2504.                 if (en.Current is CodeTypeDeclaration) {
  2505.                     if (options.BlankLinesBetweenMembers) {
  2506.                         Output.WriteLine();
  2507.                     }
  2508.                     CodeTypeDeclaration currentClass = (CodeTypeDeclaration)en.Current;
  2509.                     ((ICodeGenerator)this).GenerateCodeFromType(currentClass, output.InnerWriter, options);
  2510.                 }
  2511.             }
  2512.         }
  2513.        
  2514.         /// <devdoc>
  2515.         /// <para> Generates code for the namepsaces in the specifield CodeDom compile unit.
  2516.         /// </para>
  2517.         /// </devdoc>
  2518.         private void GenerateNamespaces(CodeCompileUnit e)
  2519.         {
  2520.             foreach (CodeNamespace n in e.Namespaces) {
  2521.                 ((ICodeGenerator)this).GenerateCodeFromNamespace(n, output.InnerWriter, options);
  2522.             }
  2523.         }
  2524.        
  2525.        
  2526.        
  2527.         /// <devdoc>
  2528.         /// <para>
  2529.         /// Outputs an argument in a attribute block.
  2530.         /// </para>
  2531.         /// </devdoc>
  2532.         private void OutputAttributeArgument(CodeAttributeArgument arg)
  2533.         {
  2534.             if (arg.Name != null && arg.Name.Length > 0) {
  2535.                 OutputIdentifier(arg.Name);
  2536.                 Output.Write("=");
  2537.             }
  2538.             ((ICodeGenerator)this).GenerateCodeFromExpression(arg.Value, output.InnerWriter, options);
  2539.         }
  2540.        
  2541.         /// <devdoc>
  2542.         /// <para>
  2543.         /// Generates code for the specified System.CodeDom.FieldDirection.
  2544.         /// </para>
  2545.         /// </devdoc>
  2546.         private void OutputDirection(FieldDirection dir)
  2547.         {
  2548.             switch (dir) {
  2549.                 case FieldDirection.In:
  2550.                     break;
  2551.                 case FieldDirection.Out:
  2552.                     Output.Write("out ");
  2553.                     break;
  2554.                 case FieldDirection.Ref:
  2555.                     Output.Write("ref ");
  2556.                     break;
  2557.             }
  2558.         }
  2559.        
  2560.         /// <devdoc>
  2561.         /// <para>
  2562.         /// Generates code for the specified expression list.
  2563.         /// </para>
  2564.         /// </devdoc>
  2565.         private void OutputExpressionList(CodeExpressionCollection expressions)
  2566.         {
  2567.                 /*newlineBetweenItems*/            OutputExpressionList(expressions, false);
  2568.         }
  2569.        
  2570.         /// <devdoc>
  2571.         /// <para>
  2572.         /// Generates code for the specified expression list.
  2573.         /// </para>
  2574.         /// </devdoc>
  2575.         private void OutputExpressionList(CodeExpressionCollection expressions, bool newlineBetweenItems)
  2576.         {
  2577.             bool first = true;
  2578.             IEnumerator en = expressions.GetEnumerator();
  2579.             Indent++;
  2580.             while (en.MoveNext()) {
  2581.                 if (first) {
  2582.                     first = false;
  2583.                 }
  2584.                 else {
  2585.                     if (newlineBetweenItems)
  2586.                         ContinueOnNewLine(",");
  2587.                     else
  2588.                         Output.Write(", ");
  2589.                 }
  2590.                 ((ICodeGenerator)this).GenerateCodeFromExpression((CodeExpression)en.Current, output.InnerWriter, options);
  2591.             }
  2592.             Indent--;
  2593.         }
  2594.        
  2595.         /// <devdoc>
  2596.         /// <para>
  2597.         /// Generates code for the specified parameters.
  2598.         /// </para>
  2599.         /// </devdoc>
  2600.         private void OutputParameters(CodeParameterDeclarationExpressionCollection parameters)
  2601.         {
  2602.             bool first = true;
  2603.             bool multiline = parameters.Count > ParameterMultilineThreshold;
  2604.             if (multiline) {
  2605.                 Indent += 3;
  2606.             }
  2607.             IEnumerator en = parameters.GetEnumerator();
  2608.             while (en.MoveNext()) {
  2609.                 CodeParameterDeclarationExpression current = (CodeParameterDeclarationExpression)en.Current;
  2610.                 if (first) {
  2611.                     first = false;
  2612.                 }
  2613.                 else {
  2614.                     Output.Write(", ");
  2615.                 }
  2616.                 if (multiline) {
  2617.                     ContinueOnNewLine("");
  2618.                 }
  2619.                 GenerateExpression(current);
  2620.             }
  2621.             if (multiline) {
  2622.                 Indent -= 3;
  2623.             }
  2624.         }
  2625.        
  2626.         /// <devdoc>
  2627.         /// <para>
  2628.         /// Generates code for the specified object type and name pair.
  2629.         /// </para>
  2630.         /// </devdoc>
  2631.         private void OutputTypeNamePair(CodeTypeReference typeRef, string name)
  2632.         {
  2633.             OutputType(typeRef);
  2634.             Output.Write(" ");
  2635.             OutputIdentifier(name);
  2636.         }
  2637.        
  2638.         private void OutputTypeParameters(CodeTypeParameterCollection typeParameters)
  2639.         {
  2640.             if (typeParameters.Count == 0) {
  2641.                 return;
  2642.             }
  2643.            
  2644.             Output.Write('<');
  2645.             bool first = true;
  2646.             for (int i = 0; i < typeParameters.Count; i++) {
  2647.                 if (first) {
  2648.                     first = false;
  2649.                 }
  2650.                 else {
  2651.                     Output.Write(", ");
  2652.                 }
  2653.                
  2654.                 if (typeParameters[i].CustomAttributes.Count > 0) {
  2655.                     GenerateAttributes(typeParameters[i].CustomAttributes, null, true);
  2656.                     Output.Write(' ');
  2657.                 }
  2658.                
  2659.                 Output.Write(typeParameters[i].Name);
  2660.             }
  2661.            
  2662.             Output.Write('>');
  2663.         }
  2664.        
  2665.         private void OutputTypeParameterConstraints(CodeTypeParameterCollection typeParameters)
  2666.         {
  2667.             if (typeParameters.Count == 0) {
  2668.                 return;
  2669.             }
  2670.            
  2671.             for (int i = 0; i < typeParameters.Count; i++) {
  2672.                 // generating something like: "where KeyType: IComparable, IEnumerable"
  2673.                
  2674.                 Output.WriteLine();
  2675.                 Indent++;
  2676.                
  2677.                 bool first = true;
  2678.                 if (typeParameters[i].Constraints.Count > 0) {
  2679.                     foreach (CodeTypeReference typeRef in typeParameters[i].Constraints) {
  2680.                         if (first) {
  2681.                             Output.Write("where ");
  2682.                             Output.Write(typeParameters[i].Name);
  2683.                             Output.Write(" : ");
  2684.                             first = false;
  2685.                         }
  2686.                         else {
  2687.                             Output.Write(", ");
  2688.                         }
  2689.                         OutputType(typeRef);
  2690.                     }
  2691.                 }
  2692.                
  2693.                 if (typeParameters[i].HasConstructorConstraint) {
  2694.                     if (first) {
  2695.                         Output.Write("where ");
  2696.                         Output.Write(typeParameters[i].Name);
  2697.                         Output.Write(" : new()");
  2698.                     }
  2699.                     else {
  2700.                         Output.Write(", new ()");
  2701.                     }
  2702.                 }
  2703.                
  2704.                 Indent--;
  2705.             }
  2706.         }
  2707.        
  2708.        
  2709.         private void OutputTypeAttributes(CodeTypeDeclaration e)
  2710.         {
  2711.             if ((e.Attributes & MemberAttributes.New) != 0) {
  2712.                 Output.Write("new ");
  2713.             }
  2714.            
  2715.             TypeAttributes attributes = e.TypeAttributes;
  2716.             switch (attributes & TypeAttributes.VisibilityMask) {
  2717.                 case TypeAttributes.Public:
  2718.                 case TypeAttributes.NestedPublic:
  2719.                     Output.Write("public ");
  2720.                     break;
  2721.                 case TypeAttributes.NestedPrivate:
  2722.                     Output.Write("private ");
  2723.                     break;
  2724.                 case TypeAttributes.NestedFamily:
  2725.                     Output.Write("protected ");
  2726.                     break;
  2727.                 case TypeAttributes.NotPublic:
  2728.                 case TypeAttributes.NestedAssembly:
  2729.                 case TypeAttributes.NestedFamANDAssem:
  2730.                     Output.Write("internal ");
  2731.                     break;
  2732.                 case TypeAttributes.NestedFamORAssem:
  2733.                     Output.Write("protected internal ");
  2734.                     break;
  2735.             }
  2736.            
  2737.             if (e.IsStruct) {
  2738.                 if (e.IsPartial) {
  2739.                     Output.Write("partial ");
  2740.                 }
  2741.                 Output.Write("struct ");
  2742.             }
  2743.             else if (e.IsEnum) {
  2744.                 Output.Write("enum ");
  2745.             }
  2746.             else {
  2747.                 switch (attributes & TypeAttributes.ClassSemanticsMask) {
  2748.                     case TypeAttributes.Class:
  2749.                         if ((attributes & TypeAttributes.Sealed) == TypeAttributes.Sealed) {
  2750.                             Output.Write("sealed ");
  2751.                         }
  2752.                         if ((attributes & TypeAttributes.Abstract) == TypeAttributes.Abstract) {
  2753.                             Output.Write("abstract ");
  2754.                         }
  2755.                         if (e.IsPartial) {
  2756.                             Output.Write("partial ");
  2757.                         }
  2758.                        
  2759.                         Output.Write("class ");
  2760.                        
  2761.                         break;
  2762.                     case TypeAttributes.Interface:
  2763.                         if (e.IsPartial) {
  2764.                             Output.Write("partial ");
  2765.                         }
  2766.                         Output.Write("interface ");
  2767.                         break;
  2768.                 }
  2769.             }
  2770.         }
  2771.        
  2772.         /// <devdoc>
  2773.         /// <para>
  2774.         /// Generates code for the specified CodeDom based class end representation.
  2775.         /// </para>
  2776.         /// </devdoc>
  2777.         private void GenerateTypeEnd(CodeTypeDeclaration e)
  2778.         {
  2779.             if (!IsCurrentDelegate) {
  2780.                 Indent--;
  2781.                 Output.WriteLine("}");
  2782.             }
  2783.         }
  2784.         /// <devdoc>
  2785.         /// <para>
  2786.         /// Generates code for the specified CodeDom based namespace start
  2787.         /// representation.
  2788.         /// </para>
  2789.         /// </devdoc>
  2790.         private void GenerateNamespaceStart(CodeNamespace e)
  2791.         {
  2792.            
  2793.             if (e.Name != null && e.Name.Length > 0) {
  2794.                 Output.Write("namespace ");
  2795.                 string[] names = e.Name.Split('.');
  2796.                 Debug.Assert(names.Length > 0);
  2797.                 OutputIdentifier(names[0]);
  2798.                 for (int i = 1; i < names.Length; i++) {
  2799.                     Output.Write(".");
  2800.                     OutputIdentifier(names[i]);
  2801.                 }
  2802.                 OutputStartingBrace();
  2803.                 Indent++;
  2804.             }
  2805.         }
  2806.        
  2807.         /// <devdoc>
  2808.         /// <para> Generates code for the specified CodeDom
  2809.         /// compile unit representation.</para>
  2810.         /// </devdoc>
  2811.         private void GenerateCompileUnit(CodeCompileUnit e)
  2812.         {
  2813.             GenerateCompileUnitStart(e);
  2814.             GenerateNamespaces(e);
  2815.             GenerateCompileUnitEnd(e);
  2816.         }
  2817.        
  2818.         /// <devdoc>
  2819.         /// <para>
  2820.         /// Generates code for the specified CodeDom based compile unit start
  2821.         /// representation.
  2822.         /// </para>
  2823.         /// </devdoc>
  2824.         private void GenerateCompileUnitStart(CodeCompileUnit e)
  2825.         {
  2826.            
  2827.             if (e.StartDirectives.Count > 0) {
  2828.                 GenerateDirectives(e.StartDirectives);
  2829.             }
  2830.            
  2831.             Output.WriteLine("//------------------------------------------------------------------------------");
  2832.             Output.Write("// <");
  2833.             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line1));
  2834.             Output.Write("// ");
  2835.             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line2));
  2836.             Output.Write("// ");
  2837.             Output.Write(SR.GetString(SR.AutoGen_Comment_Line3));
  2838.             Output.WriteLine(System.Environment.Version.ToString());
  2839.             Output.WriteLine("//");
  2840.             Output.Write("// ");
  2841.             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line4));
  2842.             Output.Write("// ");
  2843.             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line5));
  2844.             Output.Write("// </");
  2845.             Output.WriteLine(SR.GetString(SR.AutoGen_Comment_Line1));
  2846.             Output.WriteLine("//------------------------------------------------------------------------------");
  2847.             Output.WriteLine("");
  2848.            
  2849.             SortedList importList;
  2850.             // CSharp needs to put assembly attributes after using statements.
  2851.             // Since we need to create a empty namespace even if we don't need it,
  2852.             // using will generated after assembly attributes.
  2853.             importList = new SortedList(StringComparer.Ordinal);
  2854.             foreach (CodeNamespace nspace in e.Namespaces) {
  2855.                 if (String.IsNullOrEmpty(nspace.Name)) {
  2856.                     // mark the namespace to stop it generating its own import list
  2857.                     nspace.UserData["GenerateImports"] = false;
  2858.                    
  2859.                     // Collect the unique list of imports
  2860.                     foreach (CodeNamespaceImport import in nspace.Imports) {
  2861.                         if (!importList.Contains(import.Namespace)) {
  2862.                             importList.Add(import.Namespace, import.Namespace);
  2863.                         }
  2864.                     }
  2865.                 }
  2866.             }
  2867.            
  2868.             // now output the imports
  2869.             foreach (string import in importList.Keys) {
  2870.                 Output.Write("using ");
  2871.                 OutputIdentifier(import);
  2872.                 Output.WriteLine(";");
  2873.             }
  2874.             if (importList.Keys.Count > 0) {
  2875.                 Output.WriteLine("");
  2876.             }
  2877.            
  2878.             // in C# the best place to put these is at the top level.
  2879.             if (e.AssemblyCustomAttributes.Count > 0) {
  2880.                 GenerateAttributes(e.AssemblyCustomAttributes, "assembly: ");
  2881.                 Output.WriteLine("");
  2882.             }
  2883.            
  2884.         }
  2885.        
  2886.         /// <devdoc>
  2887.         /// <para>
  2888.         /// Generates code for the specified CodeDom based compile unit end
  2889.         /// representation.
  2890.         /// </para>
  2891.         /// </devdoc>
  2892.         private void GenerateCompileUnitEnd(CodeCompileUnit e)
  2893.         {
  2894.             if (e.EndDirectives.Count > 0) {
  2895.                 GenerateDirectives(e.EndDirectives);
  2896.             }
  2897.         }
  2898.        
  2899.         /// <devdoc>
  2900.         /// <para>[To be supplied.]</para>
  2901.         /// </devdoc>
  2902.         private void GenerateDirectionExpression(CodeDirectionExpression e)
  2903.         {
  2904.             OutputDirection(e.Direction);
  2905.             GenerateExpression(e.Expression);
  2906.         }
  2907.        
  2908.         private void GenerateDirectives(CodeDirectiveCollection directives)
  2909.         {
  2910.             for (int i = 0; i < directives.Count; i++) {
  2911.                 CodeDirective directive = directives[i];
  2912.                 if (directive is CodeChecksumPragma) {
  2913.                     GenerateChecksumPragma((CodeChecksumPragma)directive);
  2914.                 }
  2915.                 else if (directive is CodeRegionDirective) {
  2916.                     GenerateCodeRegionDirective((CodeRegionDirective)directive);
  2917.                 }
  2918.             }
  2919.         }
  2920.        
  2921.         private void GenerateChecksumPragma(CodeChecksumPragma checksumPragma)
  2922.         {
  2923.             Output.Write("#pragma checksum \"");
  2924.             Output.Write(checksumPragma.FileName);
  2925.             Output.Write("\" \"");
  2926.             Output.Write(checksumPragma.ChecksumAlgorithmId.ToString("B", CultureInfo.InvariantCulture));
  2927.             Output.Write("\" \"");
  2928.             if (checksumPragma.ChecksumData != null) {
  2929.                 foreach (byte b in checksumPragma.ChecksumData) {
  2930.                     Output.Write(b.ToString("X2", CultureInfo.InvariantCulture));
  2931.                 }
  2932.             }
  2933.             Output.WriteLine("\"");
  2934.         }
  2935.        
  2936.         private void GenerateCodeRegionDirective(CodeRegionDirective regionDirective)
  2937.         {
  2938.             if (regionDirective.RegionMode == CodeRegionMode.Start) {
  2939.                 Output.Write("#region ");
  2940.                 Output.WriteLine(regionDirective.RegionText);
  2941.             }
  2942.             else if (regionDirective.RegionMode == CodeRegionMode.End) {
  2943.                 Output.WriteLine("#endregion");
  2944.             }
  2945.         }
  2946.        
  2947.         /// <devdoc>
  2948.         /// <para>
  2949.         /// Generates code for the specified CodeDom based namespace end
  2950.         /// representation.
  2951.         /// </para>
  2952.         /// </devdoc>
  2953.         private void GenerateNamespaceEnd(CodeNamespace e)
  2954.         {
  2955.             if (e.Name != null && e.Name.Length > 0) {
  2956.                 Indent--;
  2957.                 Output.WriteLine("}");
  2958.             }
  2959.         }
  2960.         /// <devdoc>
  2961.         /// <para>
  2962.         /// Generates code for the specified CodeDom based namespace import
  2963.         /// representation.
  2964.         /// </para>
  2965.         /// </devdoc>
  2966.         private void GenerateNamespaceImport(CodeNamespaceImport e)
  2967.         {
  2968.             Output.Write("using ");
  2969.             OutputIdentifier(e.Namespace);
  2970.             Output.WriteLine(";");
  2971.         }
  2972.         /// <devdoc>
  2973.         /// <para>
  2974.         /// Generates code for the specified CodeDom based attribute block start
  2975.         /// representation.
  2976.         /// </para>
  2977.         /// </devdoc>
  2978.         private void GenerateAttributeDeclarationsStart(CodeAttributeDeclarationCollection attributes)
  2979.         {
  2980.             Output.Write("[");
  2981.         }
  2982.         /// <devdoc>
  2983.         /// <para>
  2984.         /// Generates code for the specified CodeDom based attribute block end
  2985.         /// representation.
  2986.         /// </para>
  2987.         /// </devdoc>
  2988.         private void GenerateAttributeDeclarationsEnd(CodeAttributeDeclarationCollection attributes)
  2989.         {
  2990.             Output.Write("]");
  2991.         }
  2992.        
  2993.         private void GenerateAttributes(CodeAttributeDeclarationCollection attributes)
  2994.         {
  2995.             GenerateAttributes(attributes, null, false);
  2996.         }
  2997.        
  2998.         private void GenerateAttributes(CodeAttributeDeclarationCollection attributes, string prefix)
  2999.         {
  3000.             GenerateAttributes(attributes, prefix, false);
  3001.         }
  3002.        
  3003.         private void GenerateAttributes(CodeAttributeDeclarationCollection attributes, string prefix, bool inLine)
  3004.         {
  3005.             if (attributes.Count == 0)
  3006.                 return;
  3007.             IEnumerator en = attributes.GetEnumerator();
  3008.             bool paramArray = false;
  3009.            
  3010.             while (en.MoveNext()) {
  3011.                 // we need to convert paramArrayAttribute to params keyword to
  3012.                 // make csharp compiler happy. In addition, params keyword needs to be after
  3013.                 // other attributes.
  3014.                
  3015.                 CodeAttributeDeclaration current = (CodeAttributeDeclaration)en.Current;
  3016.                
  3017.                 if (current.Name.Equals("system.paramarrayattribute", StringComparison.OrdinalIgnoreCase)) {
  3018.                     paramArray = true;
  3019.                     continue;
  3020.                 }
  3021.                
  3022.                 GenerateAttributeDeclarationsStart(attributes);
  3023.                 if (prefix != null) {
  3024.                     Output.Write(prefix);
  3025.                 }
  3026.                
  3027.                 if (current.AttributeType != null) {
  3028.                     Output.Write(GetTypeOutput(current.AttributeType));
  3029.                 }
  3030.                 Output.Write("(");
  3031.                
  3032.                 bool firstArg = true;
  3033.                 foreach (CodeAttributeArgument arg in current.Arguments) {
  3034.                     if (firstArg) {
  3035.                         firstArg = false;
  3036.                     }
  3037.                     else {
  3038.                         Output.Write(", ");
  3039.                     }
  3040.                    
  3041.                     OutputAttributeArgument(arg);
  3042.                 }
  3043.                
  3044.                 Output.Write(")");
  3045.                 GenerateAttributeDeclarationsEnd(attributes);
  3046.                 if (inLine) {
  3047.                     Output.Write(" ");
  3048.                 }
  3049.                 else {
  3050.                     Output.WriteLine();
  3051.                 }
  3052.             }
  3053.            
  3054.             if (paramArray) {
  3055.                 if (prefix != null) {
  3056.                     Output.Write(prefix);
  3057.                 }
  3058.                 Output.Write("params");
  3059.                
  3060.                 if (inLine) {
  3061.                     Output.Write(" ");
  3062.                 }
  3063.                 else {
  3064.                     Output.WriteLine();
  3065.                 }
  3066.             }
  3067.            
  3068.            
  3069.         }
  3070.        
  3071.         static bool IsKeyword(string value)
  3072.         {
  3073.             return FixedStringLookup.Contains(keywords, value, false);
  3074.         }
  3075.        
  3076.         static bool IsPrefixTwoUnderscore(string value)
  3077.         {
  3078.             if (value.Length < 3) {
  3079.                 return false;
  3080.             }
  3081.             else {
  3082.                 return ((value[0] == '_') && (value[1] == '_') && (value[2] != '_'));
  3083.             }
  3084.         }
  3085.        
  3086.         public bool Supports(GeneratorSupport support)
  3087.         {
  3088.             return ((support & LanguageSupport) == support);
  3089.         }
  3090.        
  3091.         /// <devdoc>
  3092.         /// <para>
  3093.         /// Gets whether the specified value is a valid identifier.
  3094.         /// </para>
  3095.         /// </devdoc>
  3096.         public bool IsValidIdentifier(string value)
  3097.         {
  3098.            
  3099.             // identifiers must be 1 char or longer
  3100.             //
  3101.             if (value == null || value.Length == 0) {
  3102.                 return false;
  3103.             }
  3104.            
  3105.             if (value.Length > 512)
  3106.                 return false;
  3107.            
  3108.             // identifiers cannot be a keyword, unless they are escaped with an '@'
  3109.             //
  3110.             if (value[0] != '@') {
  3111.                 if (IsKeyword(value))
  3112.                     return false;
  3113.             }
  3114.             else {
  3115.                 value = value.Substring(1);
  3116.             }
  3117.            
  3118.             return CodeGenerator.IsValidLanguageIndependentIdentifier(value);
  3119.         }
  3120.        
  3121.         public void ValidateIdentifier(string value)
  3122.         {
  3123.             if (!IsValidIdentifier(value)) {
  3124.                 throw new ArgumentException(SR.GetString(SR.InvalidIdentifier, value));
  3125.             }
  3126.         }
  3127.        
  3128.         public string CreateValidIdentifier(string name)
  3129.         {
  3130.             if (IsPrefixTwoUnderscore(name)) {
  3131.                 name = "_" + name;
  3132.             }
  3133.            
  3134.             while (IsKeyword(name)) {
  3135.                 name = "_" + name;
  3136.             }
  3137.            
  3138.             return name;
  3139.         }
  3140.        
  3141.         public string CreateEscapedIdentifier(string name)
  3142.         {
  3143.             // Any identifier started with two consecutive underscores are
  3144.             // reserved by CSharp.
  3145.             if (IsKeyword(name) || IsPrefixTwoUnderscore(name)) {
  3146.                 return "@" + name;
  3147.             }
  3148.             return name;
  3149.         }
  3150.        
  3151.         // returns the type name without any array declaration.
  3152.         private string GetBaseTypeOutput(CodeTypeReference typeRef)
  3153.         {
  3154.             string s = typeRef.BaseType;
  3155.             if (s.Length == 0) {
  3156.                 s = "void";
  3157.                 return s;
  3158.             }
  3159.            
  3160.             string lowerCaseString = s.ToLower(CultureInfo.InvariantCulture);
  3161.            
  3162.             switch (lowerCaseString) {
  3163.                 case "system.int16":
  3164.                     s = "short";
  3165.                     break;
  3166.                 case "system.int32":
  3167.                     s = "int";
  3168.                     break;
  3169.                 case "system.int64":
  3170.                     s = "long";
  3171.                     break;
  3172.                 case "system.string":
  3173.                     s = "string";
  3174.                     break;
  3175.                 case "system.object":
  3176.                     s = "object";
  3177.                     break;
  3178.                 case "system.boolean":
  3179.                     s = "bool";
  3180.                     break;
  3181.                 case "system.void":
  3182.                     s = "void";
  3183.                     break;
  3184.                 case "system.char":
  3185.                     s = "char";
  3186.                     break;
  3187.                 case "system.byte":
  3188.                     s = "byte";
  3189.                     break;
  3190.                 case "system.uint16":
  3191.                     s = "ushort";
  3192.                     break;
  3193.                 case "system.uint32":
  3194.                     s = "uint";
  3195.                     break;
  3196.                 case "system.uint64":
  3197.                     s = "ulong";
  3198.                     break;
  3199.                 case "system.sbyte":
  3200.                     s = "sbyte";
  3201.                     break;
  3202.                 case "system.single":
  3203.                     s = "float";
  3204.                     break;
  3205.                 case "system.double":
  3206.                     s = "double";
  3207.                     break;
  3208.                 case "system.decimal":
  3209.                     s = "decimal";
  3210.                     break;
  3211.                 default:
  3212.                     // replace + with . for nested classes.
  3213.                     //
  3214.                     StringBuilder sb = new StringBuilder(s.Length + 10);
  3215.                     if (typeRef.Options == CodeTypeReferenceOptions.GlobalReference) {
  3216.                         sb.Append("global::");
  3217.                     }
  3218.                    
  3219.                     string baseType = typeRef.BaseType;
  3220.                    
  3221.                     int lastIndex = 0;
  3222.                     int currentTypeArgStart = 0;
  3223.                     for (int i = 0; i < baseType.Length; i++) {
  3224.                         switch (baseType[i]) {
  3225.                             case '+':
  3226.                             case '.':
  3227.                                 sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex, i - lastIndex)));
  3228.                                 sb.Append('.');
  3229.                                 i++;
  3230.                                 lastIndex = i;
  3231.                                 break;
  3232.                             case '`':
  3233.                                
  3234.                                 sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex, i - lastIndex)));
  3235.                                 i++;
  3236.                                 // skip the '
  3237.                                 int numTypeArgs = 0;
  3238.                                 while (i < baseType.Length && baseType[i] >= '0' && baseType[i] <= '9') {
  3239.                                     numTypeArgs = numTypeArgs * 10 + (baseType[i] - '0');
  3240.                                     i++;
  3241.                                 }
  3242.                                
  3243.                                 GetTypeArgumentsOutput(typeRef.TypeArguments, currentTypeArgStart, numTypeArgs, sb);
  3244.                                 currentTypeArgStart += numTypeArgs;
  3245.                                
  3246.                                 // Arity can be in the middle of a nested type name, so we might have a . or + after it.
  3247.                                 // Skip it if so.
  3248.                                 if (i < baseType.Length && (baseType[i] == '+' || baseType[i] == '.')) {
  3249.                                     sb.Append('.');
  3250.                                     i++;
  3251.                                 }
  3252.                                
  3253.                                 lastIndex = i;
  3254.                                 break;
  3255.                         }
  3256.                     }
  3257.                    
  3258.                     if (lastIndex < baseType.Length)
  3259.                         sb.Append(CreateEscapedIdentifier(baseType.Substring(lastIndex)));
  3260.                    
  3261.                     return sb.ToString();
  3262.             }
  3263.             return s;
  3264.         }
  3265.        
  3266.        
  3267.         private string GetTypeArgumentsOutput(CodeTypeReferenceCollection typeArguments)
  3268.         {
  3269.             StringBuilder sb = new StringBuilder(128);
  3270.             GetTypeArgumentsOutput(typeArguments, 0, typeArguments.Count, sb);
  3271.             return sb.ToString();
  3272.         }
  3273.        
  3274.         private void GetTypeArgumentsOutput(CodeTypeReferenceCollection typeArguments, int start, int length, StringBuilder sb)
  3275.         {
  3276.             sb.Append('<');
  3277.             bool first = true;
  3278.             for (int i = start; i < start + length; i++) {
  3279.                 if (first) {
  3280.                     first = false;
  3281.                 }
  3282.                 else {
  3283.                     sb.Append(", ");
  3284.                 }
  3285.                
  3286.                 // it's possible that we call GetTypeArgumentsOutput with an empty typeArguments collection. This is the case
  3287.                 // for open types, so we want to just output the brackets and commas.
  3288.                 if (i < typeArguments.Count)
  3289.                     sb.Append(GetTypeOutput(typeArguments[i]));
  3290.             }
  3291.             sb.Append('>');
  3292.         }
  3293.        
  3294.         public string GetTypeOutput(CodeTypeReference typeRef)
  3295.         {
  3296.             string s = String.Empty;
  3297.            
  3298.             CodeTypeReference baseTypeRef = typeRef;
  3299.             while (baseTypeRef.ArrayElementType != null) {
  3300.                 baseTypeRef = baseTypeRef.ArrayElementType;
  3301.             }
  3302.             s += GetBaseTypeOutput(baseTypeRef);
  3303.            
  3304.             while (typeRef != null && typeRef.ArrayRank > 0) {
  3305.                 char[] results = new char[typeRef.ArrayRank + 1];
  3306.                 results[0] = '[';
  3307.                 results[typeRef.ArrayRank] = ']';
  3308.                 for (int i = 1; i < typeRef.ArrayRank; i++) {
  3309.                     results[i] = ',';
  3310.                 }
  3311.                 s += new string(results);
  3312.                 typeRef = typeRef.ArrayElementType;
  3313.             }
  3314.            
  3315.             return s;
  3316.         }
  3317.        
  3318.         private void OutputStartingBrace()
  3319.         {
  3320.             if (Options.BracingStyle == "C") {
  3321.                 Output.WriteLine("");
  3322.                 Output.WriteLine("{");
  3323.             }
  3324.             else {
  3325.                 Output.WriteLine(" {");
  3326.             }
  3327.         }
  3328.        
  3329.         private CompilerResults FromFileBatch(CompilerParameters options, string[] fileNames)
  3330.         {
  3331.             if (options == null) {
  3332.                 throw new ArgumentNullException("options");
  3333.             }
  3334.             if (fileNames == null)
  3335.                 throw new ArgumentNullException("fileNames");
  3336.            
  3337.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  3338.            
  3339.             string outputFile = null;
  3340.             int retValue = 0;
  3341.            
  3342.             CompilerResults results = new CompilerResults(options.TempFiles);
  3343.             SecurityPermission perm1 = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
  3344.             perm1.Assert();
  3345.             try {
  3346.                 results.Evidence = options.Evidence;
  3347.             }
  3348.             finally {
  3349.                 SecurityPermission.RevertAssert();
  3350.             }
  3351.             bool createdEmptyAssembly = false;
  3352.            
  3353.             if (options.OutputAssembly == null || options.OutputAssembly.Length == 0) {
  3354.                 string extension = (options.GenerateExecutable) ? "exe" : "dll";
  3355.                 options.OutputAssembly = results.TempFiles.AddExtension(extension, !options.GenerateInMemory);
  3356.                
  3357.                 // Create an empty assembly. This is so that the file will have permissions that
  3358.                 // we can later access with our current credential. If we don't do this, the compiler
  3359.                 // could end up creating an assembly that we cannot open.
  3360.                 new FileStream(options.OutputAssembly, FileMode.Create, FileAccess.ReadWrite).Close();
  3361.                 createdEmptyAssembly = true;
  3362.             }
  3363.            
  3364.             string pdbname = "ildb";
  3365.            
  3366.             // Don't delete pdbs when debug=false but they have specified pdbonly.
  3367.             if (options.CompilerOptions != null && CultureInfo.InvariantCulture.CompareInfo.IndexOf(options.CompilerOptions, "/debug:pdbonly", CompareOptions.IgnoreCase) != -1)
  3368.                 results.TempFiles.AddExtension(pdbname, true);
  3369.             else
  3370.                 results.TempFiles.AddExtension(pdbname);
  3371.            
  3372.             string args = CmdArgsFromParameters(options) + " " + JoinStringArray(fileNames, " ");
  3373.            
  3374.             // Use a response file if the compiler supports it
  3375.             string responseFileArgs = GetResponseFileCmdArgs(options, args);
  3376.             string trueArgs = null;
  3377.             if (responseFileArgs != null) {
  3378.                 trueArgs = args;
  3379.                 args = responseFileArgs;
  3380.             }
  3381.            
  3382.             Compile(options, Executor.GetRuntimeInstallDirectory(), CompilerName, args, ref outputFile, ref retValue, trueArgs);
  3383.            
  3384.             results.NativeCompilerReturnValue = retValue;
  3385.            
  3386.             // only look for errors/warnings if the compile failed or the caller set the warning level
  3387.             if (retValue != 0 || options.WarningLevel > 0) {
  3388.                
  3389.                 FileStream outputStream = new FileStream(outputFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
  3390.                 try {
  3391.                     if (outputStream.Length > 0) {
  3392.                         // The output of the compiler is in UTF8
  3393.                         StreamReader sr = new StreamReader(outputStream, Encoding.UTF8);
  3394.                         string line;
  3395.                         do {
  3396.                             line = sr.ReadLine();
  3397.                             if (line != null) {
  3398.                                 results.Output.Add(line);
  3399.                                
  3400.                                 ProcessCompilerOutputLine(results, line);
  3401.                             }
  3402.                         }
  3403.                         while (line != null);
  3404.                     }
  3405.                 }
  3406.                 finally {
  3407.                     outputStream.Close();
  3408.                 }
  3409.                
  3410.                 // Delete the empty assembly if we created one
  3411.                 if (retValue != 0 && createdEmptyAssembly)
  3412.                     File.Delete(options.OutputAssembly);
  3413.             }
  3414.            
  3415.             if (!results.Errors.HasErrors && options.GenerateInMemory) {
  3416.                 FileStream fs = new FileStream(options.OutputAssembly, FileMode.Open, FileAccess.Read, FileShare.Read);
  3417.                 try {
  3418.                     int fileLen = (int)fs.Length;
  3419.                     byte[] b = new byte[fileLen];
  3420.                     fs.Read(b, 0, fileLen);
  3421.                     SecurityPermission perm = new SecurityPermission(SecurityPermissionFlag.ControlEvidence);
  3422.                     perm.Assert();
  3423.                     try {
  3424.                         results.CompiledAssembly = Assembly.Load(b, null, options.Evidence);
  3425.                     }
  3426.                     finally {
  3427.                         SecurityPermission.RevertAssert();
  3428.                     }
  3429.                 }
  3430.                 finally {
  3431.                     fs.Close();
  3432.                 }
  3433.             }
  3434.             else {
  3435.                
  3436.                 results.PathToAssembly = options.OutputAssembly;
  3437.             }
  3438.            
  3439.             return results;
  3440.         }
  3441.        
  3442.         /// <internalonly/>
  3443.         CompilerResults ICodeCompiler.CompileAssemblyFromDom(CompilerParameters options, CodeCompileUnit e)
  3444.         {
  3445.             if (options == null) {
  3446.                 throw new ArgumentNullException("options");
  3447.             }
  3448.            
  3449.             try {
  3450.                 return FromDom(options, e);
  3451.             }
  3452.             finally {
  3453.                 options.TempFiles.SafeDelete();
  3454.             }
  3455.         }
  3456.        
  3457.         /// <internalonly/>
  3458.         CompilerResults ICodeCompiler.CompileAssemblyFromFile(CompilerParameters options, string fileName)
  3459.         {
  3460.             if (options == null) {
  3461.                 throw new ArgumentNullException("options");
  3462.             }
  3463.            
  3464.             try {
  3465.                 return FromFile(options, fileName);
  3466.             }
  3467.             finally {
  3468.                 options.TempFiles.SafeDelete();
  3469.             }
  3470.         }
  3471.        
  3472.         /// <internalonly/>
  3473.         CompilerResults ICodeCompiler.CompileAssemblyFromSource(CompilerParameters options, string source)
  3474.         {
  3475.             if (options == null) {
  3476.                 throw new ArgumentNullException("options");
  3477.             }
  3478.            
  3479.             try {
  3480.                 return FromSource(options, source);
  3481.             }
  3482.             finally {
  3483.                 options.TempFiles.SafeDelete();
  3484.             }
  3485.         }
  3486.        
  3487.         /// <internalonly/>
  3488.         CompilerResults ICodeCompiler.CompileAssemblyFromSourceBatch(CompilerParameters options, string[] sources)
  3489.         {
  3490.             if (options == null) {
  3491.                 throw new ArgumentNullException("options");
  3492.             }
  3493.            
  3494.             try {
  3495.                 return FromSourceBatch(options, sources);
  3496.             }
  3497.             finally {
  3498.                 options.TempFiles.SafeDelete();
  3499.             }
  3500.         }
  3501.        
  3502.         /// <internalonly/>
  3503.         CompilerResults ICodeCompiler.CompileAssemblyFromFileBatch(CompilerParameters options, string[] fileNames)
  3504.         {
  3505.             if (options == null) {
  3506.                 throw new ArgumentNullException("options");
  3507.             }
  3508.             if (fileNames == null)
  3509.                 throw new ArgumentNullException("fileNames");
  3510.            
  3511.             try {
  3512.                 // Try opening the files to make sure they exists. This will throw an exception
  3513.                 // if it doesn't
  3514.                 foreach (string fileName in fileNames) {
  3515.                     using (Stream str = File.OpenRead(fileName)) {
  3516.                     }
  3517.                 }
  3518.                
  3519.                 return FromFileBatch(options, fileNames);
  3520.             }
  3521.             finally {
  3522.                 options.TempFiles.SafeDelete();
  3523.             }
  3524.         }
  3525.        
  3526.         /// <internalonly/>
  3527.         CompilerResults ICodeCompiler.CompileAssemblyFromDomBatch(CompilerParameters options, CodeCompileUnit[] ea)
  3528.         {
  3529.             if (options == null) {
  3530.                 throw new ArgumentNullException("options");
  3531.             }
  3532.            
  3533.             try {
  3534.                 return FromDomBatch(options, ea);
  3535.             }
  3536.             finally {
  3537.                 options.TempFiles.SafeDelete();
  3538.             }
  3539.         }
  3540.        
  3541.         internal void Compile(CompilerParameters options, string compilerDirectory, string compilerExe, string arguments, ref string outputFile, ref int nativeReturnValue, string trueArgs)
  3542.         {
  3543.             string errorFile = null;
  3544.             outputFile = options.TempFiles.AddExtension("out");
  3545.            
  3546.             // We try to execute the compiler with a full path name.
  3547.             string fullname = compilerDirectory + compilerExe;
  3548.             if (File.Exists(fullname)) {
  3549.                 string trueCmdLine = null;
  3550.                 if (trueArgs != null)
  3551.                     trueCmdLine = "\"" + fullname + "\" " + trueArgs;
  3552.                 nativeReturnValue = Executor.ExecWaitWithCapture(options.SafeUserToken, "\"" + fullname + "\" " + arguments, Environment.CurrentDirectory, options.TempFiles, ref outputFile, ref errorFile, trueCmdLine);
  3553.             }
  3554.             else {
  3555.                 throw new InvalidOperationException(SR.GetString(SR.CompilerNotFound, fullname));
  3556.             }
  3557.         }
  3558.        
  3559.         /// <devdoc>
  3560.         /// <para>
  3561.         /// Compiles the specified compile unit and options, and returns the results
  3562.         /// from the compilation.
  3563.         /// </para>
  3564.         /// </devdoc>
  3565.         private CompilerResults FromDom(CompilerParameters options, CodeCompileUnit e)
  3566.         {
  3567.             if (options == null) {
  3568.                 throw new ArgumentNullException("options");
  3569.             }
  3570.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  3571.            
  3572.             CodeCompileUnit[] units = new CodeCompileUnit[1];
  3573.             units[0] = e;
  3574.             return FromDomBatch(options, units);
  3575.         }
  3576.        
  3577.         /// <devdoc>
  3578.         /// <para>
  3579.         /// Compiles the specified file using the specified options, and returns the
  3580.         /// results from the compilation.
  3581.         /// </para>
  3582.         /// </devdoc>
  3583.         private CompilerResults FromFile(CompilerParameters options, string fileName)
  3584.         {
  3585.             if (options == null) {
  3586.                 throw new ArgumentNullException("options");
  3587.             }
  3588.             if (fileName == null)
  3589.                 throw new ArgumentNullException("fileName");
  3590.            
  3591.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  3592.            
  3593.             // Try opening the file to make sure it exists. This will throw an exception
  3594.             // if it doesn't
  3595.             using (Stream str = File.OpenRead(fileName)) {
  3596.             }
  3597.            
  3598.             string[] filenames = new string[1];
  3599.             filenames[0] = fileName;
  3600.             return FromFileBatch(options, filenames);
  3601.         }
  3602.        
  3603.         /// <devdoc>
  3604.         /// <para>
  3605.         /// Compiles the specified source code using the specified options, and
  3606.         /// returns the results from the compilation.
  3607.         /// </para>
  3608.         /// </devdoc>
  3609.         private CompilerResults FromSource(CompilerParameters options, string source)
  3610.         {
  3611.             if (options == null) {
  3612.                 throw new ArgumentNullException("options");
  3613.             }
  3614.            
  3615.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  3616.            
  3617.             string[] sources = new string[1];
  3618.             sources[0] = source;
  3619.            
  3620.             return FromSourceBatch(options, sources);
  3621.         }
  3622.        
  3623.         /// <devdoc>
  3624.         /// <para>
  3625.         /// Compiles the specified compile units and
  3626.         /// options, and returns the results from the compilation.
  3627.         /// </para>
  3628.         /// </devdoc>
  3629.         private CompilerResults FromDomBatch(CompilerParameters options, CodeCompileUnit[] ea)
  3630.         {
  3631.             if (options == null) {
  3632.                 throw new ArgumentNullException("options");
  3633.             }
  3634.             if (ea == null)
  3635.                 throw new ArgumentNullException("ea");
  3636.            
  3637.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  3638.            
  3639.             string[] filenames = new string[ea.Length];
  3640.            
  3641.             CompilerResults results = null;
  3642.            
  3643.             for (int i = 0; i < ea.Length; i++) {
  3644.                 if (ea[i] == null)
  3645.                     continue;
  3646.                 // the other two batch methods just work if one element is null, so we'll match that.
  3647.                 ResolveReferencedAssemblies(options, ea[i]);
  3648.                 filenames[i] = options.TempFiles.AddExtension(i + FileExtension);
  3649.                 Stream temp = new FileStream(filenames[i], FileMode.Create, FileAccess.Write, FileShare.Read);
  3650.                 try {
  3651.                     using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)) {
  3652.                         ((ICodeGenerator)this).GenerateCodeFromCompileUnit(ea[i], sw, Options);
  3653.                         sw.Flush();
  3654.                     }
  3655.                 }
  3656.                 finally {
  3657.                     temp.Close();
  3658.                 }
  3659.             }
  3660.            
  3661.             results = FromFileBatch(options, filenames);
  3662.             return results;
  3663.         }
  3664.        
  3665.         /// <devdoc>
  3666.         /// <para>
  3667.         /// Because CodeCompileUnit and CompilerParameters both have a referenced assemblies
  3668.         /// property, they must be reconciled. However, because you can compile multiple
  3669.         /// compile units with one set of options, it will simply merge them.
  3670.         /// </para>
  3671.         /// </devdoc>
  3672.         private void ResolveReferencedAssemblies(CompilerParameters options, CodeCompileUnit e)
  3673.         {
  3674.             if (e.ReferencedAssemblies.Count > 0) {
  3675.                 foreach (string assemblyName in e.ReferencedAssemblies) {
  3676.                     if (!options.ReferencedAssemblies.Contains(assemblyName)) {
  3677.                         options.ReferencedAssemblies.Add(assemblyName);
  3678.                     }
  3679.                 }
  3680.             }
  3681.         }
  3682.        
  3683.         /// <devdoc>
  3684.         /// <para>
  3685.         /// Compiles the specified source code strings using the specified options, and
  3686.         /// returns the results from the compilation.
  3687.         /// </para>
  3688.         /// </devdoc>
  3689.         private CompilerResults FromSourceBatch(CompilerParameters options, string[] sources)
  3690.         {
  3691.             if (options == null) {
  3692.                 throw new ArgumentNullException("options");
  3693.             }
  3694.             if (sources == null)
  3695.                 throw new ArgumentNullException("sources");
  3696.            
  3697.             new SecurityPermission(SecurityPermissionFlag.UnmanagedCode).Demand();
  3698.            
  3699.             string[] filenames = new string[sources.Length];
  3700.            
  3701.             CompilerResults results = null;
  3702.             for (int i = 0; i < sources.Length; i++) {
  3703.                 string name = options.TempFiles.AddExtension(i + FileExtension);
  3704.                 Stream temp = new FileStream(name, FileMode.Create, FileAccess.Write, FileShare.Read);
  3705.                 try {
  3706.                     using (StreamWriter sw = new StreamWriter(temp, Encoding.UTF8)) {
  3707.                         sw.Write(sources[i]);
  3708.                         sw.Flush();
  3709.                     }
  3710.                 }
  3711.                 finally {
  3712.                     temp.Close();
  3713.                 }
  3714.                 filenames[i] = name;
  3715.             }
  3716.             results = FromFileBatch(options, filenames);
  3717.            
  3718.             return results;
  3719.         }
  3720.        
  3721.         /// <devdoc>
  3722.         /// <para>Joins the specified string arrays.</para>
  3723.         /// </devdoc>
  3724.         private static string JoinStringArray(string[] sa, string separator)
  3725.         {
  3726.             if (sa == null || sa.Length == 0)
  3727.                 return String.Empty;
  3728.            
  3729.             if (sa.Length == 1) {
  3730.                 return "\"" + sa[0] + "\"";
  3731.             }
  3732.            
  3733.             StringBuilder sb = new StringBuilder();
  3734.             for (int i = 0; i < sa.Length - 1; i++) {
  3735.                 sb.Append("\"");
  3736.                 sb.Append(sa[i]);
  3737.                 sb.Append("\"");
  3738.                 sb.Append(separator);
  3739.             }
  3740.             sb.Append("\"");
  3741.             sb.Append(sa[sa.Length - 1]);
  3742.             sb.Append("\"");
  3743.            
  3744.             return sb.ToString();
  3745.         }
  3746.        
  3747.         /// <internalonly/>
  3748.         void ICodeGenerator.GenerateCodeFromType(CodeTypeDeclaration e, TextWriter w, CodeGeneratorOptions o)
  3749.         {
  3750.             bool setLocal = false;
  3751.             if (output != null && w != output.InnerWriter) {
  3752.                 throw new InvalidOperationException(SR.GetString(SR.CodeGenOutputWriter));
  3753.             }
  3754.             if (output == null) {
  3755.                 setLocal = true;
  3756.                 options = (o == null) ? new CodeGeneratorOptions() : o;
  3757.                 output = new IndentedTextWriter(w, options.IndentString);
  3758.             }
  3759.            
  3760.             try {
  3761.                 GenerateType(e);
  3762.             }
  3763.             finally {
  3764.                 if (setLocal) {
  3765.                     output = null;
  3766.                     options = null;
  3767.                 }
  3768.             }
  3769.         }
  3770.        
  3771.         /// <internalonly/>
  3772.         void ICodeGenerator.GenerateCodeFromExpression(CodeExpression e, TextWriter w, CodeGeneratorOptions o)
  3773.         {
  3774.             bool setLocal = false;
  3775.             if (output != null && w != output.InnerWriter) {
  3776.                 throw new InvalidOperationException(SR.GetString(SR.CodeGenOutputWriter));
  3777.             }
  3778.             if (output == null) {
  3779.                 setLocal = true;
  3780.                 options = (o == null) ? new CodeGeneratorOptions() : o;
  3781.                 output = new IndentedTextWriter(w, options.IndentString);
  3782.             }
  3783.            
  3784.             try {
  3785.                 GenerateExpression(e);
  3786.             }
  3787.             finally {
  3788.                 if (setLocal) {
  3789.                     output = null;
  3790.                     options = null;
  3791.                 }
  3792.             }
  3793.         }
  3794.        
  3795.         /// <internalonly/>
  3796.         void ICodeGenerator.GenerateCodeFromCompileUnit(CodeCompileUnit e, TextWriter w, CodeGeneratorOptions o)
  3797.         {
  3798.             bool setLocal = false;
  3799.             if (output != null && w != output.InnerWriter) {
  3800.                 throw new InvalidOperationException(SR.GetString(SR.CodeGenOutputWriter));
  3801.             }
  3802.             if (output == null) {
  3803.                 setLocal = true;
  3804.                 options = (o == null) ? new CodeGeneratorOptions() : o;
  3805.                 output = new IndentedTextWriter(w, options.IndentString);
  3806.             }
  3807.            
  3808.             try {
  3809.                 if (e is CodeSnippetCompileUnit) {
  3810.                     GenerateSnippetCompileUnit((CodeSnippetCompileUnit)e);
  3811.                 }
  3812.                 else {
  3813.                     GenerateCompileUnit(e);
  3814.                 }
  3815.             }
  3816.             finally {
  3817.                 if (setLocal) {
  3818.                     output = null;
  3819.                     options = null;
  3820.                 }
  3821.             }
  3822.         }
  3823.        
  3824.         /// <internalonly/>
  3825.         void ICodeGenerator.GenerateCodeFromNamespace(CodeNamespace e, TextWriter w, CodeGeneratorOptions o)
  3826.         {
  3827.             bool setLocal = false;
  3828.             if (output != null && w != output.InnerWriter) {
  3829.                 throw new InvalidOperationException(SR.GetString(SR.CodeGenOutputWriter));
  3830.             }
  3831.             if (output == null) {
  3832.                 setLocal = true;
  3833.                 options = (o == null) ? new CodeGeneratorOptions() : o;
  3834.                 output = new IndentedTextWriter(w, options.IndentString);
  3835.             }
  3836.            
  3837.             try {
  3838.                 GenerateNamespace(e);
  3839.             }
  3840.             finally {
  3841.                 if (setLocal) {
  3842.                     output = null;
  3843.                     options = null;
  3844.                 }
  3845.             }
  3846.         }
  3847.        
  3848.         /// <internalonly/>
  3849.         void ICodeGenerator.GenerateCodeFromStatement(CodeStatement e, TextWriter w, CodeGeneratorOptions o)
  3850.         {
  3851.             bool setLocal = false;
  3852.             if (output != null && w != output.InnerWriter) {
  3853.                 throw new InvalidOperationException(SR.GetString(SR.CodeGenOutputWriter));
  3854.             }
  3855.             if (output == null) {
  3856.                 setLocal = true;
  3857.                 options = (o == null) ? new CodeGeneratorOptions() : o;
  3858.                 output = new IndentedTextWriter(w, options.IndentString);
  3859.             }
  3860.            
  3861.             try {
  3862.                 GenerateStatement(e);
  3863.             }
  3864.             finally {
  3865.                 if (setLocal) {
  3866.                     output = null;
  3867.                     options = null;
  3868.                 }
  3869.             }
  3870.         }
  3871.     }
  3872.    
  3873.     internal class CSharpTypeAttributeConverter : CSharpModifierAttributeConverter
  3874.     {
  3875.         private static string[] names;
  3876.         private static object[] values;
  3877.         private static CSharpTypeAttributeConverter defaultConverter;
  3878.        
  3879.         private CSharpTypeAttributeConverter()
  3880.         {
  3881.             // no need to create an instance; use Default
  3882.         }
  3883.        
  3884.         public static CSharpTypeAttributeConverter Default {
  3885.             get {
  3886.                 if (defaultConverter == null) {
  3887.                     defaultConverter = new CSharpTypeAttributeConverter();
  3888.                 }
  3889.                 return defaultConverter;
  3890.             }
  3891.         }
  3892.        
  3893.         /// <devdoc>
  3894.         /// Retrieves an array of names for attributes.
  3895.         /// </devdoc>
  3896.         protected override string[] Names {
  3897.             get {
  3898.                 if (names == null) {
  3899.                     names = new string[] {"Public", "Internal"};
  3900.                 }
  3901.                
  3902.                 return names;
  3903.             }
  3904.         }
  3905.        
  3906.         /// <devdoc>
  3907.         /// Retrieves an array of values for attributes.
  3908.         /// </devdoc>
  3909.         protected override object[] Values {
  3910.             get {
  3911.                 if (values == null) {
  3912.                     values = new object[] {(object)TypeAttributes.Public, (object)TypeAttributes.NotPublic};
  3913.                 }
  3914.                
  3915.                 return values;
  3916.             }
  3917.         }
  3918.        
  3919.         protected override object DefaultValue {
  3920.             get { return TypeAttributes.NotPublic; }
  3921.         }
  3922.     }
  3923.    
  3924.    
  3925.     internal class CSharpMemberAttributeConverter : CSharpModifierAttributeConverter
  3926.     {
  3927.         private static string[] names;
  3928.         private static object[] values;
  3929.         private static CSharpMemberAttributeConverter defaultConverter;
  3930.        
  3931.         private CSharpMemberAttributeConverter()
  3932.         {
  3933.             // no need to create an instance; use Default
  3934.         }
  3935.        
  3936.         public static CSharpMemberAttributeConverter Default {
  3937.             get {
  3938.                 if (defaultConverter == null) {
  3939.                     defaultConverter = new CSharpMemberAttributeConverter();
  3940.                 }
  3941.                 return defaultConverter;
  3942.             }
  3943.         }
  3944.        
  3945.         /// <devdoc>
  3946.         /// Retrieves an array of names for attributes.
  3947.         /// </devdoc>
  3948.         protected override string[] Names {
  3949.             get {
  3950.                 if (names == null) {
  3951.                     names = new string[] {"Public", "Protected", "Protected Internal", "Internal", "Private"};
  3952.                 }
  3953.                
  3954.                 return names;
  3955.             }
  3956.         }
  3957.        
  3958.         /// <devdoc>
  3959.         /// Retrieves an array of values for attributes.
  3960.         /// </devdoc>
  3961.         protected override object[] Values {
  3962.             get {
  3963.                 if (values == null) {
  3964.                     values = new object[] {(object)MemberAttributes.Public, (object)MemberAttributes.Family, (object)MemberAttributes.FamilyOrAssembly, (object)MemberAttributes.Assembly, (object)MemberAttributes.Private};
  3965.                 }
  3966.                
  3967.                 return values;
  3968.             }
  3969.         }
  3970.        
  3971.         protected override object DefaultValue {
  3972.             get { return MemberAttributes.Private; }
  3973.         }
  3974.     }
  3975.    
  3976.     /// <devdoc>
  3977.     /// This type converter provides common values for MemberAttributes
  3978.     /// </devdoc>
  3979.     internal abstract class CSharpModifierAttributeConverter : TypeConverter
  3980.     {
  3981.        
  3982.         protected abstract object[] Values {
  3983.             get;
  3984.         }
  3985.         protected abstract string[] Names {
  3986.             get;
  3987.         }
  3988.         protected abstract object DefaultValue {
  3989.             get;
  3990.         }
  3991.        
  3992.        
  3993.        
  3994.         /// <devdoc>
  3995.         /// We override this because we can convert from string types.
  3996.         /// </devdoc>
  3997.         public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  3998.         {
  3999.             if (sourceType == typeof(string)) {
  4000.                 return true;
  4001.             }
  4002.            
  4003.             return base.CanConvertFrom(context, sourceType);
  4004.         }
  4005.        
  4006.         /// <devdoc>
  4007.         /// Converts the given object to the converter's native type.
  4008.         /// </devdoc>
  4009.         public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  4010.         {
  4011.             if (value is string) {
  4012.                 string name = (string)value;
  4013.                 string[] names = Names;
  4014.                 for (int i = 0; i < names.Length; i++) {
  4015.                     if (names[i].Equals(name)) {
  4016.                         return Values[i];
  4017.                     }
  4018.                 }
  4019.             }
  4020.            
  4021.             return DefaultValue;
  4022.         }
  4023.        
  4024.         /// <devdoc>
  4025.         /// Converts the given object to another type. The most common types to convert
  4026.         /// are to and from a string object. The default implementation will make a call
  4027.         /// to ToString on the object if the object is valid and if the destination
  4028.         /// type is string. If this cannot convert to the desitnation type, this will
  4029.         /// throw a NotSupportedException.
  4030.         /// </devdoc>
  4031.         public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
  4032.         {
  4033.             if (destinationType == null) {
  4034.                 throw new ArgumentNullException("destinationType");
  4035.             }
  4036.            
  4037.             if (destinationType == typeof(string)) {
  4038.                 object[] modifiers = Values;
  4039.                 for (int i = 0; i < modifiers.Length; i++) {
  4040.                     if (modifiers[i].Equals(value)) {
  4041.                         return Names[i];
  4042.                     }
  4043.                 }
  4044.                
  4045.                 return SR.GetString(SR.toStringUnknown);
  4046.             }
  4047.            
  4048.             return base.ConvertTo(context, culture, value, destinationType);
  4049.         }
  4050.        
  4051.         /// <devdoc>
  4052.         /// Determines if the list of standard values returned from
  4053.         /// GetStandardValues is an exclusive list. If the list
  4054.         /// is exclusive, then no other values are valid, such as
  4055.         /// in an enum data type. If the list is not exclusive,
  4056.         /// then there are other valid values besides the list of
  4057.         /// standard values GetStandardValues provides.
  4058.         /// </devdoc>
  4059.         public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
  4060.         {
  4061.             return true;
  4062.         }
  4063.        
  4064.         /// <devdoc>
  4065.         /// Determines if this object supports a standard set of values
  4066.         /// that can be picked from a list.
  4067.         /// </devdoc>
  4068.         public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
  4069.         {
  4070.             return true;
  4071.         }
  4072.        
  4073.         /// <devdoc>
  4074.         /// Retrieves a collection containing a set of standard values
  4075.         /// for the data type this validator is designed for. This
  4076.         /// will return null if the data type does not support a
  4077.         /// standard set of values.
  4078.         /// </devdoc>
  4079.         public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
  4080.         {
  4081.             return new StandardValuesCollection(Values);
  4082.         }
  4083.     }
  4084. }

Developer Fusion