condition tests passes
[mono.git] / mcs / mcs / codegen.cs
index 56a2667c3e1312e94cc64f3ed34681fab76940fe..af57f0f9a717474010dcfc76972972dbc59dc82e 100644 (file)
@@ -21,6 +21,7 @@ using System;
 using System.IO;
 using System.Collections;
 using System.Collections.Specialized;
+using System.Globalization;
 using System.Reflection;
 using System.Reflection.Emit;
 using System.Runtime.InteropServices;
@@ -231,7 +232,7 @@ namespace Mono.CSharp {
                public ILGenerator ig;
 
                [Flags]
-               public enum Flags : byte {
+               public enum Flags : int {
                        /// <summary>
                        ///   This flag tracks the `checked' state of the compilation,
                        ///   it controls whether we should generate code that does overflow
@@ -275,7 +276,16 @@ namespace Mono.CSharp {
                        ///
                        /// Indicates the current context is in probing mode, no errors are reported. 
                        ///
-                       ProbingMode = 1 <<      7
+                       ProbingMode = 1 <<      7,
+
+                       //
+                       // Inside field intializer expression
+                       //
+                       InFieldInitializer = 1 << 8,
+                       
+                       InferReturnType = 1 << 9,
+                       
+                       InCompoundAssignment = 1 << 10
                }
 
                Flags flags;
@@ -295,19 +305,6 @@ namespace Mono.CSharp {
                /// </summary>
                public bool MethodIsStatic;
 
-               /// <summary>
-               ///   Whether we are emitting a field initializer
-               /// </summary>
-               public bool IsFieldInitializer;
-
-               /// <summary>
-               ///   If this is true, then Return and ContextualReturn statements
-               ///   will set the ReturnType value based on the expression types
-               ///   of each return statement instead of the method return type
-               ///   (which is initially null).
-               /// </summary>
-               public bool InferReturnType;
-
                /// <summary>
                ///   The value that is allowed to be returned or NULL if there is no
                ///   return type.
@@ -318,7 +315,7 @@ namespace Mono.CSharp {
                ///   Points to the Type (extracted from the TypeContainer) that
                ///   declares this body of code
                /// </summary>
-               public Type ContainerType;
+               public readonly Type ContainerType;
                
                /// <summary>
                ///   Whether this is generating code for a constructor
@@ -552,6 +549,16 @@ namespace Mono.CSharp {
                                (omit_struct_analysis ? Flags.OmitStructFlowAnalysis : 0);
                        return new FlagsHandle (this, Flags.DoFlowAnalysis | Flags.OmitStructFlowAnalysis, newflags);
                }
+               
+               /// <summary>
+               ///   If this is true, then Return and ContextualReturn statements
+               ///   will set the ReturnType value based on the expression types
+               ///   of each return statement instead of the method return type
+               ///   (which is initially null).
+               /// </summary>
+               public bool InferReturnType {
+                       get { return (flags & Flags.InferReturnType) != 0; }
+               }
 
                public bool IsInObsoleteScope {
                        get {
@@ -573,6 +580,14 @@ namespace Mono.CSharp {
                        set { isAnonymousMethodAllowed = value; }
                }
 
+               public bool IsInFieldInitializer {
+                       get { return (flags & Flags.InFieldInitializer) != 0; }
+               }
+               
+               public bool IsInCompoundAssignment {
+                       get { return (flags & Flags.InCompoundAssignment) != 0; }
+               }               
+
                public FlowBranching CurrentBranching {
                        get { return current_flow_branching; }
                }
@@ -1297,7 +1312,7 @@ namespace Mono.CSharp {
                        else if (aname.Version != null || aname.CultureInfo != null)
                                throw new Exception ("Friend assembly `" + a.GetString () + 
                                                "' is invalid. InternalsVisibleTo cannot have version or culture specified.");
-                       else if (aname.GetPublicKey () == null && Name.GetPublicKey () != null) {
+                       else if (aname.GetPublicKey () == null && Name.GetPublicKey () != null && Name.GetPublicKey ().Length != 0) {
                                Report.Error (1726, a.Location, "Friend assembly reference `" + aname.FullName + "' is invalid." +
                                                " Strong named assemblies must specify a public key in their InternalsVisibleTo declarations");
                                return false;
@@ -1307,6 +1322,28 @@ namespace Mono.CSharp {
                }
 #endif
 
+               static bool IsValidAssemblyVersion (string version)
+               {
+                       Version v;
+                       try {
+                               v = new Version (version);
+                       } catch {
+                               try {
+                                       int major = int.Parse (version, CultureInfo.InvariantCulture);
+                                       v = new Version (major, 0);
+                               } catch {
+                                       return false;
+                               }
+                       }
+
+                       foreach (int candidate in new int [] { v.Major, v.Minor, v.Build, v.Revision }) {
+                               if (candidate > ushort.MaxValue)
+                                       return false;
+                       }
+
+                       return true;
+               }
+
                public override void ApplyAttributeBuilder (Attribute a, CustomAttributeBuilder customBuilder)
                {
                        if (a.Type.IsSubclassOf (TypeManager.security_attr_type) && a.CheckSecurityActionValidity (true)) {
@@ -1328,6 +1365,19 @@ namespace Mono.CSharp {
                                }
                        }
 
+                       if (a.Type == TypeManager.assembly_version_attribute_type) {
+                               string value = a.GetString ();
+                               if (value == null || value.Length == 0)
+                                       return;
+
+                               value = value.Replace ('*', '0');
+
+                               if (!IsValidAssemblyVersion (value)) {
+                                       a.Error_AttributeEmitError (string.Format ("Specified version `{0}' is not valid", value));
+                                       return;
+                               }
+                       }
+
 #if GMCS_SOURCE
                        if (a.Type == TypeManager.internals_visible_attr_type && !CheckInternalsVisibleAttribute (a))
                                return;