Merge pull request #807 from akoeplinger/fix-fonttest
[mono.git] / mcs / mcs / typemanager.cs
index fd56706c1252eb2b0f04be54acd172d7a10a958e..870b7be2a754773b25c721b29e0fb28b38d4315c 100644 (file)
@@ -144,7 +144,7 @@ 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);
+                               var found = PredefinedType.Resolve (module, p.Kind, p.Namespace, p.Name, p.Arity, true, true);
                                if (found == null || found == p)
                                        continue;
 
@@ -186,7 +186,9 @@ namespace Mono.CSharp
                public readonly PredefinedType IsVolatile;
                public readonly PredefinedType IEnumeratorGeneric;
                public readonly PredefinedType IListGeneric;
+               public readonly PredefinedType IReadOnlyListGeneric;
                public readonly PredefinedType ICollectionGeneric;
+               public readonly PredefinedType IReadOnlyCollectionGeneric;
                public readonly PredefinedType IEnumerableGeneric;
                public readonly PredefinedType Nullable;
                public readonly PredefinedType Activator;
@@ -228,6 +230,9 @@ namespace Mono.CSharp
                public readonly PredefinedType Action;
                public readonly PredefinedType Task;
                public readonly PredefinedType TaskGeneric;
+               public readonly PredefinedType IAsyncStateMachine;
+               public readonly PredefinedType INotifyCompletion;
+               public readonly PredefinedType ICriticalNotifyCompletion;
 
                public PredefinedTypes (ModuleContainer module)
                {
@@ -243,7 +248,9 @@ namespace Mono.CSharp
                        IsVolatile = new PredefinedType (module, MemberKind.Class, "System.Runtime.CompilerServices", "IsVolatile");
                        IEnumeratorGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerator", 1);
                        IListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IList", 1);
+                       IReadOnlyListGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IReadOnlyList", 1);
                        ICollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "ICollection", 1);
+                       IReadOnlyCollectionGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IReadOnlyCollection", 1);
                        IEnumerableGeneric = new PredefinedType (module, MemberKind.Interface, "System.Collections.Generic", "IEnumerable", 1);
                        Nullable = new PredefinedType (module, MemberKind.Struct, "System", "Nullable", 1);
                        Activator = new PredefinedType (module, MemberKind.Class, "System", "Activator");
@@ -276,6 +283,9 @@ namespace Mono.CSharp
                        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);
+                       IAsyncStateMachine = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "IAsyncStateMachine");
+                       INotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "INotifyCompletion");
+                       ICriticalNotifyCompletion = new PredefinedType (module, MemberKind.Interface, "System.Runtime.CompilerServices", "ICriticalNotifyCompletion");
 
                        //
                        // Define types which are used for comparison. It does not matter
@@ -288,13 +298,19 @@ namespace Mono.CSharp
                                ArgIterator.TypeSpec.IsSpecialRuntimeType = true;
 
                        if (IEnumerableGeneric.Define ())
-                               IEnumerableGeneric.TypeSpec.IsGenericIterateInterface = true;
+                               IEnumerableGeneric.TypeSpec.IsArrayGenericInterface = true;
 
                        if (IListGeneric.Define ())
-                               IListGeneric.TypeSpec.IsGenericIterateInterface = true;
+                               IListGeneric.TypeSpec.IsArrayGenericInterface = true;
+
+                       if (IReadOnlyListGeneric.Define ())
+                               IReadOnlyListGeneric.TypeSpec.IsArrayGenericInterface = true;
 
                        if (ICollectionGeneric.Define ())
-                               ICollectionGeneric.TypeSpec.IsGenericIterateInterface = true;
+                               ICollectionGeneric.TypeSpec.IsArrayGenericInterface = true;
+
+                       if (IReadOnlyCollectionGeneric.Define ())
+                               IReadOnlyCollectionGeneric.TypeSpec.IsArrayGenericInterface = true;
 
                        if (Nullable.Define ())
                                Nullable.TypeSpec.IsNullableType = true;
