Skip to content

Commit

Permalink
Added support of param arrays within constructors, in line with other…
Browse files Browse the repository at this point in the history
… method invocations. (#199)

Fix #196
  • Loading branch information
metoule authored Dec 10, 2021
1 parent 83dc6e4 commit 3abf5b1
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 15 deletions.
12 changes: 9 additions & 3 deletions src/DynamicExpresso.Core/Parsing/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1077,15 +1077,21 @@ private Expression ParseNew()
ValidateToken(TokenId.OpenCurlyBracket, ErrorMessages.OpenCurlyBracketExpected);
}

var constructor = newType.GetConstructor(args.Select(p => p.Type).ToArray());
if (constructor == null)
var applicableConstructors = FindBestMethod(newType.GetConstructors(), args);
if (applicableConstructors.Length == 0)
throw CreateParseException(_token.pos, ErrorMessages.NoApplicableConstructor, newType);

if (applicableConstructors.Length > 1)
throw CreateParseException(_token.pos, ErrorMessages.AmbiguousConstructorInvocation, newType);

var constructor = applicableConstructors[0];
var newExpr = Expression.New((ConstructorInfo)constructor.MethodBase, constructor.PromotedParameters);

var memberBindings = new MemberBinding[0];
if (_token.id == TokenId.OpenCurlyBracket)
memberBindings = ParseObjectInitializer(newType);

return Expression.MemberInit(Expression.New(constructor, args), memberBindings);
return Expression.MemberInit(newExpr, memberBindings);
}

private MemberBinding[] ParseObjectInitializer(Type newType)
Expand Down
35 changes: 23 additions & 12 deletions src/DynamicExpresso.Core/Resources/ErrorMessages.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions src/DynamicExpresso.Core/Resources/ErrorMessages.resx
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,7 @@
<data name="ParamsArrayTypeNotAnArray" xml:space="preserve">
<value>Params array type is not an array, element not found</value>
</data>
<data name="AmbiguousConstructorInvocation" xml:space="preserve">
<value>Ambiguous invocation of constructor in type '{0}'</value>
</data>
</root>
14 changes: 14 additions & 0 deletions test/DynamicExpresso.UnitTest/ConstructorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,20 @@ public void Object_initializer_syntax_error()
Assert.Throws<ParseException>(() => target.Parse("new MyClass() {5}")); // no field name
}

[Test]
public void Ctor_params_array()
{
var target = new Interpreter();
target.Reference(typeof(MyClass));
Assert.AreEqual(new MyClass(6, 5, 4, 3).MyArr, target.Eval("new MyClass(6, 5, 4, 3).MyArr"));
}

private class MyClass
{
public int IntField;
public string StrProp { get; set; }
public int ReadOnlyProp { get; }
public int[] MyArr { get; set; }

public MyClass()
{
Expand All @@ -148,6 +157,11 @@ public MyClass(string strValue)
StrProp = strValue;
}

public MyClass(params int[] intValues)
{
MyArr = intValues;
}

public override bool Equals(object obj)
{
return Equals(obj as MyClass);
Expand Down

0 comments on commit 3abf5b1

Please sign in to comment.