Author: marek
Date: 2008-01-14 13:06:47 -0500 (Mon, 14 Jan 2008)
New Revision: 92889

Modified:
   trunk/mcs/mcs/ChangeLog
   trunk/mcs/mcs/anonymous.cs
   trunk/mcs/mcs/assign.cs
   trunk/mcs/mcs/class.cs
   trunk/mcs/mcs/convert.cs
   trunk/mcs/mcs/delegate.cs
   trunk/mcs/mcs/ecore.cs
   trunk/mcs/mcs/expression.cs
   trunk/mcs/mcs/iterators.cs
   trunk/mcs/mcs/lambda.cs
   trunk/mcs/mcs/parameter.cs
   trunk/mcs/mcs/statement.cs
   trunk/mcs/mcs/typemanager.cs
Log:
2008-01-14  Marek Safar  <[EMAIL PROTECTED]>

        * typemanager.cs, lambda.cs, parameter.cs, ecore.cs, class.cs, 
delegate.cs,
        iterators.cs, convert.cs, assign.cs, anonymous.cs, expression.cs,
        statement.cs: The first expression tree implementation drop, mostly
        infrastructure work.



Modified: trunk/mcs/mcs/ChangeLog
===================================================================
--- trunk/mcs/mcs/ChangeLog     2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/ChangeLog     2008-01-14 18:06:47 UTC (rev 92889)
@@ -1,5 +1,12 @@
 2008-01-14  Marek Safar  <[EMAIL PROTECTED]>
 
+       * typemanager.cs, lambda.cs, parameter.cs, ecore.cs, class.cs, 
delegate.cs,
+       iterators.cs, convert.cs, assign.cs, anonymous.cs, expression.cs,
+       statement.cs: The first expression tree implementation drop, mostly
+       infrastructure work.
+
+2008-01-14  Marek Safar  <[EMAIL PROTECTED]>
+
        * ecore.cs (IsNestedChild): Refactored.
 
 2008-01-11  Marek Safar  <[EMAIL PROTECTED]>

Modified: trunk/mcs/mcs/anonymous.cs
===================================================================
--- trunk/mcs/mcs/anonymous.cs  2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/anonymous.cs  2008-01-14 18:06:47 UTC (rev 92889)
@@ -1124,6 +1124,8 @@
 
                public bool CreateAnonymousHelpers ()
                {
+                       // FIXME: this polutes expression trees implementation
+
                        Report.Debug (64, "ANONYMOUS METHOD EXPRESSION CREATE 
ROOT SCOPE",
                                      this, Host, container, loc);
 
@@ -1164,21 +1166,31 @@
                        }
                }
 
