Merge pull request #409 from Alkarex/patch-1
[mono.git] / mcs / class / System.Core / System.Linq.Expressions / NewExpression.cs
index a9c383764cc2bdb10e3688fba1ebf80060322345..005d17569ec8d9c4943cd897e927b59b4bb0973d 100644 (file)
@@ -1,4 +1,12 @@
-// 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 + "(");
+#if !FULL_AOT_RUNTIME
+               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));
+               }
+#endif
+
+               static ConstructorInfo GetDefaultConstructor (Type type)
+               {
+                       return type.GetConstructor (Type.EmptyTypes);
                }
-               #endregion
        }
-}
\ No newline at end of file
+}