Commit 84a593fe authored by Vinicius Jarina's avatar Vinicius Jarina
Browse files

Merge pull request #133 from isaacbrodsky/master

Fix calling methods with nullable parameters (null could not be passed)
parents fb177cdf c162d48d
...@@ -103,11 +103,34 @@ namespace NLua ...@@ -103,11 +103,34 @@ namespace NLua
var underlyingType = Nullable.GetUnderlyingType (paramType); var underlyingType = Nullable.GetUnderlyingType (paramType);
if (underlyingType != null) if (underlyingType != null) {
paramType = underlyingType; // Silently convert nullable types to their non null requics paramType = underlyingType; // Silently convert nullable types to their non null requics
}
var extractKey = GetExtractDictionaryKey (paramType); var extractKey = GetExtractDictionaryKey (paramType);
bool netParamIsNumeric = paramType == typeof (int) ||
paramType == typeof (uint) ||
paramType == typeof (long) ||
paramType == typeof (ulong) ||
paramType == typeof (short) ||
paramType == typeof (ushort) ||
paramType == typeof (float) ||
paramType == typeof (double) ||
paramType == typeof (decimal) ||
paramType == typeof (byte);
// If it is a nullable
if (underlyingType != null) {
// null can always be assigned to nullable
if (luatype == LuaTypes.Nil) {
// Return the correct extractor anyways
if (netParamIsNumeric || paramType == typeof (bool))
return extractValues [extractKey];
return extractNetObject;
}
}
if (paramType.Equals (typeof(object))) if (paramType.Equals (typeof(object)))
return extractValues [extractKey]; return extractValues [extractKey];
...@@ -127,15 +150,6 @@ namespace NLua ...@@ -127,15 +150,6 @@ namespace NLua
return extractValues [GetExtractDictionaryKey (typeof(double))]; return extractValues [GetExtractDictionaryKey (typeof(double))];
} }
bool netParamIsString = paramType == typeof (string) || paramType == typeof (char []); bool netParamIsString = paramType == typeof (string) || paramType == typeof (char []);
bool netParamIsNumeric = paramType == typeof (int) ||
paramType == typeof (uint) ||
paramType == typeof (long) ||
paramType == typeof (ulong) ||
paramType == typeof (short) ||
paramType == typeof (float) ||
paramType == typeof (double) ||
paramType == typeof (decimal) ||
paramType == typeof (byte);
if (netParamIsNumeric) { if (netParamIsNumeric) {
if (LuaLib.LuaIsNumber (luaState, stackPos) && !netParamIsString) if (LuaLib.LuaIsNumber (luaState, stackPos) && !netParamIsString)
...@@ -149,13 +163,13 @@ namespace NLua ...@@ -149,13 +163,13 @@ namespace NLua
else if (luatype == LuaTypes.Nil) else if (luatype == LuaTypes.Nil)
return extractNetObject; // kevinh - silently convert nil to a null string pointer return extractNetObject; // kevinh - silently convert nil to a null string pointer
} else if (paramType == typeof(LuaTable)) { } else if (paramType == typeof(LuaTable)) {
if (luatype == LuaTypes.Table) if (luatype == LuaTypes.Table || luatype == LuaTypes.Nil)
return extractValues [extractKey]; return extractValues [extractKey];
} else if (paramType == typeof(LuaUserData)) { } else if (paramType == typeof(LuaUserData)) {
if (luatype == LuaTypes.UserData) if (luatype == LuaTypes.UserData || luatype == LuaTypes.Nil)
return extractValues [extractKey]; return extractValues [extractKey];
} else if (paramType == typeof(LuaFunction)) { } else if (paramType == typeof(LuaFunction)) {
if (luatype == LuaTypes.Function) if (luatype == LuaTypes.Function || luatype == LuaTypes.Nil)
return extractValues [extractKey]; return extractValues [extractKey];
} else if (typeof(Delegate).IsAssignableFrom (paramType) && luatype == LuaTypes.Function) } else if (typeof(Delegate).IsAssignableFrom (paramType) && luatype == LuaTypes.Function)
return new ExtractValue (new DelegateGenerator (translator, paramType).ExtractGenerated); return new ExtractValue (new DelegateGenerator (translator, paramType).ExtractGenerated);
......
...@@ -830,7 +830,10 @@ namespace NLua ...@@ -830,7 +830,10 @@ namespace NLua
internal LuaTable GetTable (LuaState luaState, int index) internal LuaTable GetTable (LuaState luaState, int index)
{ {
LuaLib.LuaPushValue (luaState, index); LuaLib.LuaPushValue (luaState, index);
return new LuaTable (LuaLib.LuaRef (luaState, 1), interpreter); int reference = LuaLib.LuaRef (luaState, 1);
if (reference == -1)
return null;
return new LuaTable (reference, interpreter);
} }
/* /*
...@@ -839,7 +842,10 @@ namespace NLua ...@@ -839,7 +842,10 @@ namespace NLua
internal LuaUserData GetUserData (LuaState luaState, int index) internal LuaUserData GetUserData (LuaState luaState, int index)
{ {
LuaLib.LuaPushValue (luaState, index); LuaLib.LuaPushValue (luaState, index);
return new LuaUserData (LuaLib.LuaRef (luaState, 1), interpreter); int reference = LuaLib.LuaRef (luaState, 1);
if (reference == -1)
return null;
return new LuaUserData(reference, interpreter);
} }
/* /*
...@@ -848,7 +854,10 @@ namespace NLua ...@@ -848,7 +854,10 @@ namespace NLua
internal LuaFunction GetFunction (LuaState luaState, int index) internal LuaFunction GetFunction (LuaState luaState, int index)
{ {
LuaLib.LuaPushValue (luaState, index); LuaLib.LuaPushValue (luaState, index);
return new LuaFunction (LuaLib.LuaRef (luaState, 1), interpreter); int reference = LuaLib.LuaRef (luaState, 1);
if (reference == -1)
return null;
return new LuaFunction (reference, interpreter);
} }
/* /*
......
...@@ -153,6 +153,26 @@ namespace NLuaTest ...@@ -153,6 +153,26 @@ namespace NLuaTest
} }
} }
/*
* Tests passing a LuaFunction
*/
[Test]
public void CallLuaFunction()
{
using (Lua lua = new Lua ()) {
lua.DoString ("function someFunc(v1,v2) return v1 + v2 end");
lua ["funcObject"] = lua.GetFunction ("someFunc");
lua.DoString ("luanet.load_assembly('mscorlib')");
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("b = TestClass():TestLuaFunction(funcObject)[0]");
Assert.AreEqual (3, lua ["b"]);
lua.DoString ("a = TestClass():TestLuaFunction(nil)");
Assert.AreEqual (null, lua ["a"]);
}
}
/* /*
* Tests capturing an exception * Tests capturing an exception
*/ */
...@@ -621,6 +641,29 @@ namespace NLuaTest ...@@ -621,6 +641,29 @@ namespace NLuaTest
} }
} }
/*
* Tests passing a null object as a parameter to a
* method that accepts a nullable.
*/
[Test]
public void TestNullableParameter ()
{
using (Lua lua = new Lua ()) {
lua.DoString ("luanet.load_assembly('NLuaTest')");
lua.DoString ("TestClass=luanet.import_type('NLuaTest.Mock.TestClass')");
lua.DoString ("test=TestClass()");
lua.DoString ("a = test:NullableMethod(nil)");
Assert.AreEqual (null, lua ["a"]);
lua ["timeVal"] = TimeSpan.FromSeconds (5);
lua.DoString ("b = test:NullableMethod(timeVal)");
Assert.AreEqual (TimeSpan.FromSeconds (5), lua ["b"]);
lua.DoString ("d = test:NullableMethod2(2)");
Assert.AreEqual (2, lua ["d"]);
lua.DoString ("c = test:NullableMethod2(nil)");
Assert.AreEqual (null, lua ["c"]);
}
}
/* /*
* Tests if DoString is correctly returning values * Tests if DoString is correctly returning values
*/ */
......
...@@ -374,6 +374,24 @@ namespace NLuaTest.Mock ...@@ -374,6 +374,24 @@ namespace NLuaTest.Mock
set { } set { }
} }
public TimeSpan? NullableMethod (TimeSpan? input)
{
return input;
}
public int? NullableMethod2 (int? input)
{
return input;
}
public object[] TestLuaFunction (LuaFunction func)
{
if (func != null) {
return func.Call (1, 2);
}
return null;
}
public int sum (int x, int y) public int sum (int x, int y)
{ {
return x + y; return x + y;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment