Merge pull request #1439 from BrzVlad/feature-managed-allocator
[mono.git] / mcs / mcs / linq.cs
index 02042beaef0c6e2e83cd631f8eef9a3aa923b374..7f19c2d89b35524f73e49b9b00c4029326fb4276 100644 (file)
@@ -6,10 +6,10 @@
 // Dual licensed under the terms of the MIT X11 or GNU GPL
 //
 // Copyright 2007-2008 Novell, Inc
+// Copyright 2011 Xamarin Inc
 //
 
 using System;
-using System.Reflection;
 using System.Collections.Generic;
 
 namespace Mono.CSharp.Linq
@@ -17,7 +17,7 @@ namespace Mono.CSharp.Linq
        public class QueryExpression : AQueryClause
        {
                public QueryExpression (AQueryClause start)
-                       : base (null, null, Location.Null)
+                       : base (null, null, start.Location)
                {
                        this.next = start;
                }
@@ -64,7 +64,7 @@ namespace Mono.CSharp.Linq
                        {
                        }
 
-                       protected override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
+                       public override void Error_TypeDoesNotContainDefinition (ResolveContext ec, TypeSpec type, string name)
                        {
                                ec.Report.Error (1935, loc, "An implementation of `{0}' query expression pattern could not be found. " +
                                        "Are you missing `System.Linq' using directive or `System.Core.dll' assembly reference?",
@@ -85,6 +85,13 @@ namespace Mono.CSharp.Linq
                                return rmg;
                        }
 
+                       protected override Expression DoResolveDynamic (ResolveContext ec, Expression memberExpr)
+                       {
+                               ec.Report.Error (1979, loc,
+                                       "Query expressions with a source or join sequence of type `dynamic' are not allowed");
+                               return null;
+                       }
+
                        #region IErrorHandler Members
 
                        bool OverloadResolver.IErrorHandler.AmbiguousCandidates (ResolveContext ec, MemberSpec best, MemberSpec ambiguous)
@@ -113,17 +120,17 @@ namespace Mono.CSharp.Linq
                                if (source_type != null) {
                                        Argument a = arguments[0];
 
-                                       if (TypeManager.IsGenericType (source_type) && TypeManager.ContainsGenericParameters (source_type)) {
+                                       if (TypeManager.IsGenericType (source_type) && InflatedTypeSpec.ContainsTypeParameter (source_type)) {
                                                TypeInferenceContext tic = new TypeInferenceContext (source_type.TypeArguments);
                                                tic.OutputTypeInference (rc, a.Expr, source_type);
                                                if (tic.FixAllTypes (rc)) {
-                                                       source_type = source_type.GetDefinition ().MakeGenericType (tic.InferredTypeArguments);
+                                                       source_type = source_type.GetDefinition ().MakeGenericType (rc, tic.InferredTypeArguments);
                                                }
                                        }
 
                                        if (!Convert.ImplicitConversionExists (rc, a.Expr, source_type)) {
                                                rc.Report.Error (1936, loc, "An implementation of `{0}' query expression pattern for source type `{1}' could not be found",
-                                                       best.Name, TypeManager.CSharpName (a.Type));
+                                                       best.Name, a.Type.GetSignatureForError ());
                                                return true;
                                        }
                                }
@@ -276,6 +283,12 @@ namespace Mono.CSharp.Linq
                        this.identifier = identifier;
                }
 
+               public RangeVariable Identifier {
+                       get {
+                               return identifier;
+                       }
+               }
+
                public FullNamedExpression IdentifierType { get; set; }
 
                protected Invocation CreateCastExpression (Expression lSide)
@@ -342,6 +355,12 @@ namespace Mono.CSharp.Linq
                        }
                }
 
+               public bool IsParameter {
+                       get {
+                               return false;
+                       }
+               }
+
                public Location Location { get; private set; }
 
                public string Name { get; private set; }
@@ -350,8 +369,6 @@ namespace Mono.CSharp.Linq
 
                public Expression CreateReferenceExpression (ResolveContext rc, Location loc)
                {
-                       Expression expr = null;
-
                        // 
                        // We know the variable name is somewhere in the scope. This generates
                        // an access expression from current block
@@ -364,6 +381,7 @@ namespace Mono.CSharp.Linq
                                                if (p.Name == Name)
                                                        return pb.GetParameterReference (i, loc);
 
+                                               Expression expr = null;
                                                var tp = p as QueryBlock.TransparentParameter;
                                                while (tp != null) {
                                                        if (expr == null)
@@ -380,8 +398,6 @@ namespace Mono.CSharp.Linq
                                                        tp = tp.Parent as QueryBlock.TransparentParameter;
                                                }
                                        }
-
-                                       expr = null;
                                }
 
                                if (pb == block)
