Fix comment typo
[mono.git] / mcs / mcs / typemanager.cs
index ea02af6d0da1b0bf6610543f321b8c884ad2b7b8..708cace79dc4871ea6c17f7ba2d34bead19e2218 100644 (file)
@@ -3,7 +3,7 @@
 //
 // Author: Miguel de Icaza (miguel@gnu.org)
 //         Ravi Pratap     (ravi@ximian.com)
-//         Marek Safar     (marek.safar@seznam.cz)
+//         Marek Safar     (marek.safar@gmail.com)
 //
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
@@ -15,6 +15,7 @@ using System;
 using System.Globalization;
 using System.Collections.Generic;
 using System.Text;
+using System.IO;
 
 namespace Mono.CSharp
 {
@@ -142,14 +143,14 @@ namespace Mono.CSharp
                {
                        var ctx = module.Compiler;
                        foreach (var p in types) {
-                               var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, Location.Null);
+                               var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity);
                                if (found == null || found == p)
                                        continue;
 
                                var tc = found.MemberDefinition as TypeContainer;
                                if (tc != null) {
                                        var ns = module.GlobalRootNamespace.GetNamespace (p.Namespace, false);
-                                       ns.ReplaceTypeWithPredefined (found, p);
+                                       ns.SetBuiltinType (p);
 
                                        tc.SetPredefinedSpec (p);
                                        p.SetDefinition (found);
@@ -216,6 +217,16 @@ namespace Mono.CSharp
                public readonly PredefinedType CallSiteGeneric;
                public readonly PredefinedType BinderFlags;
 
+               //
+               // C# 5.0
+               //
+               public readonly PredefinedType AsyncVoidMethodBuilder;
+               public readonly PredefinedType AsyncTaskMethodBuilder;
+               public readonly PredefinedType AsyncTaskMethodBuilderGeneric;
+               public readonly PredefinedType Action;
+               public readonly PredefinedType Task;
+               public readonly PredefinedType TaskGeneric;
+
                public PredefinedTypes (ModuleContainer module)
                {
                        TypedReference = new PredefinedType (module, MemberKind.Struct, "System", "TypedReference");
@@ -256,6 +267,13 @@ namespace Mono.CSharp
                        Binder = new PredefinedType (module, MemberKind.Class, "Microsoft.CSharp.RuntimeBinder", "Binder");
                        BinderFlags = new PredefinedType (module, MemberKind.Enum, "Microsoft.CSharp.RuntimeBinder", "CSharpBinderFlags");
 
+                       Action = new PredefinedType (module, MemberKind.Delegate, "System", "Action");
+                       AsyncVoidMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncVoidMethodBuilder");
+                       AsyncTaskMethodBuilder = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder");
+                       AsyncTaskMethodBuilderGeneric = new PredefinedType (module, MemberKind.Struct, "System.Runtime.CompilerServices", "AsyncTaskMethodBuilder", 1);
+                       Task = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task");
+                       TaskGeneric = new PredefinedType (module, MemberKind.Class, "System.Threading.Tasks", "Task", 1);
+
                        //
                        // Define types which are used for comparison. It does not matter
                        // if they don't exist as no error report is needed
@@ -280,12 +298,27 @@ namespace Mono.CSharp
 
                        if (ExpressionGeneric.Define ())
                                ExpressionGeneric.TypeSpec.IsExpressionTreeType = true;
+
+                       Task.Define ();
+                       if (TaskGeneric.Define ())
+                               TaskGeneric.TypeSpec.IsGenericTask = true;
                }
        }
 
        class PredefinedMembers
        {
                public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
+               public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
+               public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
                public readonly PredefinedMember<MethodSpec> DecimalCtor;
                public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
                public readonly PredefinedMember<MethodSpec> DecimalCtorLong;
@@ -317,7 +350,6 @@ namespace Mono.CSharp
                public readonly PredefinedMember<MethodSpec> StringInequal;
                public readonly PredefinedMember<MethodSpec> StructLayoutAttributeCtor;
                public readonly PredefinedMember<FieldSpec> StructLayoutCharSet;
-               public readonly PredefinedMember<FieldSpec> StructLayoutPack;
                public readonly PredefinedMember<FieldSpec> StructLayoutSize;
                public readonly PredefinedMember<MethodSpec> TypeGetTypeFromHandle;
 
@@ -330,6 +362,48 @@ namespace Mono.CSharp
                        ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
                                MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
 
+                       AsyncTaskMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncTaskMethodBuilder.TypeSpec));
+
+                       AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
+
+                       AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Method ("SetException", 0,
+                               ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
+
+                       AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Property ("Task", null));
+
+                       AsyncTaskMethodBuilderGenericCreate = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
+
+                       AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Method ("SetResult", 0,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.NONE)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, null, SpecialConstraint.None, Variance.None, null)
+                                                       }, false), btypes.Void));
+
+                       AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Method ("SetException", 0,
+                               ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
+
+                       AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Property ("Task", null));
+
+                       AsyncVoidMethodBuilderCreate = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               MemberFilter.Method ("Create", 0, ParametersCompiled.EmptyReadOnlyParameters, types.AsyncVoidMethodBuilder.TypeSpec));
+
+                       AsyncVoidMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               MemberFilter.Method ("SetException", 0, null, btypes.Void));
+
+                       AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
+
                        DecimalCtor = new PredefinedMember<MethodSpec> (module, btypes.Decimal,
                                MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
                                        btypes.Int, btypes.Int, btypes.Int, btypes.Bool, btypes.Byte)));
