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