@@ -392,7 +408,7 @@ namespace Mono.CSharp.Linq
                }
        }
 
-       class QueryStartClause : ARangeVariableQueryClause
+       public class QueryStartClause : ARangeVariableQueryClause
        {
                public QueryStartClause (QueryBlock block, Expression expr, RangeVariable identifier, Location loc)
                        : base (block, identifier, expr, loc)
@@ -402,19 +418,6 @@ namespace Mono.CSharp.Linq
 
                public override Expression BuildQueryClause (ResolveContext ec, Expression lSide, Parameter parameter)
                {
-/*
-                       expr = expr.Resolve (ec);
-                       if (expr == null)
-                               return null;
-
-                       if (expr.Type == InternalType.Dynamic || expr.Type == TypeManager.void_type) {
-                               ec.Report.Error (1979, expr.Location,
-                                       "Query expression with a source or join sequence of type `{0}' is not allowed",
-                                       TypeManager.CSharpName (expr.Type));
-                               return null;
-                       }
-*/
-
                        if (IdentifierType != null)
                                expr = CreateCastExpression (expr);
 
@@ -452,6 +455,12 @@ namespace Mono.CSharp.Linq
                        }
                }
 
+               public Expression SelectorExpression {
+                       get {
+                               return element_selector;
+                       }
+               }
+
                protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
                {
                        base.CreateArguments (ec, parameter, ref args);
@@ -480,6 +489,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "GroupBy"; }
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class Join : SelectMany
@@ -493,6 +507,18 @@ namespace Mono.CSharp.Linq
                        this.inner_selector = innerSelector;
                }
 
+               public QueryBlock InnerSelector {
+                       get {
+                               return inner_selector;
+                       }
+               }
+               
+               public QueryBlock OuterSelector {
+                       get {
+                               return outer_selector;
+                       }
+               }
+
                protected override void CreateArguments (ResolveContext ec, Parameter parameter, ref Arguments args)
                {
                        args = new Arguments (4);
@@ -526,6 +552,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "Join"; }
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class GroupJoin : Join
@@ -547,6 +578,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "GroupJoin"; }
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class Let : ARangeVariableQueryClause
@@ -565,6 +601,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "Select"; }
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class Select : AQueryClause
@@ -590,6 +631,12 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "Select"; }
                }
+               
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
+
        }
 
        public class SelectMany : ARangeVariableQueryClause
@@ -627,7 +674,7 @@ namespace Mono.CSharp.Linq
                        } else {
                                result_selector_expr = CreateRangeVariableType (ec, parameter, target, new SimpleName (target.Name, target.Location));
 
-                               result_block = new QueryBlock (ec.Compiler, block.Parent, block.StartLocation);
+                               result_block = new QueryBlock (block.Parent, block.StartLocation);
                                result_block.SetParameters (parameter, target_param);
                        }
 
@@ -641,11 +688,16 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "SelectMany"; }
                }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class Where : AQueryClause
        {
-               public Where (QueryBlock block, BooleanExpression expr, Location loc)
+               public Where (QueryBlock block, Expression expr, Location loc)
                        : base (block, expr, loc)
                {
                }
@@ -653,6 +705,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "Where"; }
                }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class OrderByAscending : AQueryClause
@@ -665,6 +722,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "OrderBy"; }
                }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class OrderByDescending : AQueryClause
@@ -677,6 +739,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "OrderByDescending"; }
                }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class ThenByAscending : OrderByAscending
@@ -689,6 +756,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "ThenBy"; }
                }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        public class ThenByDescending : OrderByDescending
@@ -701,6 +773,11 @@ namespace Mono.CSharp.Linq
                protected override string MethodName {
                        get { return "ThenByDescending"; }
                }
+
+               public override object Accept (StructuralVisitor visitor)
+               {
+                       return visitor.Visit (this);
+               }
        }
 
        //
@@ -727,22 +804,21 @@ namespace Mono.CSharp.Linq
                                Identifier = identifier.Name;
                        }
 
-                       public new static void Reset ()
+                       public static void Reset ()
                        {
                                Counter = 0;
                        }
                }
 
-               public QueryBlock (CompilerContext ctx, Block parent, Location start)
-                       : base (parent, ParametersCompiled.EmptyReadOnlyParameters, start)
+               public QueryBlock (Block parent, Location start)
+                       : base (parent, ParametersCompiled.EmptyReadOnlyParameters, start, Flags.CompilerGenerated)
                {
-                       flags |= Flags.CompilerGenerated;
                }
 
                public void AddRangeVariable (RangeVariable variable)
                {
                        variable.Block = this;
-                       AddLocalName (variable.Name, variable);
+                       TopBlock.AddLocalName (variable.Name, variable, true);
                }
 
                public override void Error_AlreadyDeclared (string name, INamedBlockVariable variable, string reason)