@@ -449,9 +523,6 @@ namespace Mono.CSharp
                        StructLayoutCharSet = new PredefinedMember<FieldSpec> (module, atypes.StructLayout, "CharSet",
                                MemberKind.Field, types.CharSet);
 
-                       StructLayoutPack = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
-                               MemberFilter.Field ("Pack", btypes.Int));
-
                        StructLayoutSize = new PredefinedMember<FieldSpec> (module, atypes.StructLayout,
                                MemberFilter.Field ("Size", btypes.Int));
 
@@ -529,14 +600,8 @@ namespace Mono.CSharp
                        if (type != null)
                                return true;
 
-                       Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
-                       var te = type_ns.LookupType (module, name, arity, true, Location.Null);
-                       if (te == null || te.Type.Kind != kind) {
-                               return false;
-                       }
-
-                       type = te.Type;
-                       return true;
+                       type = Resolve (module, kind, ns, name, arity, false);
+                       return type != null;
                }
 
                public string GetSignatureForError ()
@@ -544,33 +609,87 @@ namespace Mono.CSharp
                        return ns + "." + name;
                }
 
-               public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, Location loc)
+               public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
+               {
+                       return Resolve (module, kind, ns, name, arity, true);
+               }
+
+               public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
                {
                        Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, true);
-                       var te = type_ns.LookupType (module, name, arity, false, Location.Null);
-                       if (te == null) {
-                               module.Compiler.Report.Error (518, loc, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
+                       var found = type_ns.GetAllTypes (name);
+                       if (found == null) {
+                               if (reportErrors)
+                                       module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
+
                                return null;
                        }
 
-                       var type = te.Type;
-                       if (type.Kind != kind) {
-                               if (type.Kind == MemberKind.Struct && kind == MemberKind.Void && type.MemberDefinition is TypeContainer) {
-                                       // Void is declared as struct but we keep it internally as
-                                       // special kind, the swap will be done by caller
+                       TypeSpec best_match = null;
+                       foreach (var candidate in found) {
+                               if (candidate.Kind != kind) {
+                                       if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
+                                               // Void is declared as struct but we keep it internally as
+                                               // special kind, the swap will be done by caller
+                                       } else {
+                                               continue;
+                                       }
+                               }
+
+                               if (candidate.Arity != arity)
+                                       continue;
+
+                               if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
+                                       continue;
+
+                               if (best_match == null) {
+                                       best_match = candidate;
+                                       continue;
+                               }
+
+                               var other_match = best_match;
+                               if (!best_match.MemberDefinition.IsImported &&
+                                       module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
+                                       best_match = candidate;
+                               }
+
+                               string location;
+                               if (best_match.MemberDefinition is MemberCore) {
+                                       location = ((MemberCore) best_match.MemberDefinition).Location.Name;
                                } else {
-                                       module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
-                                       return null;
+                                       var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
+                                       location = Path.GetFileName (assembly.Location);
+                               }
+
+                               module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
+                               module.Compiler.Report.SymbolRelatedToPreviousError (candidate);
+
+                               module.Compiler.Report.Warning (1685, 1,
+                                       "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
+                                       ns, name, location);
+
+                               break;
+                       }
+
+                       if (best_match == null && reportErrors) {
+                               Location loc;
+                               if (found[0].MemberDefinition is MemberCore) {
+                                       loc = ((MemberCore) found[0].MemberDefinition).Location;
+                               } else {
+                                       loc = Location.Null;
+                                       module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
                                }
+
+                               module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
                        }
 
-                       return type;
+                       return best_match;
                }
 
-               public TypeSpec Resolve (Location loc)
+               public TypeSpec Resolve ()
                {
                        if (type == null)
-                               type = Resolve (module, kind, ns, name, arity, loc);
+                               type = Resolve (module, kind, ns, name, arity);
 
                        return type;
                }
@@ -662,7 +781,7 @@ namespace Mono.CSharp
                                return member;
 
                        if (declaring_type == null) {
-                               if (declaring_type_predefined.Resolve (loc) == null)
+                               if (declaring_type_predefined.Resolve () == null)
                                        return null;
                        }
 
@@ -670,7 +789,7 @@ namespace Mono.CSharp
                                TypeSpec[] types = new TypeSpec[parameters_predefined.Length];
                                for (int i = 0; i < types.Length; ++i) {
                                        var p = parameters_predefined[i];
-                                       types[i] = p.Resolve (loc);
+                                       types[i] = p.Resolve ();
                                        if (types[i] == null)
                                                return null;
                                }
@@ -752,34 +871,15 @@ namespace Mono.CSharp
                if (t.IsPointer)
                        return IsUnmanagedType (GetElementType (t));
 
-               if (!IsValueType (t))
+               if (!TypeSpec.IsValueType (t))
                        return false;
 
                if (t.IsNested && t.DeclaringType.IsGenericOrParentIsGeneric)
                        return false;
 
                return true;
-       }
-
-       //
-       // Null is considered to be a reference type
-       //                      
-       public static bool IsReferenceType (TypeSpec t)
-       {
-               if (t.IsGenericParameter)
-                       return ((TypeParameterSpec) t).IsReferenceType;
-
-               return !t.IsStruct && !IsEnumType (t);
-       }                       
+       }       
                
-       public static bool IsValueType (TypeSpec t)
-       {
-               if (t.IsGenericParameter)
-                       return ((TypeParameterSpec) t).IsValueType;
-
-               return t.IsStruct || IsEnumType (t);
-       }
-
        public static bool IsFamilyAccessible (TypeSpec type, TypeSpec parent)
        {
 //             TypeParameter tparam = LookupTypeParameter (type);