using System.IO;
using System.Collections;
using System.Collections.Specialized;
+using System.Globalization;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
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
///
/// 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;
/// </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.
/// 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
(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 {
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; }
}
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;
}
#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)) {
}
}
+ 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;