Merge pull request #2463 from ludovic-henry/monoerror-mono_object_new_pinned
[mono.git] / mcs / mcs / import.cs
index 0d7e9e5ad5fec0c693e3b56fedbd3c0c448aed16..78bd541791319165ebb9c0b9279148874a74bdcd 100644 (file)
@@ -13,6 +13,7 @@ using System;
 using System.Runtime.CompilerServices;
 using System.Linq;
 using System.Collections.Generic;
+using System.IO;
 
 #if STATIC
 using MetaType = IKVM.Reflection.Type;
@@ -208,15 +209,15 @@ namespace Mono.CSharp
                        if ((fa & FieldAttributes.Literal) != 0) {
                                Constant c = field_type.Kind == MemberKind.MissingType ?
                                        new NullConstant (InternalType.ErrorType, Location.Null) :
-                                       Constant.CreateConstantFromValue (field_type, fi.GetRawConstantValue (), Location.Null);
-                               return new ConstSpec (declaringType, definition, field_type, fi, mod, c);
+                                       CreateConstantFromValue (field_type, fi);
+                               return new ConstSpec (declaringType, definition, field_type, fi, mod | Modifiers.STATIC, c);
                        }
 
                        if ((fa & FieldAttributes.InitOnly) != 0) {
                                if (field_type.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
                                        var dc = ReadDecimalConstant (CustomAttributeData.GetCustomAttributes (fi));
                                        if (dc != null)
-                                               return new ConstSpec (declaringType, definition, field_type, fi, mod, dc);
+                                               return new ConstSpec (declaringType, definition, field_type, fi, mod | Modifiers.STATIC, dc);
                                }
 
                                mod |= Modifiers.READONLY;
@@ -242,6 +243,25 @@ namespace Mono.CSharp
                        return new FieldSpec (declaringType, definition, field_type, fi, mod);
                }
 
+               Constant CreateConstantFromValue (TypeSpec fieldType, FieldInfo fi)
+               {
+                       var value = fi.GetRawConstantValue ();
+                       //
+                       // Metadata value can be encoded using different constant value type
+                       // than is actual field type
+                       //
+                       // e.g. unsigned int16 CONSTANT = int16 (0x0000ffff)
+                       //
+                       if (value != null && !fieldType.IsEnum) {
+                               var c = ImportConstant (value);
+                               if (c != null) {
+                                       return fieldType == c.Type ? c : c.ConvertExplicitly (false, fieldType);
+                               }
+                       }
+
+                       return Constant.CreateConstantFromValue (fieldType, value, Location.Null);
+               }
+
                public EventSpec CreateEvent (EventInfo ei, TypeSpec declaringType, MethodSpec add, MethodSpec remove)
                {
                        add.IsAccessor = true;
@@ -434,6 +454,8 @@ namespace Mono.CSharp
                                                else
                                                        mod |= Modifiers.VIRTUAL;
                                        }
+                               } else if (parameters.HasExtensionMethodType) {
+                                       mod |= Modifiers.METHOD_EXTENSION;
                                }
                        }
 
@@ -529,7 +551,7 @@ namespace Mono.CSharp
                                                        if (value == null) {
                                                                default_value = Constant.CreateConstantFromValue (ptype, null, Location.Null);
                                                        } else {
-                                                               default_value = ImportParameterConstant (value);
+                                                               default_value = ImportConstant (value);
 
                                                                if (ptype.IsEnum) {
                                                                        default_value = new EnumConstant ((Constant) default_value, ptype);
@@ -555,7 +577,7 @@ namespace Mono.CSharp
                                                } else if (value == null) {
                                                        default_value = new DefaultValueExpression (new TypeExpression (ptype, Location.Null), Location.Null);
                                                } else if (ptype.BuiltinType == BuiltinTypeSpec.Type.Decimal) {
-                                                       default_value = ImportParameterConstant (value);
+                                                       default_value = ImportConstant (value);
                                                }
                                        }
                                }
@@ -958,6 +980,21 @@ namespace Mono.CSharp
                        return found;
                }
 
+               public ImportedAssemblyDefinition GetImportedAssemblyDefinition (AssemblyName assemblyName)
+               {
+                       foreach (var a in Assemblies) {
+                               var ia = a as ImportedAssemblyDefinition;
+                               if (ia == null)
+                                       continue;
+                               
+                               if (a.Name == assemblyName.Name)
+                                       return ia;
+                       }
+
+                       return null;
+               }
+
+
                public void ImportTypeBase (MetaType type)
                {
                        TypeSpec spec = import_cache[type];
@@ -1107,7 +1144,7 @@ namespace Mono.CSharp
                                spec.TypeArguments = tparams.ToArray ();
                }
 
-               Constant ImportParameterConstant (object value)
+               Constant ImportConstant (object value)
                {
                        //
                        // Get type of underlying value as int constant can be used for object
@@ -1285,6 +1322,23 @@ namespace Mono.CSharp
                        public string DefaultIndexerName;
                        public bool? CLSAttributeValue;
                        public TypeSpec CoClass;
+
+                       static bool HasMissingType (ConstructorInfo ctor)
+                       {
+#if STATIC
+                               //
+                               // Mimic odd csc behaviour where missing type on predefined
+                               // attributes means the attribute is silently ignored. This can
+                               // happen with PCL facades
+                               //
+                               foreach (var p in ctor.GetParameters ()) {
+                                       if (p.ParameterType.__ContainsMissingType)
+                                               return true;
+                               }
+#endif
+
+                               return false;
+                       }
                        
                        public static AttributesBag Read (MemberInfo mi, MetadataImporter importer)
                        {
@@ -1359,6 +1413,9 @@ namespace Mono.CSharp
                                                        if (dt.Namespace != "System")
                                                                continue;
 
+                                                       if (HasMissingType (a.Constructor))
+                                                               continue;
+
                                                        if (bag == null)
                                                                bag = new AttributesBag ();
 
@@ -1377,6 +1434,9 @@ namespace Mono.CSharp
                                                        if (dt.Namespace != "System.Runtime.InteropServices")
                                                                continue;
 
+                                                       if (HasMissingType (a.Constructor))
+                                                               continue;
+
                                                        if (bag == null)
                                                                bag = new AttributesBag ();
 
@@ -1680,7 +1740,14 @@ namespace Mono.CSharp
                                        if (s == null)
                                                continue;
 
-                                       var an = new AssemblyName (s);
+                                       AssemblyName an;
+                                       try {
+                                               an = new AssemblyName (s);
+                                       } catch (FileLoadException) {
+                                               // Invalid assembly name reuses FileLoadException
+                                               continue;
+                                       }
+
                                        if (internals_visible_to == null)
                                                internals_visible_to = new List<AssemblyName> ();
 
@@ -1935,7 +2002,7 @@ namespace Mono.CSharp
                {
                        // 
                        // Report details about missing type and most likely cause of the problem.
-                       // csc reports 1683, 1684 as warnings but we report them only when used
+                       // csc used to reports 1683, 1684 (now 7069) as warnings but we report them only when used
                        // or referenced from the user core in which case compilation error has to
                        // be reported because compiler cannot continue anyway
                        //
@@ -1976,7 +2043,7 @@ namespace Mono.CSharp
                                        report.Error (731, loc, "The type forwarder for type `{0}' in assembly `{1}' has circular dependency",
                                                name, definition.DeclaringAssembly.FullName);
                                } else {
-                                       report.Error (1684, loc,
+                                       report.Error (7069, loc,
                                                "Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found",
                                                name, t.MemberDefinition.DeclaringAssembly.FullName);
                                }