-               protected Expression CompatibleChecks (EmitContext ec, Type 
delegate_type)
+               protected Type CompatibleChecks (EmitContext ec, Type 
delegate_type)
                {
                        if (!ec.IsAnonymousMethodAllowed) {
                                Report.Error (1706, loc, "Anonymous methods and 
lambda expressions cannot be used in the current context");
                                return null;
                        }
                        
-                       if (!TypeManager.IsDelegateType (delegate_type)){
-                               Report.Error (1660, loc,
-                                             "Cannot convert `{0}' to type " +
-                                             "`{1}' because it is not a 
delegate type",
-                                             GetSignatureForError (), 
TypeManager.CSharpName (delegate_type));
+                       if (TypeManager.IsDelegateType (delegate_type))
+                               return delegate_type;
+
+#if GMCS_SOURCE
+                       if (TypeManager.DropGenericTypeArguments 
(delegate_type) == TypeManager.expression_type) {
+                               delegate_type = TypeManager.GetTypeArguments 
(delegate_type) [0];
+                               if (TypeManager.IsDelegateType (delegate_type))
+                                       return delegate_type;
+
+                               Report.Error (835, loc, "Cannot convert `{0}' 
to an expression tree of non-delegate type `{1}'",
+                                       GetSignatureForError (), 
TypeManager.CSharpName (delegate_type));
                                return null;
                        }
-                       return this;
+#endif
+
+                       Report.Error (1660, loc, "Cannot convert `{0}' to 
non-delegate type `{1}'",
+                                     GetSignatureForError (), 
TypeManager.CSharpName (delegate_type));
+                       return null;
                }
 
                protected bool VerifyExplicitParameters (Type delegate_type, 
ParameterData parameters, bool ignore_error)
@@ -1298,9 +1310,10 @@
                // Returns AnonymousMethod container if this anonymous method
                // expression can be implicitly converted to the delegate type 
`delegate_type'
                //
-               public AnonymousMethod Compatible (EmitContext ec, Type 
delegate_type)
+               public Expression Compatible (EmitContext ec, Type type)
                {
-                       if (CompatibleChecks (ec, delegate_type) == null)
+                       Type delegate_type = CompatibleChecks (ec, type);
+                       if (delegate_type == null)
                                return null;
 
                        //
@@ -1330,12 +1343,22 @@
                                      TypeManager.IsGenericType 
(delegate_type), loc);
 
                        try {
-                               return CompatibleMethod (ec, null, return_type, 
delegate_type);
+                               AnonymousMethod am = CompatibleMethod (ec, 
null, return_type, delegate_type);
+                               if (am != null && delegate_type != type)
+                                       return CreateExpressionTree (ec, 
delegate_type);
+
+                               return am;
                        } catch (Exception e) {
                                throw new InternalErrorException (e, loc);
                        }
                }
 
+               protected virtual Expression CreateExpressionTree (EmitContext 
ec, Type delegate_type)
+               {
+                       Report.Error (1946, loc, "An anonymous method cannot be 
converted to an expression tree");
+                       return null;
+               }
+
                protected virtual Parameters ResolveParameters (EmitContext ec, 
TypeInferenceContext tic, Type delegate_type)
                {
                        ParameterData delegate_parameters = 
TypeManager.GetDelegateParameters (delegate_type);
@@ -1437,10 +1460,8 @@
                }
        }
 
-       public abstract class AnonymousContainer : IAnonymousContainer
+       public abstract class AnonymousContainer : Expression, 
IAnonymousContainer
        {
-               public readonly Location Location;
-
                public Parameters Parameters;
 
                //
@@ -1476,7 +1497,7 @@
                        this.generic = generic;
                        this.Parameters = parameters;
                        this.Block = block;
-                       this.Location = loc;
+                       this.loc = loc;
 
                        block.AnonymousContainer = this;
                }
@@ -1497,8 +1518,6 @@
                        get;
                }
 
-               public abstract string GetSignatureForError ();
-
                public bool Compatible (EmitContext ec)
                {
                        // REFACTOR: The method should be refactor, many of the
@@ -1570,8 +1589,6 @@
                        return res;
                }
 
-               public abstract Expression Resolve (EmitContext ec);
-
                public virtual bool Define (EmitContext ec)
                {
                        Report.Debug (64, "DEFINE ANONYMOUS METHOD #3", this, 
ec, aec, Block);
@@ -1595,6 +1612,11 @@
 
                protected abstract Method DoCreateMethodHost (EmitContext ec);
 
+               public override void Emit (EmitContext ec)
+               {
+                       throw new NotSupportedException ();
+               }
+
                public Block Container {
                        get { return container; }
                }
@@ -1762,7 +1784,7 @@
                                scope == null ? Modifiers.PRIVATE : 
Modifiers.INTERNAL, member_name, Parameters);
                }
 
-               public override Expression Resolve (EmitContext ec)
+               public override Expression DoResolve (EmitContext ec)
                {
                        if (!Define (ec))
                                return null;

Modified: trunk/mcs/mcs/assign.cs
===================================================================
--- trunk/mcs/mcs/assign.cs     2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/assign.cs     2008-01-14 18:06:47 UTC (rev 92889)
@@ -282,6 +282,12 @@
                {
                        this.is_embedded = true;
                }
+               
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       Report.Error (832, loc, "An expression tree cannot 
contain an assignment operator");
+                       return null;
+               }
 
                protected virtual Assign GetEmbeddedAssign (Location loc)
                {

Modified: trunk/mcs/mcs/class.cs
===================================================================
--- trunk/mcs/mcs/class.cs      2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/class.cs      2008-01-14 18:06:47 UTC (rev 92889)
@@ -3081,8 +3081,10 @@
                {
                        base.Emit ();
 
+#if GMCS_SOURCE
                        if ((ModFlags & Modifiers.METHOD_EXTENSION) != 0)
                                TypeBuilder.SetCustomAttribute 
(TypeManager.extension_attribute_attr);
+#endif                 
                }
 
                public override TypeExpr[] GetClassBases (out TypeExpr 
base_class)
@@ -4565,9 +4567,11 @@
                                MethodData.Emit (Parent);
                                base.Emit ();
                                
+#if GMCS_SOURCE                                
                                if ((ModFlags & Modifiers.METHOD_EXTENSION) != 
0)
                                        MethodBuilder.SetCustomAttribute 
(TypeManager.extension_attribute_attr);
-                               
+#endif
+
                                Block = null;
                                MethodData = null;
                        } catch {

Modified: trunk/mcs/mcs/convert.cs
===================================================================
--- trunk/mcs/mcs/convert.cs    2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/convert.cs    2008-01-14 18:06:47 UTC (rev 92889)
@@ -1405,10 +1405,9 @@
 
                        if (expr_type == TypeManager.anonymous_method_type){
                                AnonymousMethodExpression ame = 
(AnonymousMethodExpression) expr;
-
-                               AnonymousMethod am = ame.Compatible (ec, 
target_type);
+                               Expression am = ame.Compatible (ec, 
target_type);
                                if (am != null)
-                                       return am.Resolve (ec);
+                                       return am.DoResolve (ec);
                        }
 
                        return null;

Modified: trunk/mcs/mcs/delegate.cs
===================================================================
--- trunk/mcs/mcs/delegate.cs   2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/delegate.cs   2008-01-14 18:06:47 UTC (rev 92889)
@@ -848,10 +848,10 @@
                        
                        Expression e = a.Expr;
                        if (e is AnonymousMethodExpression && 
RootContext.Version != LanguageVersion.ISO_1) {
-                               AnonymousMethod am = 
((AnonymousMethodExpression) e).Compatible (ec, type);
-                               if (am == null)
+                               e = ((AnonymousMethodExpression) e).Compatible 
(ec, type);
+                               if (e == null)
                                        return null;
-                               return am.Resolve (ec);
+                               return e.Resolve (ec);
                        }
 
                        method_group = e as MethodGroupExpr;

Modified: trunk/mcs/mcs/ecore.cs
===================================================================
--- trunk/mcs/mcs/ecore.cs      2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/ecore.cs      2008-01-14 18:06:47 UTC (rev 92889)
@@ -1244,6 +1244,12 @@
 
                        return cloned;
                }
+
+               public virtual Expression CreateExpressionTree (EmitContext ec)
+               {
+                       throw new NotImplementedException (
+                               "Expression tree conversion not implemented for 
" + GetType ());
+               }
        }
 
        /// <summary>

Modified: trunk/mcs/mcs/expression.cs
===================================================================
--- trunk/mcs/mcs/expression.cs 2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/expression.cs 2008-01-14 18:06:47 UTC (rev 92889)
@@ -4027,6 +4027,11 @@
                        return Name == pr.Name && referenced == pr.referenced;
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       return Parameter.ExpressionTreeVariableReference ();
+               }
+
                //
                // Notice that for ref/out parameters, the type exposed is not 
the
                // same type exposed externally.

Modified: trunk/mcs/mcs/iterators.cs
===================================================================
--- trunk/mcs/mcs/iterators.cs  2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/iterators.cs  2008-01-14 18:06:47 UTC (rev 92889)
@@ -938,7 +938,7 @@
                                Parameters.EmptyReadOnlyParameters);
                }
 
