2008-08-07 Atsushi Enomoto <atsushi@ximian.com>
[mono.git] / mcs / class / System / Microsoft.CSharp / CSharpCodeGenerator.cs
index ad1f197874a077df2f92b3a8b2caeaeb01b455da..b91480a1fa30872ad9b7ad12933ea67de8c13527 100644 (file)
@@ -34,18 +34,26 @@ namespace Mono.CSharp
        using System;
        using System.CodeDom;
        using System.CodeDom.Compiler;
+       using System.Globalization;
        using System.IO;
        using System.Reflection;
        using System.Collections;
        using System.Text;
 
+#if NET_2_0
+       using System.Collections.Generic;
+#endif
+       
        internal class CSharpCodeGenerator
                : CodeGenerator
        {
-            
+#if NET_2_0
+               IDictionary <string, string> providerOptions;
+#endif
+               
                // It is used for beautiful "for" syntax
                bool dont_write_semicolon;
-            
+
                //
                // Constructors
                //
@@ -54,6 +62,17 @@ namespace Mono.CSharp
                        dont_write_semicolon = false;
                }
 
+#if NET_2_0
+               public CSharpCodeGenerator (IDictionary <string, string> providerOptions)
+               {
+                       this.providerOptions = providerOptions;
+               }
+
+               protected IDictionary <string, string> ProviderOptions {
+                       get { return providerOptions; }
+               }
+#endif
+               
                //
                // Properties
                //
@@ -67,7 +86,7 @@ namespace Mono.CSharp
                // Methods
                //
 
-               protected override void GenerateArrayCreateExpression( CodeArrayCreateExpression expression )
+               protected override void GenerateArrayCreateExpression (CodeArrayCreateExpression expression)
                {
                        //
                        // This tries to replicate MS behavior as good as
@@ -85,74 +104,73 @@ namespace Mono.CSharp
 
                        TextWriter output = Output;
 
-                       output.Write( "new " );
+                       output.Write ("new ");
 
                        CodeExpressionCollection initializers = expression.Initializers;
                        CodeTypeReference createType = expression.CreateType;
 
-                       if ( initializers.Count > 0 ) {
+                       if (initializers.Count > 0) {
 
-                               OutputType( createType );
+                               OutputType (createType);
 
                                if (expression.CreateType.ArrayRank == 0) {
-                                       output.Write( "[]" );
+                                       output.Write ("[]");
                                }
-                               
-                               output.WriteLine( " {" );
+
+                               OutputStartBrace ();
                                ++Indent;
-                               OutputExpressionList( initializers, true );
+                               OutputExpressionList (initializers, true);
                                --Indent;
-                               output.Write( "}" );
-
+                               output.Write ("}");
                        } else {
                                CodeTypeReference arrayType = createType.ArrayElementType;
-                               while ( arrayType != null ) {
+                               while (arrayType != null) {
                                        createType = arrayType;
                                        arrayType = arrayType.ArrayElementType;
                                }
 
-                               OutputType( createType );
+                               OutputType (createType);
 
-                               output.Write( '[' );
+                               output.Write ('[');
 
                                CodeExpression size = expression.SizeExpression;
-                               if ( size != null )
-                                       GenerateExpression( size );
+                               if (size != null)
+                                       GenerateExpression (size);
                                else
-                                       output.Write( expression.Size );
+                                       output.Write (expression.Size);
 
-                               output.Write( ']' );
+                               output.Write(']');
                        }
                }
                
-               protected override void GenerateBaseReferenceExpression( CodeBaseReferenceExpression expression )
+               protected override void GenerateBaseReferenceExpression (CodeBaseReferenceExpression expression)
                {
-                       Output.Write( "base" );
+                       Output.Write ("base");
                }
                
-               protected override void GenerateCastExpression( CodeCastExpression expression )
+               protected override void GenerateCastExpression (CodeCastExpression expression)
                {
                        TextWriter output = Output;
-                       output.Write( "((" );
-                       OutputType( expression.TargetType );
-                       output.Write( ")(" );
-                       GenerateExpression( expression.Expression );
-                       output.Write( "))" );
-               }
-
-
-               protected override void GenerateCompileUnitStart( CodeCompileUnit compileUnit )
-               {
-                       GenerateComment( new CodeComment( "------------------------------------------------------------------------------" ) );
-                       GenerateComment( new CodeComment( " <autogenerated>" ) );
-                       GenerateComment( new CodeComment( "     This code was generated by a tool." ) );
-                       GenerateComment( new CodeComment( "     Mono Runtime Version: " +  System.Environment.Version ) );
-                       GenerateComment( new CodeComment( "" ) );
-                       GenerateComment( new CodeComment( "     Changes to this file may cause incorrect behavior and will be lost if " ) );
-                       GenerateComment( new CodeComment( "     the code is regenerated." ) );
-                       GenerateComment( new CodeComment( " </autogenerated>" ) );
-                       GenerateComment( new CodeComment( "------------------------------------------------------------------------------" ) );
-                       Output.WriteLine();
+                       output.Write ("((");
+                       OutputType (expression.TargetType);
+                       output.Write (")(");
+                       GenerateExpression (expression.Expression);
+                       output.Write ("))");
+               }
+
+
+               protected override void GenerateCompileUnitStart (CodeCompileUnit compileUnit)
+               {
+                       GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));
+                       GenerateComment (new CodeComment (" <autogenerated>"));
+                       GenerateComment (new CodeComment ("     This code was generated by a tool."));
+                       GenerateComment (new CodeComment ("     Mono Runtime Version: " +  System.Environment.Version));
+                       GenerateComment (new CodeComment (""));
+                       GenerateComment (new CodeComment ("     Changes to this file may cause incorrect behavior and will be lost if "));
+                       GenerateComment (new CodeComment ("     the code is regenerated."));
+                       GenerateComment (new CodeComment (" </autogenerated>"));
+                       GenerateComment (new CodeComment ("------------------------------------------------------------------------------"));
+                       Output.WriteLine ();
                        base.GenerateCompileUnitStart (compileUnit);
                }
 
@@ -172,339 +190,360 @@ namespace Mono.CSharp
                        GenerateCompileUnitEnd (compileUnit);
                }
 
