importing messaging-2008 branch to trunk.
[mono.git] / mcs / mcs / linq.cs
index a7b76aff7d95b30af94362e17d5caa89e1e432b8..bff39a7238b176a07d58dc5f86509cf23fa3655f 100644 (file)
@@ -39,8 +39,18 @@ namespace Mono.CSharp.Linq
 
                public override Expression DoResolve (EmitContext ec)
                {
+                       int counter = TransparentParameter.Counter;
+
                        Expression e = BuildQueryClause (ec, null, null, null);
                        e = e.Resolve (ec);
+
+                       //
+                       // Reset counter in probing mode to ensure that all transparent
+                       // identifier anonymous types are created only once
+                       //
+                       if (ec.IsInProbingMode)
+                               TransparentParameter.Counter = counter;
+
                        return e;
                }
 
@@ -90,7 +100,7 @@ namespace Mono.CSharp.Linq
                        public bool NoExactMatch (EmitContext ec, MethodBase method)
                        {
 #if GMCS_SOURCE                                
-                               ParameterData pd = TypeManager.GetParameterData (method);
+                               AParametersCollection pd = TypeManager.GetParameterData (method);
                                Type source_type = pd.ExtensionMethodType;
                                if (source_type != null) {
                                        Argument a = (Argument) Arguments [0];
@@ -197,22 +207,10 @@ namespace Mono.CSharp.Linq
                {
                        Parameters p = new Parameters (parameters);
 
-                       LambdaExpression selector = new LambdaExpression (
-                               null, null, (TypeContainer)ec.TypeContainer, p, ec.CurrentBlock, loc);
+                       LambdaExpression selector = new LambdaExpression (loc);
                        selector.Block = new SelectorBlock (ec.CurrentBlock, p, ti, loc);
                        selector.Block.AddStatement (new ContextualReturn (expr));
 
-                       if (!ec.IsInProbingMode) {
-                               selector.CreateAnonymousHelpers ();
-
-                               // TODO: I am not sure where this should be done to work
-                               // correctly with anonymous containerss and was called only once
-                               // FIXME: selector.RootScope == null for nested anonymous
-                               // methods only ?
-                               if (selector.RootScope != null)
-                                       selector.RootScope.DefineType ();
-                       }
-                       
                        return new Argument (selector);
                }
 
@@ -223,6 +221,11 @@ namespace Mono.CSharp.Linq
 
                protected abstract string MethodName { get; }
 
+               public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+               {
+                       // Nothing to mutate
+               }
+
                public virtual AQueryClause Next {
                        set {
                                next = value;
@@ -344,9 +347,9 @@ namespace Mono.CSharp.Linq
        public class Cast : QueryStartClause
        {
                // We don't have to clone cast type
-               readonly Expression type_expr;
+               readonly FullNamedExpression type_expr;
 
-               public Cast (Expression type, Expression expr)
+               public Cast (FullNamedExpression type, Expression expr)
                        : base (expr)
                {
                        this.type_expr = type;
@@ -354,7 +357,7 @@ namespace Mono.CSharp.Linq
                
                public override Expression BuildQueryClause (EmitContext ec, Expression lSide, Parameter parameter, TransparentIdentifiersScope ti)
                {
-                       lSide = CreateQueryExpression (expr, new TypeArguments (loc, type_expr), null);
+                       lSide = CreateQueryExpression (expr, new TypeArguments (type_expr), null);
                        if (next != null)
                                return next.BuildQueryClause (ec, lSide, parameter, ti);
 
@@ -511,17 +514,16 @@ namespace Mono.CSharp.Linq
                                        //
                                        // Spread resolved initializer type
                                        //
-                                       parameter.ParameterType = type;
-                                       parameter.Resolve (ec);
+                                       ((ImplicitLambdaParameter) parameter).Type = type;
                                }
 
                                return e;
                        }
 
-                       protected override void Error_InvalidInitializer (Expression initializer)
+                       protected override void Error_InvalidInitializer (string initializer)
                        {
                                Report.Error (1932, loc, "A range variable `{0}' cannot be initialized with `{1}'",
-                                       Name, initializer.GetSignatureForError ());
+                                       Name, initializer);
                        }                       
                }
 
@@ -684,6 +686,11 @@ namespace Mono.CSharp.Linq
                        {
                                throw new NotSupportedException ();
                        }
+
+                       public override void MutateHoistedGenericType (AnonymousMethodStorey storey)
+                       {
+                               throw new NotSupportedException ();
+                       }
                }
 
                public ImplicitQueryParameter (LocatedToken variable)
@@ -698,11 +705,11 @@ namespace Mono.CSharp.Linq
        //
        public class TransparentParameter : ImplicitLambdaParameter
        {
-               static int counter;
+               public static int Counter;
                const string ParameterNamePrefix = "<>__TranspIdent";
 
                public TransparentParameter (Location loc)
-                       : base (ParameterNamePrefix + counter++, loc)
+                       : base (ParameterNamePrefix + Counter++, loc)
                {
                }
        }
@@ -791,26 +798,26 @@ namespace Mono.CSharp.Linq
        //
        // This block is actually never used, it is used by parser only
        //
-       public class QueryBlock : Block
+       public class QueryBlock : ExplicitBlock
        {
-               Hashtable range_variables = new Hashtable ();
-
                public QueryBlock (Block parent, Location start)
                        : base (parent, start, Location.Null)
                {
+                       range_variables = new System.Collections.Specialized.HybridDictionary ();
                }
 
                protected override void AddVariable (LocalInfo li)
                {
                        string name = li.Name;
                        if (range_variables.Contains (name)) {
-                               Location conflict = (Location)range_variables [name];
-                               Report.SymbolRelatedToPreviousError (conflict, name);
+                               LocalInfo conflict = (LocalInfo) range_variables [name];
+                               Report.SymbolRelatedToPreviousError (conflict.Location, name);
                                Error_AlreadyDeclared (li.Location, name);
                                return;
                        }
 
-                       range_variables.Add (name, li.Location);
+                       range_variables.Add (name, li);
+                       Explicit.AddKnownVariable (name, li);
                }
                
                protected override void Error_AlreadyDeclared (Location loc, string var, string reason)