Fixed space indents to tabs to adhere to Mono coding guidelines.
[mono.git] / mcs / class / System / Microsoft.CSharp / CSharpCodeGenerator.cs
index 5191b0d5b69e435307811c0fd883e8ebd338e181..e5d9e5e7e669b6fa293eed9d2037467b419084eb 100644 (file)
@@ -4,6 +4,7 @@
 // Author:
 //   Daniel Stodden (stodden@in.tum.de)
 //   Marek Safar (marek.safar@seznam.cz)
+//   Ilker Cetinkaya (mail@ilker.de)
 //
 // (C) 2002 Ximian, Inc.
 //
@@ -39,17 +40,12 @@ namespace Mono.CSharp
        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
-               Dictionary <string, string> providerOptions;
-#endif
+               IDictionary <string, string> providerOptions;
                
                // It is used for beautiful "for" syntax
                bool dont_write_semicolon;
@@ -62,16 +58,14 @@ namespace Mono.CSharp
                        dont_write_semicolon = false;
                }
 
-#if NET_2_0
-               public CSharpCodeGenerator (Dictionary <string, string> providerOptions)
+               public CSharpCodeGenerator (IDictionary <string, string> providerOptions)
                {
                        this.providerOptions = providerOptions;
                }
 
-               protected Dictionary <string, string> ProviderOptions {
+               protected IDictionary <string, string> ProviderOptions {
                        get { return providerOptions; }
                }
-#endif
                
                //
                // Properties
@@ -178,18 +172,43 @@ namespace Mono.CSharp
                {
                        GenerateCompileUnitStart (compileUnit);
 
+                       GenerateGlobalNamespace (compileUnit);
+
                        if (compileUnit.AssemblyCustomAttributes.Count > 0) {
                                OutputAttributes (compileUnit.AssemblyCustomAttributes, 
                                        "assembly: ", false);
                                Output.WriteLine ("");
                        }
 
-                       foreach (CodeNamespace ns in compileUnit.Namespaces)
-                               GenerateNamespace (ns);
+                       GenerateLocalNamespaces (compileUnit);
 
                        GenerateCompileUnitEnd (compileUnit);
                }
 
+               private void GenerateGlobalNamespace (CodeCompileUnit compileUnit) {
+                       CodeNamespace globalNamespace = null;
+
+                       foreach (CodeNamespace codeNamespace in compileUnit.Namespaces)
+                               if (string.IsNullOrEmpty (codeNamespace.Name)) 
+                                       globalNamespace = codeNamespace;
+  
+                       if (globalNamespace != null)
+                               GenerateNamespace (globalNamespace);
+               }
+
+               private void GenerateLocalNamespaces (CodeCompileUnit compileUnit) {
+                       foreach (CodeNamespace codeNamespace in compileUnit.Namespaces)
+                               if (!string.IsNullOrEmpty (codeNamespace.Name))
+                                       GenerateNamespace (codeNamespace);
+               }
+
+               protected override void GenerateDefaultValueExpression (CodeDefaultValueExpression e)
+               {
+                       Output.Write ("default(");
+                       OutputType (e.Type);
+                       Output.Write (')');
+               }
+
                protected override void GenerateDelegateCreateExpression (CodeDelegateCreateExpression expression)
                {
                        TextWriter output = Output;
@@ -272,10 +291,8 @@ namespace Mono.CSharp
                                Output.Write ('.');
                        };
                        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)
@@ -561,6 +578,7 @@ namespace Mono.CSharp
                {
                        Output.WriteLine ();
                        Output.WriteLine ("#line default");
+                       Output.WriteLine ("#line hidden");
                }
 
                protected override void GenerateEvent (CodeMemberEvent eventRef, CodeTypeDeclaration declaration)
@@ -628,16 +646,10 @@ namespace Mono.CSharp
                protected override void GenerateEntryPointMethod (CodeEntryPointMethod method, 
                                                                  CodeTypeDeclaration 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++;
@@ -682,17 +694,13 @@ namespace Mono.CSharp
                        }
                        output.Write (GetSafeName (method.Name));
 
-#if NET_2_0
                        GenerateGenericsParameters (method.TypeParameters);
-#endif
 
                        output.Write ('(');
                        OutputParameters (method.Parameters);
                        output.Write (')');
 
-#if NET_2_0
                        GenerateGenericsConstraints (method.TypeParameters);
-#endif
 
                        if (IsAbstract (attributes) || declaration.IsInterface)
                                output.WriteLine (';');
@@ -830,9 +838,7 @@ namespace Mono.CSharp
                                return;
                        }
 
-#if NET_2_0
                        OutputAttributes (constructor.CustomAttributes, null, false);
-#endif
 
                        Output.Write ("static " + GetSafeName (CurrentTypeName) + "()");
                        OutputStartBrace ();
@@ -853,9 +859,7 @@ namespace Mono.CSharp
 
                                output.Write (GetSafeName (declaration.Name));
 
-#if NET_2_0
                                GenerateGenericsParameters (declaration.TypeParameters);
-#endif
 
                                IEnumerator enumerator = declaration.BaseTypes.GetEnumerator ();
                                if (enumerator.MoveNext ()) {
@@ -872,9 +876,7 @@ namespace Mono.CSharp
                                        }
                                }
 
-#if NET_2_0
                                GenerateGenericsConstraints (declaration.TypeParameters);