-               protected override void GenerateDelegateCreateExpression( CodeDelegateCreateExpression expression )
+               protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)
                {
                        TextWriter output = Output;
 
-                       output.Write( "new " );
-
-                       OutputType( expression.DelegateType );
-
-                       output.Write( '(' );
+                       output.Write ("new ");
+                       OutputType (expression.DelegateType);
+                       output.Write ('(');
 
                        CodeExpression targetObject = expression.TargetObject;
-                       if ( targetObject != null ) {
-                               GenerateExpression( targetObject );
-                               Output.Write( '.' );
+                       if (targetObject != null) {
+                               GenerateExpression (targetObject);
+                               Output.Write ('.');
                        }
-                       output.Write( GetSafeName (expression.MethodName) );
+                       output.Write (GetSafeName (expression.MethodName));
 
-                       output.Write( ')' );
+                       output.Write (')');
                }
 
-               protected override void GenerateFieldReferenceExpression( CodeFieldReferenceExpression expression )
+               protected override void GenerateFieldReferenceExpression (CodeFieldReferenceExpression expression)
                {
                        CodeExpression targetObject = expression.TargetObject;
-                       if ( targetObject != null ) {
-                               GenerateExpression( targetObject );
-                               Output.Write( '.' );
+                       if (targetObject != null) {
+                               GenerateExpression (targetObject);
+                               Output.Write ('.');
                        }
-                       Output.Write( GetSafeName (expression.FieldName) );
+                       Output.Write (GetSafeName (expression.FieldName));
                }
                
-               protected override void GenerateArgumentReferenceExpression( CodeArgumentReferenceExpression expression )
+               protected override void GenerateArgumentReferenceExpression (CodeArgumentReferenceExpression expression)
                {
-                       Output.Write( GetSafeName (expression.ParameterName) );
+                       Output.Write (GetSafeName (expression.ParameterName));
                }
 
-               protected override void GenerateVariableReferenceExpression( CodeVariableReferenceExpression expression )
+               protected override void GenerateVariableReferenceExpression (CodeVariableReferenceExpression expression)
                {
-                       Output.Write( GetSafeName (expression.VariableName) );
+                       Output.Write (GetSafeName (expression.VariableName));
                }
                        
-               protected override void GenerateIndexerExpression( CodeIndexerExpression expression )
+               protected override void GenerateIndexerExpression (CodeIndexerExpression expression)
                {
                        TextWriter output = Output;
 
-                       GenerateExpression( expression.TargetObject );
-                       output.Write( '[' );
-                       OutputExpressionList( expression.Indices );
-                       output.Write( ']' );
+                       GenerateExpression (expression.TargetObject);
+                       output.Write ('[');
+                       OutputExpressionList (expression.Indices);
+                       output.Write (']');
                }
                
-               protected override void GenerateArrayIndexerExpression( CodeArrayIndexerExpression expression )
+               protected override void GenerateArrayIndexerExpression (CodeArrayIndexerExpression expression)
                {
                        TextWriter output = Output;
 
-                       GenerateExpression( expression.TargetObject );
-                       output.Write( '[' );
-                       OutputExpressionList( expression.Indices );
-                       output.Write( ']' );
+                       GenerateExpression (expression.TargetObject);
+                       output.Write ('[');
+                       OutputExpressionList (expression.Indices);
+                       output.Write (']');
                }
                
-               protected override void GenerateSnippetExpression( CodeSnippetExpression expression )
+               protected override void GenerateSnippetExpression (CodeSnippetExpression expression)
                {
-                       Output.Write( expression.Value );
+                       Output.Write (expression.Value);
                }
                
-               protected override void GenerateMethodInvokeExpression( CodeMethodInvokeExpression expression )
+               protected override void GenerateMethodInvokeExpression (CodeMethodInvokeExpression expression)
                {
                        TextWriter output = Output;
 
-                       GenerateMethodReferenceExpression( expression.Method );
+                       GenerateMethodReferenceExpression (expression.Method);
 
-                       output.Write( '(' );
-                       OutputExpressionList( expression.Parameters );
-                       output.Write( ')' );
+                       output.Write ('(');
+                       OutputExpressionList (expression.Parameters);
+                       output.Write (')');
                }
 
-               protected override void GenerateMethodReferenceExpression( CodeMethodReferenceExpression expression )
+               protected override void GenerateMethodReferenceExpression (CodeMethodReferenceExpression expression)
                {
                        if (expression.TargetObject != null)
                        {
-                               GenerateExpression( expression.TargetObject );
-                               Output.Write( '.' );
+                               GenerateExpression (expression.TargetObject);
+                               Output.Write ('.');
                        };
-                       Output.Write( GetSafeName (expression.MethodName) );
+                       Output.Write (GetSafeName (expression.MethodName));
 #if NET_2_0
                        if (expression.TypeArguments.Count > 0)
                                Output.Write (GetTypeArguments (expression.TypeArguments));
 #endif
                }
 
-               protected override void GenerateEventReferenceExpression( CodeEventReferenceExpression expression )
+               protected override void GenerateEventReferenceExpression (CodeEventReferenceExpression expression)
                {
-                       GenerateExpression( expression.TargetObject );
-                       Output.Write( '.' );
-                       Output.Write( GetSafeName (expression.EventName) );
+                       if (expression.TargetObject != null) {
+                               GenerateExpression (expression.TargetObject);
+                               Output.Write ('.');
+                       }
+                       Output.Write (GetSafeName (expression.EventName));
                }
 
-               protected override void GenerateDelegateInvokeExpression( CodeDelegateInvokeExpression expression )
+               protected override void GenerateDelegateInvokeExpression (CodeDelegateInvokeExpression expression)
                {
-                       GenerateExpression( expression.TargetObject );
-                       Output.Write( '(' );
-                       OutputExpressionList( expression.Parameters );
-                       Output.Write( ')' );
+                       if (expression.TargetObject != null)
+                               GenerateExpression (expression.TargetObject);
+                       Output.Write ('(');
+                       OutputExpressionList (expression.Parameters);
+                       Output.Write (')');
                }
                
-               protected override void GenerateObjectCreateExpression( CodeObjectCreateExpression expression )
+               protected override void GenerateObjectCreateExpression (CodeObjectCreateExpression expression)
                {
-                       Output.Write( "new " );
-                       OutputType( expression.CreateType );
-                       Output.Write( '(' );
-                       OutputExpressionList( expression.Parameters );
-                       Output.Write( ')' );
+                       Output.Write ("new ");
+                       OutputType (expression.CreateType);
+                       Output.Write ('(');
+                       OutputExpressionList (expression.Parameters);
+                       Output.Write (')');
                }
 
-               protected override void GeneratePropertyReferenceExpression( CodePropertyReferenceExpression expression )
+               protected override void GeneratePropertyReferenceExpression (CodePropertyReferenceExpression expression)
                {
                        CodeExpression targetObject = expression.TargetObject;
-                       if ( targetObject != null ) {
-                               GenerateExpression( targetObject );
-                               Output.Write( '.' );
+                       if (targetObject != null) {
+                               GenerateExpression (targetObject);
+                               Output.Write ('.');
                        }
-                       Output.Write( GetSafeName (expression.PropertyName ) );
+                       Output.Write (GetSafeName (expression.PropertyName ));
                }
 
-               protected override void GeneratePropertySetValueReferenceExpression( CodePropertySetValueReferenceExpression expression )
+               protected override void GeneratePropertySetValueReferenceExpression (CodePropertySetValueReferenceExpression expression)
                {
-                       Output.Write ( "value" );       
+                       Output.Write ("value");
                }
 
-               protected override void GenerateThisReferenceExpression( CodeThisReferenceExpression expression )
+               protected override void GenerateThisReferenceExpression (CodeThisReferenceExpression expression)
                {
-                       Output.Write( "this" );
+                       Output.Write ("this");
                }
 
-               protected override void GenerateExpressionStatement( CodeExpressionStatement statement )
+               protected override void GenerateExpressionStatement (CodeExpressionStatement statement)
                {
-                       GenerateExpression( statement.Expression );
+                       GenerateExpression (statement.Expression);
                        if (dont_write_semicolon)
                                return;
-                       Output.WriteLine( ';' );
+                       Output.WriteLine(';');
                }
 
-               protected override void GenerateIterationStatement( CodeIterationStatement statement )
+               protected override void GenerateIterationStatement (CodeIterationStatement statement)
                {
                        TextWriter output = Output;
-                    
+
                        dont_write_semicolon = true;
-                       output.Write( "for (" );
-                       GenerateStatement( statement.InitStatement );
-                       output.Write( "; " );
-                       GenerateExpression( statement.TestExpression );
-                       output.Write( "; " );
-                       GenerateStatement( statement.IncrementStatement );
-                       output.Write( ") " );
+                       output.Write ("for (");
+                       GenerateStatement (statement.InitStatement);
+                       output.Write ("; ");
+                       GenerateExpression (statement.TestExpression);
+                       output.Write ("; ");
+                       GenerateStatement (statement.IncrementStatement);
+                       output.Write (")");
                        dont_write_semicolon = false;
-                       output.WriteLine ('{');
+                       OutputStartBrace ();
                        ++Indent;
-                       GenerateStatements( statement.Statements );
+                       GenerateStatements (statement.Statements);
                        --Indent;
                        output.WriteLine ('}');
                }
 
-               protected override void GenerateThrowExceptionStatement( CodeThrowExceptionStatement statement )
+               protected override void GenerateThrowExceptionStatement (CodeThrowExceptionStatement statement)
                {
-                       Output.Write( "throw" );
+                       Output.Write ("throw");
                        if (statement.ToThrow != null) {
                                Output.Write (' ');
                                GenerateExpression (statement.ToThrow);
                        }
-                       Output.WriteLine(";");
+                       Output.WriteLine (";");
                }
 
-               protected override void GenerateComment( CodeComment comment )
+               protected override void GenerateComment (CodeComment comment)
                {
                        TextWriter output = Output;
-                       string[] lines = comment.Text.Split ('\n');
-                       bool first = true;
-                       foreach (string line in lines){
-                               if ( comment.DocComment )
-                                       output.Write( "///" );
-                               else
-                                       output.Write( "//" );
-                               if (first) {
-                                       output.Write (' ');
-                                       first = false;
+
+                       string commentChars = null;
+
+                       if (comment.DocComment) {
+                               commentChars = "///";
+                       } else {
+                               commentChars = "//";
+                       }
+
+                       output.Write (commentChars);
+                       output.Write (' ');
+                       string text = comment.Text;
+
+                       for (int i = 0; i < text.Length; i++) {
+                               output.Write (text[i]);
+                               if (text[i] == '\r') {
+                                       if (i < (text.Length - 1) && text[i + 1] == '\n') {
+                                               continue;
+                                       }
+                                       output.Write (commentChars);
+                               } else if (text[i] == '\n') {
+                                       output.Write (commentChars);
                                }
-                               output.WriteLine( line );
-               }
+                       }
+
+                       output.WriteLine ();
                }
 
-               protected override void GenerateMethodReturnStatement( CodeMethodReturnStatement statement )
+               protected override void GenerateMethodReturnStatement (CodeMethodReturnStatement statement)
                {
                        TextWriter output = Output;
 
                        if (statement.Expression != null) {
-                               output.Write ( "return " );
+                               output.Write ("return ");
                                GenerateExpression (statement.Expression);
-                               output.WriteLine ( ";" );
+                               output.WriteLine (";");
                        } else {
                                output.WriteLine ("return;");
                        }
                }
 
-               protected override void GenerateConditionStatement( CodeConditionStatement statement )
+               protected override void GenerateConditionStatement (CodeConditionStatement statement)
                {
                        TextWriter output = Output;
-                       output.Write( "if (" );
+                       output.Write ("if (");
+                       GenerateExpression (statement.Condition);
+                       output.Write (")");
+                       OutputStartBrace ();
 
-                       GenerateExpression( statement.Condition );
-
-                       output.WriteLine( ") {" );
                        ++Indent;
-                       GenerateStatements( statement.TrueStatements );
+                       GenerateStatements (statement.TrueStatements);
                        --Indent;
 
                        CodeStatementCollection falses = statement.FalseStatements;
-                       if ( falses.Count > 0 ) {
-                               output.Write( '}' );
-                               if ( Options.ElseOnClosing )
-                                       output.Write( ' ' );
+                       if (falses.Count > 0) {
+                               output.Write ('}');
+                               if (Options.ElseOnClosing)
+                                       output.Write (' ');
                                else
-                                       output.WriteLine();
-                               output.WriteLine( "else {" );
+                                       output.WriteLine ();
+                               output.Write ("else");
+                               OutputStartBrace ();
                                ++Indent;
-                               GenerateStatements( falses );
+                               GenerateStatements (falses);
                                --Indent;
                        }
-                       output.WriteLine( '}' );
+                       output.WriteLine ('}');
                }
 
-               protected override void GenerateTryCatchFinallyStatement( CodeTryCatchFinallyStatement statement )
+               protected override void GenerateTryCatchFinallyStatement (CodeTryCatchFinallyStatement statement)
                {
                        TextWriter output = Output;
                        CodeGeneratorOptions options = Options;
 
-                       output.WriteLine( "try {" );
+                       output.Write ("try");
+                       OutputStartBrace ();
                        ++Indent;
-                       GenerateStatements( statement.TryStatements );
+                       GenerateStatements (statement.TryStatements);
                        --Indent;
-                       output.Write( '}' );
                        
-                       foreach ( CodeCatchClause clause in statement.CatchClauses ) {
-                               if ( options.ElseOnClosing )
-                                       output.Write( ' ' );
+                       foreach (CodeCatchClause clause in statement.CatchClauses) {
+                               output.Write ('}');
+                               if (options.ElseOnClosing)
+                                       output.Write (' ');
                                else
-                                       output.WriteLine();
-                               output.Write( "catch (" );
-                               OutputTypeNamePair( clause.CatchExceptionType, GetSafeName (clause.LocalName) );
-                               output.WriteLine( ") {" );
+                                       output.WriteLine ();
+                               output.Write ("catch (");
+                               OutputTypeNamePair (clause.CatchExceptionType, GetSafeName(clause.LocalName));
+                               output.Write (")");
+                               OutputStartBrace ();
                                ++Indent;
-                               GenerateStatements( clause.Statements );
+                               GenerateStatements (clause.Statements);
                                --Indent;
-                               output.Write( '}' );
                        }
 
                        CodeStatementCollection finallies = statement.FinallyStatements;
-                       if ( finallies.Count > 0 ) {
-                               if ( options.ElseOnClosing )
-                                       output.Write( ' ' );
+                       if (finallies.Count > 0) {
+                               output.Write ('}');
+                               if (options.ElseOnClosing)
+                                       output.Write (' ');
                                else
-                                       output.WriteLine();
-                               output.WriteLine( "finally {" );
+                                       output.WriteLine ();
+                               output.Write ("finally");
+                               OutputStartBrace ();
                                ++Indent;
-                               GenerateStatements( finallies );
+                               GenerateStatements (finallies);
                                --Indent;
-                               output.WriteLine( '}' );
                        }
 
-                       output.WriteLine();
+                       output.WriteLine('}');
                }
 
-               protected override void GenerateAssignStatement( CodeAssignStatement statement )
-               {                       
+               protected override void GenerateAssignStatement (CodeAssignStatement statement)
+               {
                        TextWriter output = Output;
-                       GenerateExpression( statement.Left );
-                       output.Write( " = " );
-                       GenerateExpression( statement.Right );
+                       GenerateExpression (statement.Left);
+                       output.Write (" = ");
+                       GenerateExpression (statement.Right);
                        if (dont_write_semicolon)
                                return;
-                       output.WriteLine( ';' );
+                       output.WriteLine (';');
                }
 
-               protected override void GenerateAttachEventStatement( CodeAttachEventStatement statement )
+               protected override void GenerateAttachEventStatement (CodeAttachEventStatement statement)
                {
                        TextWriter output = Output;
 
-                       GenerateEventReferenceExpression( statement.Event );
-                       output.Write( " += " );
-                       GenerateExpression( statement.Listener );
-                       output.WriteLine( ';' );
+                       GenerateEventReferenceExpression (statement.Event);
+                       output.Write (" += ");
+                       GenerateExpression (statement.Listener);
+                       output.WriteLine (';');
                }
 
-               protected override void GenerateRemoveEventStatement( CodeRemoveEventStatement statement )
+               protected override void GenerateRemoveEventStatement (CodeRemoveEventStatement statement)
                {
                        TextWriter output = Output;
-                       GenerateEventReferenceExpression( statement.Event );
-                       Output.Write( " -= " );
-                       GenerateExpression( statement.Listener );
-                       output.WriteLine( ';' );
+                       GenerateEventReferenceExpression (statement.Event);
+                       output.Write (" -= ");
+                       GenerateExpression (statement.Listener);
+                       output.WriteLine (';');
                }
 
-               protected override void GenerateGotoStatement( CodeGotoStatement statement )
+               protected override void GenerateGotoStatement (CodeGotoStatement statement)
                {
                        TextWriter output = Output;
 
-                       output.Write( "goto " );
-                       output.Write( GetSafeName (statement.Label) );
-                       output.Write( ";" );
+                       output.Write ("goto ");
+                       output.Write (GetSafeName (statement.Label));
+                       output.WriteLine (";");
                }
                
-               protected override void GenerateLabeledStatement( CodeLabeledStatement statement )
+               protected override void GenerateLabeledStatement (CodeLabeledStatement statement)
                {
-                       TextWriter output = Output;
-
-                       output.Write( String.Concat (GetSafeName (statement.Label), ": "));
+                       Indent--;
+                       Output.Write (statement.Label);
+                       Output.WriteLine (":");
+                       Indent++;
 
-                       if (statement.Statement != null)
-                               GenerateStatement( statement.Statement );
+                       if (statement.Statement != null) {
+                               GenerateStatement (statement.Statement);
+                       }
                }
 
-               protected override void GenerateVariableDeclarationStatement( CodeVariableDeclarationStatement statement )
+               protected override void GenerateVariableDeclarationStatement (CodeVariableDeclarationStatement statement)
                {
                        TextWriter output = Output;
 
-                       OutputTypeNamePair( statement.Type, GetSafeName (statement.Name) );
+                       OutputTypeNamePair (statement.Type, GetSafeName (statement.Name));
 
                        CodeExpression initExpression = statement.InitExpression;
-                       if ( initExpression != null ) {
-                               output.Write( " = " );
-                               GenerateExpression( initExpression );
+                       if (initExpression != null) {
+                               output.Write (" = ");
+                               GenerateExpression (initExpression);
                        }
 
-                       output.WriteLine( ';' );
+                       if (!dont_write_semicolon) {
+                               output.WriteLine (';');
+                       }
                }
 
                protected override void GenerateLinePragmaStart (CodeLinePragma linePragma)
@@ -522,148 +561,212 @@ namespace Mono.CSharp
                {
                        Output.WriteLine ();
                        Output.WriteLine ("#line default");
+#if NET_2_0
+                       Output.WriteLine ("#line hidden");
+#endif
                }
 
-               protected override void GenerateEvent( CodeMemberEvent eventRef, CodeTypeDeclaration declaration )
+               protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)
                {
+                       if (IsCurrentDelegate || IsCurrentEnum) {
+                               return;
+                       }
+
                        OutputAttributes (eventRef.CustomAttributes, null, false);
 
-                       OutputMemberAccessModifier (eventRef.Attributes);
-                       OutputMemberScopeModifier (eventRef.Attributes | MemberAttributes.Final); // Don't output "virtual"
+                       if (eventRef.PrivateImplementationType == null) {
+                               OutputMemberAccessModifier (eventRef.Attributes);
+                       }
+
                        Output.Write ("event ");
-                       OutputTypeNamePair (eventRef.Type, GetSafeName (eventRef.Name));
+
+                       if (eventRef.PrivateImplementationType != null) {
+                               OutputTypeNamePair (eventRef.Type,
+                                       eventRef.PrivateImplementationType.BaseType + "." + 
+                                       eventRef.Name);
+                       } else {
+                               OutputTypeNamePair (eventRef.Type, GetSafeName (eventRef.Name));
+                       }
                        Output.WriteLine (';');
                }
 
-               protected override void GenerateField( CodeMemberField field )
+               protected override void GenerateField (CodeMemberField field)
                {
+                       if (IsCurrentDelegate || IsCurrentInterface) {
+                               return;
+                       }
+
                        TextWriter output = Output;
 
                        OutputAttributes (field.CustomAttributes, null, false);
 
-                       if (IsCurrentEnum)
-                               Output.Write(GetSafeName (field.Name));
-                       else {
+                       if (IsCurrentEnum) {
+                               Output.Write (GetSafeName (field.Name));
+                       else {
                                MemberAttributes attributes = field.Attributes;
-                               OutputMemberAccessModifier( attributes );
-                               OutputFieldScopeModifier( attributes );
+                               OutputMemberAccessModifier (attributes);
+                               OutputVTableModifier (attributes);
+                               OutputFieldScopeModifier (attributes);
 
-                               OutputTypeNamePair( field.Type, GetSafeName (field.Name) );
+                               OutputTypeNamePair (field.Type, GetSafeName (field.Name));
                        }
 
                        CodeExpression initExpression = field.InitExpression;
-                       if ( initExpression != null ) {
-                               output.Write( " = " );
-                               GenerateExpression( initExpression );
+                       if (initExpression != null) {
+                               output.Write (" = ");
+                               GenerateExpression (initExpression);
                        }
 
                        if (IsCurrentEnum)
-                               output.WriteLine( ',' );
+                               output.WriteLine (',');
                        else
-                               output.WriteLine( ';' );
+                               output.WriteLine (';');
                }
                
-               protected override void GenerateSnippetMember( CodeSnippetTypeMember member )
+               protected override void GenerateSnippetMember (CodeSnippetTypeMember member)
                {
                        Output.Write (member.Text);
                }
                
-               protected override void GenerateEntryPointMethodCodeEntryPointMethod method, 
-                                                                 CodeTypeDeclaration declaration )
+               protected override void GenerateEntryPointMethod (CodeEntryPointMethod method, 
+                                                                 CodeTypeDeclaration declaration)
                {
-                       method.Name = "Main";
-                       GenerateMethod( method, declaration );
+#if NET_2_0
+                       OutputAttributes (method.CustomAttributes, null, false);
+#endif
+
+                       Output.Write ("public static ");
+#if NET_2_0
+                       OutputType (method.ReturnType);
+#else
+                       Output.Write ("void");
+#endif
+                       Output.Write (" Main()");
+                       OutputStartBrace ();
+                       Indent++;
+                       GenerateStatements (method.Statements);
+                       Indent--;
+                       Output.WriteLine ("}");
                }
                
-               protected override void GenerateMethodCodeMemberMethod method,
-                                                       CodeTypeDeclaration declaration )
+               protected override void GenerateMethod (CodeMemberMethod method,
+                                                       CodeTypeDeclaration declaration)
                {
+                       if (IsCurrentDelegate || IsCurrentEnum) {
+                               return;
+                       }
+
                        TextWriter output = Output;
 
                        OutputAttributes (method.CustomAttributes, null, false);
 
-                       if (method.ReturnTypeCustomAttributes.Count > 0)
-                               OutputAttributeDeclarations( method.ReturnTypeCustomAttributes );
+                       OutputAttributes (method.ReturnTypeCustomAttributes, 
+                               "return: ", false);
 
                        MemberAttributes attributes = method.Attributes;
 
-                       if (method.PrivateImplementationType == null && !declaration.IsInterface)
-                               OutputMemberAccessModifier( attributes );
-
-                       if (!declaration.IsInterface)
-                               OutputMemberScopeModifier( attributes );
-
-                       OutputType( method.ReturnType );
+                       if (!IsCurrentInterface) {
+                               if (method.PrivateImplementationType == null) {
+                                       OutputMemberAccessModifier (attributes);
+                                       OutputVTableModifier (attributes);
+                                       OutputMemberScopeModifier (attributes);
+                               }
+                       } else {
+                               OutputVTableModifier (attributes);
+                       }
 
-                       output.Write( ' ' );
+                       OutputType (method.ReturnType);
+                       output.Write (' ');
 
                        CodeTypeReference privateType = method.PrivateImplementationType;
-                       if ( privateType != null ) {
-                               OutputType( privateType );
-                               output.Write( '.' );
+                       if (privateType != null) {
+                               output.Write (privateType.BaseType);
+                               output.Write ('.');
                        }
-                       output.Write( GetSafeName (method.Name) );
+                       output.Write (GetSafeName (method.Name));
 
 #if NET_2_0
                        GenerateGenericsParameters (method.TypeParameters);
 #endif
 
-                       output.Write( '(' );
-                       OutputParameters( method.Parameters );
-                       output.Write( ')' );
+                       output.Write ('(');
+                       OutputParameters (method.Parameters);
+                       output.Write (')');
 
 #if NET_2_0
                        GenerateGenericsConstraints (method.TypeParameters);
 #endif
 
-                       if ( (attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract || declaration.IsInterface)
-                               output.WriteLine( ';' );
+                       if (IsAbstract (attributes) || declaration.IsInterface)
+                               output.WriteLine (';');
                        else {
-                               output.WriteLine( " {" );
+                               OutputStartBrace ();
                                ++Indent;
-                               GenerateStatements( method.Statements );
+                               GenerateStatements (method.Statements);
                                --Indent;
-                               output.WriteLine( '}' );
+                               output.WriteLine ('}');
                        }
                }
 
-               protected override void GenerateProperty( CodeMemberProperty property,
-                                                         CodeTypeDeclaration declaration )
+               static bool IsAbstract (MemberAttributes attributes)
+               {
+                       return (attributes & MemberAttributes.ScopeMask) == MemberAttributes.Abstract;
+               }
+
+               protected override void GenerateProperty (CodeMemberProperty property,
+                                                         CodeTypeDeclaration declaration)
                {
+                       if (IsCurrentDelegate || IsCurrentEnum) {
+                               return;
+                       }
+
                        TextWriter output = Output;
 
                        OutputAttributes (property.CustomAttributes, null, false);
 
                        MemberAttributes attributes = property.Attributes;
-                       OutputMemberAccessModifier (attributes);
-                       OutputMemberScopeModifier (attributes);
 
-                       if (property.Name == "Item")
-                       {
-                               // indexer
-                               
-                               OutputTypeNamePair( property.Type, "this");
-                               output.Write("[");
-                               OutputParameters(property.Parameters);
-                               output.Write("]");
+                       if (!IsCurrentInterface) {
+                               if (property.PrivateImplementationType == null) {
+                                       OutputMemberAccessModifier (attributes);
+                                       OutputVTableModifier (attributes);
+                                       OutputMemberScopeModifier (attributes);
+                               }
+                       } else {
+                               OutputVTableModifier (attributes);
                        }
-                       else
-                       {
-                               OutputTypeNamePair( property.Type, GetSafeName (property.Name));
+
+                       OutputType (property.Type);
+                       output.Write (' ');
+
+                       if (!IsCurrentInterface && property.PrivateImplementationType != null) {
+                               output.Write (property.PrivateImplementationType.BaseType);
+                               output.Write ('.');
+                       }
+
+                       // only consider property indexer if name is Item (case-insensitive 
+                       // comparison) AND property has parameters
+                       if (string.Compare(property.Name, "Item", true, CultureInfo.InvariantCulture) == 0 && property.Parameters.Count > 0) {
+                               output.Write ("this[");
+                               OutputParameters(property.Parameters);
+                               output.Write(']');
+                       } else {
+                               output.Write (GetSafeName (property.Name));
                        }
-                       output.WriteLine (" {");
+                       OutputStartBrace ();
                        ++Indent;
 
-                       if (declaration.IsInterface)
+                       if (declaration.IsInterface || IsAbstract (property.Attributes))
                        {
-                               if (property.HasGet) output.WriteLine("get; ");
-                               if (property.HasSet) output.WriteLine("set; ");
+                               if (property.HasGet) output.WriteLine("get;");
+                               if (property.HasSet) output.WriteLine("set;");
                        }
                        else
                        {
                                if (property.HasGet)
                                {
-                                       output.WriteLine ("get {");
+                                       output.Write ("get");
+                                       OutputStartBrace ();
                                        ++Indent;
 
                                        GenerateStatements (property.GetStatements);
@@ -674,7 +777,8 @@ namespace Mono.CSharp
 
                                if (property.HasSet)
                                {
-                                       output.WriteLine ("set {");
+                                       output.Write ("set");
+                                       OutputStartBrace ();
                                        ++Indent;
 
                                        GenerateStatements (property.SetStatements);
@@ -688,9 +792,12 @@ namespace Mono.CSharp
                        output.WriteLine ('}');
                }
 
-               protected override void GenerateConstructor( CodeConstructor constructor,
-                                                            CodeTypeDeclaration declaration )
+               protected override void GenerateConstructor (CodeConstructor constructor, CodeTypeDeclaration declaration)
                {
+                       if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface) {
+                               return;
+                       }
+
                        OutputAttributes (constructor.CustomAttributes, null, false);
 
                        OutputMemberAccessModifier (constructor.Attributes);
@@ -713,130 +820,155 @@ namespace Mono.CSharp
                                Output.Write(')');
                                Indent -= 2;
                        }
-                       Output.WriteLine (" {");
+                       OutputStartBrace ();
                        Indent++;
                        GenerateStatements (constructor.Statements);
                        Indent--;
                        Output.WriteLine ('}');
                }
-               
-               protected override void GenerateTypeConstructor( CodeTypeConstructor constructor )
+
+               protected override void GenerateTypeConstructor (CodeTypeConstructor constructor)
                {
-                       Output.WriteLine ("static " + GetSafeName (CurrentTypeName) + "() {");
+                       if (IsCurrentDelegate || IsCurrentEnum || IsCurrentInterface) {
+                               return;
+                       }
+
+#if NET_2_0
+                       OutputAttributes (constructor.CustomAttributes, null, false);
+#endif
+
+                       Output.Write ("static " + GetSafeName (CurrentTypeName) + "()");
+                       OutputStartBrace ();
                        Indent++;
                        GenerateStatements (constructor.Statements);
                        Indent--;
                        Output.WriteLine ('}');
                }
 
-               protected override void GenerateTypeStart( CodeTypeDeclaration declaration )
+               protected override void GenerateTypeStart(CodeTypeDeclaration declaration)
                {
                        TextWriter output = Output;
-                       CodeTypeDelegate del = declaration as CodeTypeDelegate;
 
                        OutputAttributes (declaration.CustomAttributes, null, false);
 
-                       TypeAttributes attributes = declaration.TypeAttributes;
-                       OutputTypeAttributes( attributes,
-                                             declaration.IsStruct,
-                                             declaration.IsEnum );
+                       if (!IsCurrentDelegate) {
+                               OutputTypeAttributes (declaration);
 
-                       if (del != null) {
-                               if (del.ReturnType != null)
-                                       OutputType (del.ReturnType);
-                               else
-                                       Output.Write ("void");
-                               output.Write(' ');
-                       }
-
-                       output.Write( GetSafeName (declaration.Name) );
+                               output.Write (GetSafeName (declaration.Name));
 
 #if NET_2_0
-                       GenerateGenericsParameters (declaration.TypeParameters);
+                               GenerateGenericsParameters (declaration.TypeParameters);
 #endif
-                       
-                       IEnumerator enumerator = declaration.BaseTypes.GetEnumerator();
-                       if ( enumerator.MoveNext() ) {
-                               CodeTypeReference type = (CodeTypeReference)enumerator.Current;
-                       
-                               output.Write( ": " );
-                               OutputType( type );
-                               
-                               while ( enumerator.MoveNext() ) {
-                                       type = (CodeTypeReference)enumerator.Current;
-                               
-                                       output.Write( ", " );
-                                       OutputType( type );
+
+                               IEnumerator enumerator = declaration.BaseTypes.GetEnumerator ();
+                               if (enumerator.MoveNext ()) {
+                                       CodeTypeReference type = (CodeTypeReference) enumerator.Current;
+
+                                       output.Write (" : ");
+                                       OutputType (type);
+
+                                       while (enumerator.MoveNext ()) {
+                                               type = (CodeTypeReference) enumerator.Current;
+
+                                               output.Write (", ");
+                                               OutputType (type);
+                                       }
                                }
-                       }
 
-                       if (del != null)
-                               output.Write ( " (" );
-                       else {
 #if NET_2_0
                                GenerateGenericsConstraints (declaration.TypeParameters);
 #endif
-                               output.WriteLine ( " {" );
+                               OutputStartBrace ();
+                               ++Indent;
+                       } else {
+                               if ((declaration.TypeAttributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public) {
+                                       output.Write ("public ");
+                               }
+
+                               CodeTypeDelegate delegateDecl = (CodeTypeDelegate) declaration;
+                               output.Write ("delegate ");
+                               OutputType (delegateDecl.ReturnType);
+                               output.Write (" ");
+                               output.Write (GetSafeName (declaration.Name));
+                               output.Write ("(");
+                               OutputParameters (delegateDecl.Parameters);
+                               output.WriteLine (");");
                        }
-                       ++Indent;
                }
 
-               protected override void GenerateTypeEnd( CodeTypeDeclaration declaration )
+               protected override void GenerateTypeEnd (CodeTypeDeclaration declaration)
                {
-                       --Indent;
-                       if (declaration is CodeTypeDelegate)
-                               Output.WriteLine (");");
-                       else
+                       if (!IsCurrentDelegate) {
+                               --Indent;
                                Output.WriteLine ("}");
+                       }
                }
 
-               protected override void GenerateNamespaceStart( CodeNamespace ns )
+               protected override void GenerateNamespaceStart (CodeNamespace ns)
                {
                        TextWriter output = Output;
                        
                        string name = ns.Name;
-                       if ( name != null && name != "" ) {
-                               output.Write( "namespace " );
-                               output.Write( GetSafeName (name) );
-                               output.WriteLine( " {" );
+                       if (name != null && name.Length != 0) {
+                               output.Write ("namespace ");
+                               output.Write (GetSafeName (name));
+                               OutputStartBrace ();
                                ++Indent;
                        }
                }
 
-               protected override void GenerateNamespaceEnd( CodeNamespace ns )
+               protected override void GenerateNamespaceEnd (CodeNamespace ns)
                {
                        string name = ns.Name;
-                       if ( name != null && name != "" ) {
+                       if (name != null && name.Length != 0) {
                                --Indent;
-                               Output.WriteLine( "}" );
+                               Output.WriteLine ("}");
                        }
                }
 
-               protected override void GenerateNamespaceImport( CodeNamespaceImport import )
+               protected override void GenerateNamespaceImport (CodeNamespaceImport import)
                {
                        TextWriter output = Output;
 
-                       output.Write( "using " );
-                       output.Write( GetSafeName (import.Namespace) );
-                       output.WriteLine( ';' );
+                       output.Write ("using ");
+                       output.Write (GetSafeName (import.Namespace));
+                       output.WriteLine (';');
                }
                
-               protected override void GenerateAttributeDeclarationsStart( CodeAttributeDeclarationCollection attributes )
+               protected override void GenerateAttributeDeclarationsStart (CodeAttributeDeclarationCollection attributes)
                {
                        Output.Write ('[');
-                       CodeMemberMethod met = CurrentMember as CodeMemberMethod;
-                       if (met != null && met.ReturnTypeCustomAttributes == attributes)
-                               Output.Write ("return: ");
                }
                
-               protected override void GenerateAttributeDeclarationsEnd( CodeAttributeDeclarationCollection attributes )
+               protected override void GenerateAttributeDeclarationsEnd (CodeAttributeDeclarationCollection attributes)
                {
                        Output.Write (']');
                }
 
+               private void OutputStartBrace ()
+               {
+                       if (Options.BracingStyle == "C") {
+                               Output.WriteLine ("");
+                               Output.WriteLine ("{");
+                       } else {
+                               Output.WriteLine (" {");
+                       }
+               }
+
                private void OutputAttributes (CodeAttributeDeclarationCollection attributes, string prefix, bool inline)
                {
+#if NET_2_0
+                       bool params_set = false;
+#endif
+
                        foreach (CodeAttributeDeclaration att in attributes) {
+#if NET_2_0
+                               if (att.Name == "System.ParamArrayAttribute") {
+                                       params_set = true;
+                                       continue;
+                               }
+#endif
+
                                GenerateAttributeDeclarationsStart (attributes);
                                if (prefix != null) {
                                        Output.Write (prefix);
@@ -849,6 +981,18 @@ namespace Mono.CSharp
                                        Output.WriteLine ();
                                }
                        }
+
+#if NET_2_0
+                       if (params_set) {
+                               if (prefix != null)
+                                       Output.Write (prefix);
+                               Output.Write ("params");
+                               if (inline)
+                                       Output.Write (" ");
+                               else
+                                       Output.WriteLine ();
+                       }
+#endif
                }
 
                private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
@@ -869,13 +1013,147 @@ namespace Mono.CSharp
                        Output.Write (')');
                }
 
-               protected override void OutputType( CodeTypeReference type )
+               protected override void OutputType (CodeTypeReference type)
+               {
+                       Output.Write (GetTypeOutput (type));
+               }
+
+               private void OutputVTableModifier (MemberAttributes attributes)
+               {
+                       if ((attributes & MemberAttributes.VTableMask) == MemberAttributes.New) {
+                               Output.Write ("new ");
+                       }
+               }
+
+               protected override void OutputFieldScopeModifier (MemberAttributes attributes)
+               {
+                       switch (attributes & MemberAttributes.ScopeMask) {
+                               case MemberAttributes.Static:
+                                       Output.Write ("static ");
+                                       break;
+                               case MemberAttributes.Const:
+                                       Output.Write ("const ");
+                                       break;
+                       }
+               }
+
+#if NET_2_0
+
+               // Note: this method should in fact be private as in .NET 2.0, the 
+               // CSharpCodeGenerator no longer derives from CodeGenerator but we
+               // still need to make this change.
+               protected override void OutputMemberAccessModifier (MemberAttributes attributes)
                {
-                       Output.Write( GetTypeOutput( type ) );
+                       switch (attributes & MemberAttributes.AccessMask) {
+                               case MemberAttributes.Assembly:
+                               case MemberAttributes.FamilyAndAssembly:
+                                       Output.Write ("internal "); 
+                                       break;
+                               case MemberAttributes.Family:
+                                       Output.Write ("protected ");
+                                       break;
+                               case MemberAttributes.FamilyOrAssembly:
+                                       Output.Write ("protected internal ");
+                                       break;
+                               case MemberAttributes.Private:
+                                       Output.Write ("private ");
+                                       break;
+                               case MemberAttributes.Public:
+                                       Output.Write ("public ");
+                                       break;
+                       }
+               }
+
+               // Note: this method should in fact be private as in .NET 2.0, the 
+               // CSharpCodeGenerator no longer derives from CodeGenerator but we
+               // still need to make this change.
+               protected override void OutputMemberScopeModifier (MemberAttributes attributes)
+               {
+                       switch (attributes & MemberAttributes.ScopeMask) {
+                               case MemberAttributes.Abstract:
+                                       Output.Write ("abstract ");
+                                       break;
+                               case MemberAttributes.Final:
+                                       // do nothing
+                                       break;
+                               case MemberAttributes.Static:
+                                       Output.Write ("static ");
+                                       break;
+                               case MemberAttributes.Override:
+                                       Output.Write ("override ");
+                                       break;
+                               default:
+                                       MemberAttributes access = attributes & MemberAttributes.AccessMask;
+                                       if (access == MemberAttributes.Assembly || access == MemberAttributes.Family || access == MemberAttributes.Public) {
+                                               Output.Write ("virtual ");
+                                       }
+                                       break;
+                       }
+               }
+#endif
+
+               private void OutputTypeAttributes (CodeTypeDeclaration declaration)
+               {
+                       TextWriter output = Output;
+                       TypeAttributes attributes = declaration.TypeAttributes;
+
+                       switch (attributes & TypeAttributes.VisibilityMask) {
+                               case TypeAttributes.Public:
+                               case TypeAttributes.NestedPublic:
+                                       output.Write ("public ");
+                                       break;
+                               case TypeAttributes.NestedPrivate:
+                                       output.Write ("private ");
+                                       break;
+#if NET_2_0
+                               case TypeAttributes.NotPublic:
+                               case TypeAttributes.NestedFamANDAssem:
+                               case TypeAttributes.NestedAssembly:
+                                       output.Write ("internal ");
+                                       break; 
+                               case TypeAttributes.NestedFamily:
+                                       output.Write ("protected ");
+                                       break;
+                               case TypeAttributes.NestedFamORAssem:
+                                       output.Write ("protected internal ");
+                                       break;
+#endif
+                       }
+
+                       if (declaration.IsStruct) {
+#if NET_2_0
+                               if (declaration.IsPartial) {
+                                       output.Write ("partial ");
+                               }
+#endif
+                               output.Write ("struct ");
+                       } else if (declaration.IsEnum) {
+                               output.Write ("enum ");
+                       } else {
+                               if ((attributes & TypeAttributes.Interface) != 0) {
+#if NET_2_0
+                                       if (declaration.IsPartial) {
+                                               output.Write ("partial ");
+                                       }
+#endif
+                                       output.Write ("interface ");
+                               } else {
+                                       if ((attributes & TypeAttributes.Sealed) != 0)
+                                               output.Write ("sealed ");
+                                       if ((attributes & TypeAttributes.Abstract) != 0)
+                                               output.Write ("abstract ");
+#if NET_2_0
+                                       if (declaration.IsPartial) {
+                                               output.Write ("partial ");
+                                       }
+#endif
+                                       output.Write ("class ");
+                               }
+                       }
                }
 
                [MonoTODO ("Implement missing special characters")]
-               protected override string QuoteSnippetString( string value )
+               protected override string QuoteSnippetString (string value)
                {
                        // FIXME: this is weird, but works.
                        string output = value.Replace ("\\", "\\\\");
@@ -887,6 +1165,93 @@ namespace Mono.CSharp
                        return "\"" + output + "\"";
                }
 
+               protected override void GeneratePrimitiveExpression(CodePrimitiveExpression e)
+               {
+                       if (e.Value is char) {
+                               this.GenerateCharValue ((char) e.Value);
+#if NET_2_0
+                       } else if (e.Value is ushort) {
+                               ushort uc = (ushort) e.Value;
+                               Output.Write (uc.ToString(CultureInfo.InvariantCulture));
+                       } else if (e.Value is uint) {
+                               uint ui = (uint) e.Value;
+                               Output.Write (ui.ToString(CultureInfo.InvariantCulture));
+                               Output.Write ("u");
+                       } else if (e.Value is ulong) {
+                               ulong ul = (ulong) e.Value;
+                               Output.Write (ul.ToString(CultureInfo.InvariantCulture));
+                               Output.Write ("ul");
+                       } else if (e.Value is sbyte) {
+                               sbyte sb = (sbyte) e.Value;
+                               Output.Write (sb.ToString(CultureInfo.InvariantCulture));
+#endif
+                       } else {
+                               base.GeneratePrimitiveExpression (e);
+                       }
+               }
+
+               private void GenerateCharValue (char c)
+               {
+                       Output.Write ('\'');
+
+                       switch (c) {
+                               case '\0':
+                                       Output.Write ("\\0");
+                                       break;
+                               case '\t':
+                                       Output.Write ("\\t");
+                                       break;
+                               case '\n':
+                                       Output.Write ("\\n");
+                                       break;
+                               case '\r':
+                                       Output.Write ("\\r");
+                                       break;
+                               case '"':
+                                       Output.Write ("\\\"");
+                                       break;
+                               case '\'':
+                                       Output.Write ("\\'");
+                                       break;
+                               case '\\':
+                                       Output.Write ("\\\\");
+                                       break;
+                               case '\u2028':
+                                       Output.Write ("\\u");
+#if NET_2_0
+                                       Output.Write (((int) c).ToString ("X4", CultureInfo.InvariantCulture));
+#else
+                                       Output.Write (((int) c).ToString (CultureInfo.InvariantCulture));
+#endif
+                                       break;
+                               case '\u2029':
+                                       Output.Write ("\\u");
+#if NET_2_0
+                                       Output.Write (((int) c).ToString ("X4", CultureInfo.InvariantCulture));
+#else
+                                       Output.Write (((int) c).ToString (CultureInfo.InvariantCulture));
+#endif
+                                       break;
+                               default:
+                                       Output.Write (c);
+                                       break;
+                       }
+
+                       Output.Write ('\'');
+               }
+
+               protected override void GenerateSingleFloatValue (float f)
+               {
+                       base.GenerateSingleFloatValue (f);
+                       base.Output.Write ('F');
+               }
+
+               protected override void GenerateDecimalValue (decimal d)
+               {
+                       base.GenerateDecimalValue (d);
+                       base.Output.Write ('m');
+               }
+
                protected override void GenerateParameterDeclarationExpression (CodeParameterDeclarationExpression e)
                {
                        OutputAttributes (e.CustomAttributes, null, true);
@@ -927,107 +1292,189 @@ namespace Mono.CSharp
                        else
                                return value;
                }
-
-               protected override string GetTypeOutput( CodeTypeReference type )
+    
+               protected override string GetTypeOutput (CodeTypeReference type)
                {
-                       string output;
-                       CodeTypeReference arrayType;
+#if NET_2_0
+                       if ((type.Options & CodeTypeReferenceOptions.GenericTypeParameter) != 0)
+                               return type.BaseType;
+#endif
+
+                       string typeOutput = null;
+
+                       if (type.ArrayElementType != null) {
+                               typeOutput = GetTypeOutput (type.ArrayElementType);
+                       } else {
+                               typeOutput = DetermineTypeOutput (type);
+                       }
 
-                       arrayType = type.ArrayElementType;
-                       if ( arrayType != null )
-                               output = GetTypeOutput( arrayType );
-                       else { 
+                       int rank = type.ArrayRank;
+                       if (rank > 0) {
+                               typeOutput += '[';
+                               for (--rank; rank > 0; --rank) {
+                                       typeOutput += ',';
+                               }
+                               typeOutput += ']';
+                       }
 
-                               switch ( type.BaseType.ToLower (System.Globalization.CultureInfo.InvariantCulture)) {
+                       return typeOutput;
+               }
+
+               private string DetermineTypeOutput (CodeTypeReference type)
+               {
+                       string typeOutput = null;
+                       string baseType = type.BaseType;
+
+                       switch (baseType.ToLower (System.Globalization.CultureInfo.InvariantCulture)) {
                                case "system.int32":
-                                       output = "int";
+                                       typeOutput = "int";
                                        break;
                                case "system.int64":
-                                       output = "long";
+                                       typeOutput = "long";
                                        break;
                                case "system.int16":
-                                       output = "short";
+                                       typeOutput = "short";
                                        break;
                                case "system.boolean":
-                                       output = "bool";
+                                       typeOutput = "bool";
                                        break;
                                case "system.char":
-                                       output = "char";
+                                       typeOutput = "char";
                                        break;
                                case "system.string":
-                                       output = "string";
+                                       typeOutput = "string";
                                        break;
                                case "system.object":
-                                       output = "object";
+                                       typeOutput = "object";
                                        break;
                                case "system.void":
-                                       output = "void";
+                                       typeOutput = "void";
                                        break;
 #if NET_2_0
                                case "system.byte":
-                                       output = "byte";
+                                       typeOutput = "byte";
                                        break;
                                case "system.sbyte":
-                                       output = "sbyte";
+                                       typeOutput = "sbyte";
                                        break;
                                case "system.decimal":
-                                       output = "decimal";
+                                       typeOutput = "decimal";
                                        break;
                                case "system.double":
-                                       output = "double";
+                                       typeOutput = "double";
                                        break;
                                case "system.single":
-                                       output = "float";
+                                       typeOutput = "float";
                                        break;
                                case "system.uint16":
-                                       output = "ushort";
+                                       typeOutput = "ushort";
                                        break;
                                case "system.uint32":
-                                       output = "uint";
+                                       typeOutput = "uint";
                                        break;
                                case "system.uint64":
-                                       output = "ulong";
+                                       typeOutput = "ulong";
                                        break;
 #endif
                                default:
-                                       output = GetSafeName (type.BaseType);
-                                       break;
-                               }
-                       }
-                       
 #if NET_2_0
-                       if (type.Options == CodeTypeReferenceOptions.GlobalReference)
-                               output = String.Concat ("global::", output);
-
-                       if (type.TypeArguments.Count > 0)
-                               output += GetTypeArguments (type.TypeArguments);
+                                       StringBuilder sb = new StringBuilder (baseType.Length);
+                                       if (type.Options == CodeTypeReferenceOptions.GlobalReference) {
+                                               sb.Append ("global::");
+                                       }
+
+                                       int lastProcessedChar = 0;
+                                       for (int i = 0; i < baseType.Length; i++) {
+                                               char currentChar = baseType[i];
+                                               if (currentChar != '+' && currentChar != '.') {
+                                                       if (currentChar == '`') {
+                                                               sb.Append (CreateEscapedIdentifier (baseType.Substring (
+                                                                       lastProcessedChar, i - lastProcessedChar)));
+                                                               // skip ` character
+                                                               i++;
+                                                               // determine number of type arguments to output
+                                                               int end = i;
+                                                               while (end < baseType.Length && Char.IsDigit (baseType [end]))
+                                                                       end++;
+                                                               int typeArgCount = Int32.Parse (baseType.Substring (i, end - i));
+                                                               // output type arguments
+                                                               OutputTypeArguments (type.TypeArguments, sb, typeArgCount);
+                                                               // skip type argument indicator
+                                                               i = end;
+                                                               // if next character is . or +, then append .
+                                                               if ((i < baseType.Length) && ((baseType[i] == '+') || (baseType[i] == '.'))) {
+                                                                       sb.Append ('.');
+                                                                       // skip character that we just processed
+                                                                       i++;
+                                                               }
+                                                               // save postion of last processed character
+                                                               lastProcessedChar = i;
+                                                       }
+                                               } else {
+                                                       sb.Append (CreateEscapedIdentifier (baseType.Substring (
+                                                               lastProcessedChar, i - lastProcessedChar)));
+                                                       sb.Append ('.');
+                                                       // skip separator
+                                                       i++;
+                                                       // save postion of last processed character
+                                                       lastProcessedChar = i;
+                                               }
+                                       }
+
+                                       // add characters that have not yet been processed 
+                                       if (lastProcessedChar < baseType.Length) {
+                                               sb.Append (CreateEscapedIdentifier (baseType.Substring (lastProcessedChar)));
+                                       }
+
+                                       typeOutput = sb.ToString ();
+#else
+                                       typeOutput = GetSafeName (baseType);
+                                       typeOutput = typeOutput.Replace ('+', '.');
 #endif
-                       int rank = type.ArrayRank;
-                       if ( rank > 0 ) {
-                               output += "[";
-                               for ( --rank; rank > 0; --rank  )
-                                       output += ",";
-                               output += "]";
+                                       break;
                        }
-
-                       return output.Replace ('+', '.');
+                       return typeOutput;
                }
 
-               protected override bool IsValidIdentifier ( string identifier )
+               static bool is_identifier_start_character (char c)
+                {
+                        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || c == '@' || Char.IsLetter (c);
+                }
+
+                static bool is_identifier_part_character (char c)
+                {
+                        return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c >= '0' && c <= '9') || Char.IsLetter (c)
+;
+                }
+               
+               protected override bool IsValidIdentifier (string identifier)
                {
+                       if (identifier == null || identifier.Length == 0)
+                               return false;
+                       
                        if (keywordsTable == null)
                                FillKeywordTable ();
 
-                       return !keywordsTable.Contains (identifier);
+                       if (keywordsTable.Contains (identifier))
+                               return false;
+
+                       if (!is_identifier_start_character (identifier [0]))
+                                return false;
+                        
+                        for (int i = 1; i < identifier.Length; i ++)
+                                if (! is_identifier_part_character (identifier [i]))
+                                        return false;
+                        
+                        return true;
                }
 
-               protected override bool Supports( GeneratorSupport supports )
+               protected override bool Supports (GeneratorSupport supports)
                {
                        return true;
                }
 
 #if NET_2_0
-               protected override void GenerateDirectives( CodeDirectiveCollection directives )
+               protected override void GenerateDirectives (CodeDirectiveCollection directives)
                {
                        foreach (CodeDirective d in directives) {
                                if (d is CodeChecksumPragma) {
@@ -1049,8 +1496,10 @@ namespace Mono.CSharp
                        Output.Write ("\" \"");
                        Output.Write (pragma.ChecksumAlgorithmId.ToString ("B"));
                        Output.Write ("\" \"");
-                       foreach (byte b in pragma.ChecksumData) {
-                               Output.Write (b.ToString ("X2"));
+                       if (pragma.ChecksumData != null) {
+                               foreach (byte b in pragma.ChecksumData) {
+                                       Output.Write (b.ToString ("X2"));
+                               }
                        }
                        Output.WriteLine ("\"");
                }
@@ -1089,31 +1538,42 @@ namespace Mono.CSharp
                        if (count == 0)
                                return;
 
-                       ++Indent;
-                       foreach (CodeTypeParameter p in parameters) {
-                               if (p.Constraints.Count == 0)
-                                       continue;
+                       bool indented = false;
+                       
+                       for (int i = 0; i < count; i++) {
+                               CodeTypeParameter p = parameters [i];
+                               bool hasConstraints = (p.Constraints.Count != 0);
                                Output.WriteLine ();
+                               if (!hasConstraints && !p.HasConstructorConstraint)
+                                       continue;
+
+                               if (!indented) {
+                                       ++Indent;
+                                       indented = true;
+                               }
+
                                Output.Write ("where ");
                                Output.Write (p.Name);
                                Output.Write (" : ");
 
-                               bool is_first = true;
-                               foreach (CodeTypeReference r in p.Constraints) {
-                                       if (is_first)
-                                               is_first = false;
-                                       else
+                               for (int j = 0; j < p.Constraints.Count; j++) {
+                                       if (j > 0)
                                                Output.Write (", ");
-                                       OutputType (r);
+                                       OutputType (p.Constraints [j]);
                                }
+
                                if (p.HasConstructorConstraint) {
-                                       if (!is_first)
+                                       if (hasConstraints)
                                                Output.Write (", ");
-                                       Output.Write ("new ()");
+                                       Output.Write ("new");
+                                       if (hasConstraints)
+                                               Output.Write (" ");
+                                       Output.Write ("()");
                                }
-
                        }
-                       --Indent;
+
+                       if (indented)
+                               --Indent;
                }
 
                string GetTypeArguments (CodeTypeReferenceCollection collection)
@@ -1128,38 +1588,59 @@ namespace Mono.CSharp
                        return sb.ToString ();
                }
 
-               internal override void OutputExtraTypeAttribute (CodeTypeDeclaration type)
+               private void OutputTypeArguments (CodeTypeReferenceCollection typeArguments, StringBuilder sb, int count)
                {
-                       if (type.IsPartial)
-                               Output.Write ("partial ");
+                       if (count == 0) {
+                               return;
+                       } else if (typeArguments.Count == 0) {
+                               // generic type definition
+                               sb.Append ("<>");
+                               return;
+                       }
+
+                       sb.Append ('<');
+
+                       // write first type argument
+                       sb.Append (GetTypeOutput (typeArguments[0]));
+                       // subsequent type argument are prefixed by ', ' separator
+                       for (int i = 1; i < count; i++) {
+                               sb.Append (", ");
+                               sb.Append (GetTypeOutput (typeArguments[i]));
+                       }
+
+                       sb.Append ('>');
                }
 #endif
 
-
 #if false
                //[MonoTODO]
-               public override void ValidateIdentifier( string identifier )
+               public override void ValidateIdentifier (string identifier)
                {
                }
 #endif
 
-               string GetSafeName (string id)
+               private string GetSafeName (string id)
                {
                        if (keywordsTable == null) {
                                FillKeywordTable ();
                        }
-                       if (keywordsTable.Contains (id)) return "@" + id;
-                       else return id;
+                       if (keywordsTable.Contains (id)) {
+                               return "@" + id;
+                       } else {
+                               return id;
+                       }
                }
 
                static void FillKeywordTable ()
                {
                        keywordsTable = new Hashtable ();
-                       foreach (string keyword in keywords) keywordsTable.Add (keyword,keyword);
+                       foreach (string keyword in keywords) {
+                               keywordsTable.Add (keyword, keyword);
+                       }
                }
 
-               static Hashtable keywordsTable;
-               static string[] keywords = new string[] {
+               private static Hashtable keywordsTable;
+               private static string[] keywords = new string[] {
                        "abstract","event","new","struct","as","explicit","null","switch","base","extern",
                        "this","false","operator","throw","break","finally","out","true",
                        "fixed","override","try","case","params","typeof","catch","for",