@@ -312,16 +328,29 @@ namespace Mono.CSharp
        {
                public readonly PredefinedMember<MethodSpec> ActivatorCreateInstance;
                public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderCreate;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderStart;
                public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetResult;
                public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetException;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderSetStateMachine;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompleted;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderOnCompletedUnsafe;
                public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderTask;
                public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericCreate;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericStart;
                public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetResult;
                public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetException;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericSetStateMachine;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompleted;
+               public readonly PredefinedMember<MethodSpec> AsyncTaskMethodBuilderGenericOnCompletedUnsafe;
                public readonly PredefinedMember<PropertySpec> AsyncTaskMethodBuilderGenericTask;
                public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderCreate;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderStart;
                public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetException;
                public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetResult;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderSetStateMachine;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompleted;
+               public readonly PredefinedMember<MethodSpec> AsyncVoidMethodBuilderOnCompletedUnsafe;
+               public readonly PredefinedMember<MethodSpec> AsyncStateMachineAttributeCtor;
                public readonly PredefinedMember<MethodSpec> DebuggerBrowsableAttributeCtor;
                public readonly PredefinedMember<MethodSpec> DecimalCtor;
                public readonly PredefinedMember<MethodSpec> DecimalCtorInt;
@@ -363,6 +392,8 @@ namespace Mono.CSharp
                        var atypes = module.PredefinedAttributes;
                        var btypes = module.Compiler.BuiltinTypes;
 
+                       var tp = new TypeParameter (0, new MemberName ("T"), null, null, Variance.None);
+
                        ActivatorCreateInstance = new PredefinedMember<MethodSpec> (module, types.Activator,
                                MemberFilter.Method ("CreateInstance", 1, ParametersCompiled.EmptyReadOnlyParameters, null));
 
@@ -372,10 +403,52 @@ namespace Mono.CSharp
                        AsyncTaskMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
                                MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
 
+                       AsyncTaskMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               "SetStateMachine", MemberKind.Method, () => new[] {
+                                               types.IAsyncStateMachine.TypeSpec
+                               }, btypes.Void);
+
                        AsyncTaskMethodBuilderSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
                                MemberFilter.Method ("SetException", 0,
                                ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
 
+                       AsyncTaskMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Method ("AwaitOnCompleted", 2,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                               new ParameterData (null, Parameter.Modifier.REF)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                               new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncTaskMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                               new ParameterData (null, Parameter.Modifier.REF)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                               new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncTaskMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilder,
+                               MemberFilter.Method ("Start", 1,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                       }, false),
+                                       btypes.Void));
+
                        AsyncTaskMethodBuilderTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilder,
                                MemberFilter.Property ("Task", null));
 
@@ -385,12 +458,54 @@ namespace Mono.CSharp
                        AsyncTaskMethodBuilderGenericSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
                                "SetResult", MemberKind.Method, () => new TypeSpec[] {
                                                types.AsyncTaskMethodBuilderGeneric.TypeSpec.MemberDefinition.TypeParameters[0]
-                               });
+                               }, btypes.Void);
+
+                       AsyncTaskMethodBuilderGenericSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               "SetStateMachine", MemberKind.Method, () => new[] {
+                                               types.IAsyncStateMachine.TypeSpec
+                               }, btypes.Void);
 
                        AsyncTaskMethodBuilderGenericSetException = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
                                MemberFilter.Method ("SetException", 0,
                                ParametersCompiled.CreateFullyResolved (btypes.Exception), btypes.Void));
 
+                       AsyncTaskMethodBuilderGenericOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Method ("AwaitOnCompleted", 2,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                               new ParameterData (null, Parameter.Modifier.REF)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                               new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncTaskMethodBuilderGenericOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                               new ParameterData (null, Parameter.Modifier.REF)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                               new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncTaskMethodBuilderGenericStart = new PredefinedMember<MethodSpec> (module, types.AsyncTaskMethodBuilderGeneric,
+                               MemberFilter.Method ("Start", 1,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                       }, false),
+                                       btypes.Void));
+
                        AsyncTaskMethodBuilderGenericTask = new PredefinedMember<PropertySpec> (module, types.AsyncTaskMethodBuilderGeneric,
                                MemberFilter.Property ("Task", null));
 
@@ -403,6 +518,52 @@ namespace Mono.CSharp
                        AsyncVoidMethodBuilderSetResult = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
                                MemberFilter.Method ("SetResult", 0, ParametersCompiled.EmptyReadOnlyParameters, btypes.Void));
 
+                       AsyncVoidMethodBuilderSetStateMachine = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               "SetStateMachine", MemberKind.Method, () => new[] {
+                                               types.IAsyncStateMachine.TypeSpec
+                               }, btypes.Void);
+
+                       AsyncVoidMethodBuilderOnCompleted = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               MemberFilter.Method ("AwaitOnCompleted", 2,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                               new ParameterData (null, Parameter.Modifier.REF)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                               new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncVoidMethodBuilderOnCompletedUnsafe = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               MemberFilter.Method ("AwaitUnsafeOnCompleted", 2,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                               new ParameterData (null, Parameter.Modifier.REF)
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                               new TypeParameterSpec (1, tp, SpecialConstraint.None, Variance.None, null)
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncVoidMethodBuilderStart = new PredefinedMember<MethodSpec> (module, types.AsyncVoidMethodBuilder,
+                               MemberFilter.Method ("Start", 1,
+                                       new ParametersImported (
+                                               new[] {
+                                                               new ParameterData (null, Parameter.Modifier.REF),
+                                                       },
+                                               new[] {
+                                                               new TypeParameterSpec (0, tp, SpecialConstraint.None, Variance.None, null),
+                                                       }, false),
+                                       btypes.Void));
+
+                       AsyncStateMachineAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.AsyncStateMachine,
+                               MemberFilter.Constructor (ParametersCompiled.CreateFullyResolved (
+                                       btypes.Type)));
+
                        DebuggerBrowsableAttributeCtor = new PredefinedMember<MethodSpec> (module, atypes.DebuggerBrowsable,
                                MemberFilter.Constructor (null));
 
@@ -464,7 +625,6 @@ namespace Mono.CSharp
                                                false),
                                btypes.Int));
 
-                       var tp = new TypeParameter(0, new MemberName("T"), null, null, Variance.None);
                        InterlockedCompareExchange_T = new PredefinedMember<MethodSpec> (module, types.Interlocked,
                                MemberFilter.Method ("CompareExchange", 1,
                                        new ParametersImported (
@@ -541,6 +701,7 @@ namespace Mono.CSharp
                readonly MemberKind kind;
                protected readonly ModuleContainer module;
                protected TypeSpec type;
+               bool defined;
 
                public PredefinedType (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
                        : this (module, kind, ns, name)
@@ -603,7 +764,11 @@ namespace Mono.CSharp
                        if (type != null)
                                return true;
 
-                       type = Resolve (module, kind, ns, name, arity, false);
+                       if (!defined) {
+                               defined = true;
+                               type = Resolve (module, kind, ns, name, arity, false, false);
+                       }
+
                        return type != null;
                }
 
@@ -612,15 +777,20 @@ namespace Mono.CSharp
                        return ns + "." + name;
                }
 
-               public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity)
+               public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool required, bool reportErrors)
                {
-                       return Resolve (module, kind, ns, name, arity, true);
-               }
+                       //
+                       // Cannot call it with true because it could create non-existent namespaces for
+                       // predefined types. It's set to true only for build-in types which all must
+                       // exist therefore it does not matter, for predefined types we don't want to create
+                       // fake namespaces when type is optional and does not exist (e.g. System.Linq).
+                       //
+                       Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, required);
+
+                       IList<TypeSpec> found = null;
+                       if (type_ns != null)
+                               found = type_ns.GetAllTypes (name);
 
-               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 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);
@@ -675,15 +845,22 @@ namespace Mono.CSharp
                        }
 
                        if (best_match == null && reportErrors) {
-                               Location loc;
-                               if (found[0].MemberDefinition is MemberCore) {
-                                       loc = ((MemberCore) found[0].MemberDefinition).Location;
+                               var found_member = found[0];
+
+                               if (found_member.Kind == MemberKind.MissingType) {
+                                       // CSC: should be different error number
+                                       module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is defined in an assembly that is not referenced.", ns, name);
                                } else {
-                                       loc = Location.Null;
-                                       module.Compiler.Report.SymbolRelatedToPreviousError (found[0]);
-                               }
+                                       Location loc;
+                                       if (found_member.MemberDefinition is MemberCore) {
+                                               loc = ((MemberCore) found_member.MemberDefinition).Location;
+                                       } else {
+                                               loc = Location.Null;
+                                               module.Compiler.Report.SymbolRelatedToPreviousError (found_member);
+                                       }
 
-                               module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
+                                       module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
+                               }
                        }
 
                        return best_match;
@@ -692,13 +869,13 @@ namespace Mono.CSharp
                public TypeSpec Resolve ()
                {
                        if (type == null)
-                               type = Resolve (module, kind, ns, name, arity);
+                               type = Resolve (module, kind, ns, name, arity, false, true);
 
                        return type;
                }
        }
 
-       class PredefinedMember<T> where T : MemberSpec
+       public class PredefinedMember<T> where T : MemberSpec
        {
                readonly ModuleContainer module;
                T member;
@@ -743,8 +920,8 @@ namespace Mono.CSharp
                        };
                }
 
-               public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder)
-                       : this (module, type, new MemberFilter (name, 0, kind, null, null))
+               public PredefinedMember (ModuleContainer module, PredefinedType type, string name, MemberKind kind, Func<TypeSpec[]> typesBuilder, TypeSpec returnType)
+                       : this (module, type, new MemberFilter (name, 0, kind, null, returnType))
                {
                        filter_builder = typesBuilder;
                }
@@ -815,17 +992,22 @@ namespace Mono.CSharp
                }
        }
 
-       partial class TypeManager {
-
-       /// <summary>
-       ///   Returns the C# name of a type if possible, or the full type name otherwise
-       /// </summary>
-       static public string CSharpName (TypeSpec t)
+       public class AwaiterDefinition
        {
-               return t.GetSignatureForError ();
+               public PropertySpec IsCompleted { get; set; }
+               public MethodSpec GetResult { get; set; }
+               public bool INotifyCompletion { get; set; }
+
+               public bool IsValidPattern {
+                       get {
+                               return IsCompleted != null && GetResult != null && IsCompleted.HasGet;
+                       }
+               }
        }
 
-       static public string CSharpName (IList<TypeSpec> types)
+       partial class TypeManager {
+
+       static public string CSharpName(IList<TypeSpec> types)
        {
                if (types.Count == 0)
                        return string.Empty;
@@ -835,7 +1017,7 @@ namespace Mono.CSharp
                        if (i > 0)
                                sb.Append (",");
 
-                       sb.Append (CSharpName (types [i]));
+                       sb.Append (types [i].GetSignatureForError ());
                }
                return sb.ToString ();
        }
@@ -923,7 +1105,7 @@ namespace Mono.CSharp
                rc.Compiler.Report.SymbolRelatedToPreviousError (t);
                rc.Compiler.Report.Error (208, loc,
                        "Cannot take the address of, get the size of, or declare a pointer to a managed type `{0}'",
-                       CSharpName (t));
+                       t.GetSignatureForError ());
 
                return false;   
        }