-               public override Expression Resolve (EmitContext ec)
+               public override Expression DoResolve (EmitContext ec)
                {
                        throw new NotSupportedException ();
                }

Modified: trunk/mcs/mcs/lambda.cs
===================================================================
--- trunk/mcs/mcs/lambda.cs     2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/lambda.cs     2008-01-14 18:06:47 UTC (rev 92889)
@@ -34,6 +34,33 @@
                                explicit_parameters = 
!(parameters.FixedParameters [0] is ImplicitLambdaParameter);
                }
 
+               public static Expression System_Linq_Expressions;
+               public static Expression System_Linq_Expressions_Expression;
+
+               protected override Expression CreateExpressionTree (EmitContext 
ec, Type delegate_type)
+               {
+                       System_Linq_Expressions = new MemberAccess (
+                                       new MemberAccess (new SimpleName 
("System", loc), "Linq", loc), "Expressions", loc);
+
+                       System_Linq_Expressions_Expression = new MemberAccess (
+                               System_Linq_Expressions, "Expression", loc);
+
+                       MemberAccess lambda = new MemberAccess 
(System_Linq_Expressions_Expression, "Lambda",
+                               new TypeArguments (loc, new TypeExpression 
(delegate_type, loc)), loc);
+
+                       Expression args = Parameters.CreateExpressionTree (ec, 
loc);
+                       Expression expr = Block.CreateExpressionTree (ec);
+                       if (expr == null)
+                               return null;
+
+                       ArrayList arguments = new ArrayList (2);
+                       arguments.Add (new Argument (expr));
+                       arguments.Add (new Argument (args));
+                       Expression invocation = new Invocation (lambda, 
arguments);
+
+                       return invocation;
+               }
+
                public override bool HasExplicitParameters {
                        get {
                                return explicit_parameters;
@@ -147,6 +174,11 @@
                {
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       return Expr.CreateExpressionTree (ec);
+               }
+
                public override void Emit (EmitContext ec)
                {
                        if (statement_return) {

Modified: trunk/mcs/mcs/parameter.cs
===================================================================
--- trunk/mcs/mcs/parameter.cs  2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/parameter.cs  2008-01-14 18:06:47 UTC (rev 92889)
@@ -236,6 +236,8 @@
                public readonly Location Location;
 
                IResolveContext resolve_context;
+               LocalVariableReference expr_tree_variable;
+               static TypeExpr parameter_expr_tree_type;
 
                Variable var;
                public Variable Variable {
@@ -606,6 +608,47 @@
 
                        return p;
                }
+
+               public ExpressionStatement CreateExpressionTreeVariable 
(EmitContext ec)
+               {
+                       if ((modFlags & Modifier.ISBYREF) != 0)
+                               Report.Error (1951, Location, "An expression 
tree parameter cannot use `ref' or `out' modifier");
+
+                       LocalInfo variable = 
ec.CurrentBlock.AddTemporaryVariable (
+                               ResolveParameterExpressionType (ec, Location), 
Location);
+                       variable.Resolve (ec);
+
+                       expr_tree_variable = new LocalVariableReference (
+                               ec.CurrentBlock, variable.Name, Location, 
variable, false);
+
+                       ArrayList arguments = new ArrayList (2);
+                       arguments.Add (new Argument (new TypeOf (
+                               new TypeExpression (parameter_type, Location), 
Location)));
+                       arguments.Add (new Argument (new StringConstant (Name, 
Location)));
+                       return new Assign (ExpressionTreeVariableReference (),
+                               new Invocation (
+                                       new MemberAccess 
(LambdaExpression.System_Linq_Expressions_Expression, "Parameter", Location),
+                                       arguments));
+               }
+
+               public Expression ExpressionTreeVariableReference ()
+               {
+                       return expr_tree_variable;
+               }
+
+               //
+               // System.Linq.Expressions.ParameterExpression type
+               //
+               public static TypeExpr ResolveParameterExpressionType 
(EmitContext ec, Location location)
+               {
+                       if (parameter_expr_tree_type != null)
+                               return parameter_expr_tree_type;
+
+                       MemberAccess ma = new MemberAccess (
+                               LambdaExpression.System_Linq_Expressions, 
"ParameterExpression", location);
+                       parameter_expr_tree_type = ma.ResolveAsTypeTerminal 
(ec, false);
+                       return parameter_expr_tree_type;
+               }
        }
 
        /// <summary>
@@ -949,6 +992,26 @@
                        return this [pos].ModFlags;
                }
 
+               public Expression CreateExpressionTree (EmitContext ec, 
Location loc)
+               {
+                       ArrayList initializers = new ArrayList (count);
+                       foreach (Parameter p in FixedParameters) {
+                               //
+                               // Each parameter expression is stored to local 
variable
+                               // to save some memory when referenced later.
+                               //
+                               StatementExpression se = new 
StatementExpression (p.CreateExpressionTreeVariable (ec));
+                               if (se.Resolve (ec))
+                                       ec.CurrentBlock.AddScopeStatement (se);
+                               
+                               initializers.Add 
(p.ExpressionTreeVariableReference ());
+                       }
+
+                       return new ArrayCreation (
+                               Parameter.ResolveParameterExpressionType (ec, 
loc),
+                               "[]", initializers, loc);
+               }
+
                public Parameters Clone ()
                {
                        Parameter [] parameters_copy = new Parameter 
[FixedParameters.Length];

Modified: trunk/mcs/mcs/statement.cs
===================================================================
--- trunk/mcs/mcs/statement.cs  2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/statement.cs  2008-01-14 18:06:47 UTC (rev 92889)
@@ -103,6 +103,12 @@
                        return s;
                }
 
+               public virtual Expression CreateExpressionTree (EmitContext ec)
+               {
+                       Report.Error (834, loc, "A lambda expression with 
statement body cannot be converted to an expresion tree");
+                       return null;
+               }
+
                public Statement PerformClone ()
                {
                        CloneContext clonectx = new CloneContext ();
@@ -1531,7 +1537,9 @@
                //
                Block switch_block;
 
+               // TODO: merge with scope_initializers
                ExpressionStatement scope_init;
+               ArrayList scope_initializers;
 
                ArrayList anonymous_children;
 
@@ -1900,6 +1908,18 @@
                        }
                        return null;
                }
+
+               //
+               // It should be used by expressions which require to
+               // register a statement during resolve process.
+               //
+               public void AddScopeStatement (StatementExpression s)
+               {
+                       if (scope_initializers == null)
+                               scope_initializers = new ArrayList ();
+
+                       scope_initializers.Add (s);
+               }
                
                public void AddStatement (Statement s)
                {
@@ -2275,6 +2295,11 @@
                        ec.Mark (StartLocation, true);
                        if (scope_init != null)
                                scope_init.EmitStatement (ec);
+                       if (scope_initializers != null) {
+                               foreach (StatementExpression s in 
scope_initializers)
+                                       s.Emit (ec);
+                       }
+
                        DoEmit (ec);
                        ec.Mark (EndLocation, true); 
 
@@ -2607,6 +2632,11 @@
                        return root_scope;
                }
 
+               public override Expression CreateExpressionTree (EmitContext ec)
+               {
+                       return ((Statement) statements 
[0]).CreateExpressionTree (ec);
+               }
+
                public void CreateIteratorHost (RootScopeInfo root)
                {
                        Report.Debug (64, "CREATE ITERATOR HOST", this, root, 
Parent, root_scope);

Modified: trunk/mcs/mcs/typemanager.cs
===================================================================
--- trunk/mcs/mcs/typemanager.cs        2008-01-14 18:01:47 UTC (rev 92888)
+++ trunk/mcs/mcs/typemanager.cs        2008-01-14 18:06:47 UTC (rev 92889)
@@ -112,16 +112,21 @@
        static public Type coclass_attr_type;
        static public Type comimport_attr_type;
 
-       /// 
-       /// .NET 2.0
-       ///
-#if NET_2_0
+#if GMCS_SOURCE
+       // 
+       // C# 2.0
+       //
        static internal Type runtime_compatibility_attr_type;
        static internal Type compiler_generated_attr_type;
        static internal Type fixed_buffer_attr_type;
        static internal Type default_charset_type;
        static internal Type internals_visible_attr_type;
        static internal Type type_forwarder_attr_type;
+
+       //
+       // C# 3.0
+       //
+       static internal Type expression_type;
 #endif
 
        // 
@@ -208,14 +213,14 @@
        static internal ConstructorInfo struct_layout_attribute_ctor;
        static public ConstructorInfo field_offset_attribute_ctor;
        
-#if NET_2_0
-       /// C# 2.0
+#if GMCS_SOURCE
+       // C# 2.0
        static internal CustomAttributeBuilder compiler_generated_attr;
        static internal ConstructorInfo fixed_buffer_attr_ctor;
-#endif
 
-       /// C# 3.0
+       // C# 3.0
        static internal CustomAttributeBuilder extension_attribute_attr;
+#endif
 
        static PtrHashtable builder_to_declspace;
 
@@ -1125,6 +1130,7 @@
                // C# 3.0
                //
                extension_attribute_type = 
CoreLookupType("System.Runtime.CompilerServices", "ExtensionAttribute", true);
+               expression_type = CoreLookupType ("System.Linq.Expressions", 
"Expression`1", true);
 #endif
 
                //

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to