-#endif
                                OutputStartBrace ();
                                ++Indent;
                        } else {
@@ -954,7 +956,14 @@ namespace Mono.CSharp
 
                private void OutputAttributes (CodeAttributeDeclarationCollection attributes, string prefix, bool inline)
                {
+                       bool params_set = false;
+
                        foreach (CodeAttributeDeclaration att in attributes) {
+                               if (att.Name == "System.ParamArrayAttribute") {
+                                       params_set = true;
+                                       continue;
+                               }
+
                                GenerateAttributeDeclarationsStart (attributes);
                                if (prefix != null) {
                                        Output.Write (prefix);
@@ -967,6 +976,16 @@ namespace Mono.CSharp
                                        Output.WriteLine ();
                                }
                        }
+
+                       if (params_set) {
+                               if (prefix != null)
+                                       Output.Write (prefix);
+                               Output.Write ("params");
+                               if (inline)
+                                       Output.Write (" ");
+                               else
+                                       Output.WriteLine ();
+                       }
                }
 
                private void OutputAttributeDeclaration (CodeAttributeDeclaration attribute)
@@ -1011,7 +1030,6 @@ namespace Mono.CSharp
                        }
                }
 
-#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
@@ -1064,7 +1082,6 @@ namespace Mono.CSharp
                                        break;
                        }
                }
-#endif
 
                private void OutputTypeAttributes (CodeTypeDeclaration declaration)
                {
@@ -1079,7 +1096,6 @@ namespace Mono.CSharp
                                case TypeAttributes.NestedPrivate:
                                        output.Write ("private ");
                                        break;
-#if NET_2_0
                                case TypeAttributes.NotPublic:
                                case TypeAttributes.NestedFamANDAssem:
                                case TypeAttributes.NestedAssembly:
@@ -1091,36 +1107,32 @@ namespace Mono.CSharp
                                case TypeAttributes.NestedFamORAssem:
                                        output.Write ("protected internal ");
                                        break;
-#endif
                        }
 
+                       if ((declaration.Attributes & MemberAttributes.New) != 0)
+                               output.Write ("new ");
+
                        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 ");
                                }
                        }
@@ -1143,7 +1155,6 @@ namespace Mono.CSharp
                {
                        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));
@@ -1158,7 +1169,6 @@ namespace Mono.CSharp
                        } else if (e.Value is sbyte) {
                                sbyte sb = (sbyte) e.Value;
                                Output.Write (sb.ToString(CultureInfo.InvariantCulture));
-#endif
                        } else {
                                base.GeneratePrimitiveExpression (e);
                        }
@@ -1192,19 +1202,11 @@ namespace Mono.CSharp
                                        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);
@@ -1269,10 +1271,8 @@ namespace Mono.CSharp
     
                protected override string GetTypeOutput (CodeTypeReference type)
                {
-#if NET_2_0
                        if ((type.Options & CodeTypeReferenceOptions.GenericTypeParameter) != 0)
                                return type.BaseType;
-#endif
 
                        string typeOutput = null;
 
@@ -1324,7 +1324,6 @@ namespace Mono.CSharp
                                case "system.void":
                                        typeOutput = "void";
                                        break;
-#if NET_2_0
                                case "system.byte":
                                        typeOutput = "byte";
                                        break;
@@ -1349,11 +1348,9 @@ namespace Mono.CSharp
                                case "system.uint64":
                                        typeOutput = "ulong";
                                        break;
-#endif
                                default:
-#if NET_2_0
                                        StringBuilder sb = new StringBuilder (baseType.Length);
-                                       if (type.Options == CodeTypeReferenceOptions.GlobalReference) {
+                                       if ((type.Options & CodeTypeReferenceOptions.GlobalReference) != 0) {
                                                sb.Append ("global::");
                                        }
 
@@ -1367,11 +1364,14 @@ namespace Mono.CSharp
                                                                // skip ` character
                                                                i++;
                                                                // determine number of type arguments to output
-                                                               int typeArgCount = baseType[i] - '0';
+                                                               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++;
+                                                               i = end;
                                                                // if next character is . or +, then append .
                                                                if ((i < baseType.Length) && ((baseType[i] == '+') || (baseType[i] == '.'))) {
                                                                        sb.Append ('.');
@@ -1398,25 +1398,20 @@ namespace Mono.CSharp
                                        }
 
                                        typeOutput = sb.ToString ();
-#else
-                                       typeOutput = GetSafeName (baseType);
-                                       typeOutput = typeOutput.Replace ('+', '.');
-#endif
                                        break;
                        }
                        return typeOutput;
                }
 
                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)
-;
-                }
+               {
+                       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)
                {
@@ -1430,13 +1425,13 @@ namespace Mono.CSharp
                                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;
+                               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)
@@ -1444,7 +1439,6 @@ namespace Mono.CSharp
                        return true;
                }
 
-#if NET_2_0
                protected override void GenerateDirectives (CodeDirectiveCollection directives)
                {
                        foreach (CodeDirective d in directives) {
@@ -1462,9 +1456,9 @@ namespace Mono.CSharp
 
                void GenerateCodeChecksumPragma (CodeChecksumPragma pragma)
                {
-                       Output.Write ("#pragma checksum \"");
-                       Output.Write (pragma.FileName);
-                       Output.Write ("\" \"");
+                       Output.Write ("#pragma checksum ");
+                       Output.Write (QuoteSnippetString (pragma.FileName));
+                       Output.Write (" \"");
                        Output.Write (pragma.ChecksumAlgorithmId.ToString ("B"));
                        Output.Write ("\" \"");
                        if (pragma.ChecksumData != null) {
@@ -1581,7 +1575,6 @@ namespace Mono.CSharp
 
                        sb.Append ('>');
                }
-#endif
 
 #if false
                //[MonoTODO]
@@ -1623,9 +1616,7 @@ namespace Mono.CSharp
                        "namespace",
                        "object","bool","byte","float","uint","char","ulong","ushort",
                        "decimal","int","sbyte","short","double","long","string","void",
-#if NET_2_0
                        "partial", "yield", "where"
-#endif
                };
        }
 }