-// Permission is hereby granted, free of charge, to any person obtaining
+//
+// NewExpression.cs
+//
+// Author:
+// Jb Evain (jbevain@novell.com)
+//
+// (C) 2008 Novell, Inc. (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-//
-// Authors:
-// Antonello Provenzano <antonello@deveel.com>
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
+using System;
using System.Collections.ObjectModel;
using System.Reflection;
-using System.Text;
+using System.Reflection.Emit;
-namespace System.Linq.Expressions
-{
- public sealed class NewExpression : Expression
- {
- #region .ctor
- internal NewExpression(Type type, ConstructorInfo constructor, ReadOnlyCollection<Expression> arguments)
- : base(ExpressionType.New, type)
- {
- this.constructor = constructor;
- this.arguments = arguments;
- }
- #endregion
+namespace System.Linq.Expressions {
+
+ public sealed class NewExpression : Expression {
- #region Fields
+ ConstructorInfo constructor;
ReadOnlyCollection<Expression> arguments;
ReadOnlyCollection<MemberInfo> members;
- private ConstructorInfo constructor;
- #endregion
- #region Properties
- public ReadOnlyCollection<Expression> Arguments
- {
- get { return arguments; }
+ public ConstructorInfo Constructor {
+ get { return constructor; }
}
- public ConstructorInfo Constructor
- {
- get { return constructor; }
+ public ReadOnlyCollection<Expression> Arguments {
+ get { return arguments; }
}
public ReadOnlyCollection<MemberInfo> Members {
get { return members; }
}
- #endregion
+ internal NewExpression (Type type, ReadOnlyCollection<Expression> arguments)
+ : base (ExpressionType.New, type)
+ {
+ this.arguments = arguments;
+ }
- #region Internal Methods
- internal override void BuildString(StringBuilder builder)
+ internal NewExpression (ConstructorInfo constructor, ReadOnlyCollection<Expression> arguments, ReadOnlyCollection<MemberInfo> members)
+ : base (ExpressionType.New, constructor.DeclaringType)
{
- Type initType = base.Type;
- if (constructor != null)
- initType = constructor.DeclaringType;
+ this.constructor = constructor;
+ this.arguments = arguments;
+ this.members = members;
+ }
- builder.Append("new " + initType.Name + "(");
+ internal override void Emit (EmitContext ec)
+ {
+ var ig = ec.ig;
+ var type = this.Type;
- int argc = arguments.Count;
- for (int i = 0; i < argc; i++)
- {
- Expression argExpr = arguments[i];
- argExpr.BuildString(builder);
+ LocalBuilder local = null;
+ if (type.IsValueType) {
+ local = ig.DeclareLocal (type);
+ ig.Emit (OpCodes.Ldloca, local);
- if (i < argc - 1)
- builder.Append(", ");
+ if (constructor == null) {
+ ig.Emit (OpCodes.Initobj, type);
+ ig.Emit (OpCodes.Ldloc, local);
+ return;
+ }
}
- builder.Append(")");
+ ec.EmitCollection (arguments);
+
+ if (type.IsValueType) {
+ ig.Emit (OpCodes.Call, constructor);
+ ig.Emit (OpCodes.Ldloc, local);
+ } else
+ ig.Emit (OpCodes.Newobj, constructor ?? GetDefaultConstructor (type));
+ }
+
+ static ConstructorInfo GetDefaultConstructor (Type type)
+ {
+ return type.GetConstructor (Type.EmptyTypes);
}
- #endregion
}
-}
\ No newline at end of file
+}