Commit 24ffaca9 authored by Vinicius Jarina's avatar Vinicius Jarina
Browse files

[NLua] Fixed #80 Using extension Function

parent dfca7e05
...@@ -9,26 +9,6 @@ using NLuaTest; ...@@ -9,26 +9,6 @@ using NLuaTest;
namespace ConsoleTest namespace ConsoleTest
{ {
public class Vector
{
public double x;
public double y;
public static Vector operator *(float k, Vector v)
{
var r = new Vector();
r.x = v.x * k;
r.y = v.y * k;
return r;
}
public static Vector operator * (Vector v, float k)
{
var r = new Vector ();
r.x = v.x * k;
r.y = v.y * k;
return r;
}
}
public class Program public class Program
{ {
...@@ -48,17 +28,19 @@ namespace ConsoleTest ...@@ -48,17 +28,19 @@ namespace ConsoleTest
using (Lua lua = new Lua ()) { using (Lua lua = new Lua ()) {
lua.LoadCLRPackage (); lua.LoadCLRPackage ();
lua.DoString (@" import ('ConsoleTest') lua.DoString (@" import ('NLuaTest')
v = Vector() v = Vector()
v.x = 10 v.x = 10
v.y = 3 v.y = 3
v = v*2 "); v = v*2 ");
var v = (ConsoleTest.Vector)lua ["v"]; var v = (Vector)lua ["v"];
lua.DoString (@" x = 2*v"); double len = v.Lenght ();
var x = (Vector)lua ["x"]; lua.DoString (" v:Lenght() ");
lua.DoString (@" len2 = v:Lenght()");
double len2 = (double)lua ["len2"];
} }
} }
......
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
using System; using System;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Runtime.CompilerServices;
namespace NLua.Extensions namespace NLua.Extensions
{ {
...@@ -140,6 +141,45 @@ namespace NLua.Extensions ...@@ -140,6 +141,45 @@ namespace NLua.Extensions
{ {
return t.GetMethods (flags).Where (m => m.Name == name); return t.GetMethods (flags).Where (m => m.Name == name);
} }
public static MethodInfo [] GetExtensionMethods (this Type type, IEnumerable<Assembly> assemblies = null)
{
List<Type> types = new List<Type> ();
types.AddRange (type.Assembly.GetTypes ().Where (t => t.IsPublic));
if (assemblies != null) {
foreach (Assembly item in assemblies) {
if (item == type.Assembly)
continue;
types.AddRange (item.GetTypes ().Where (t => t.IsPublic));
}
}
var query = from extensionType in types
where extensionType.IsSealed && !extensionType.IsGenericType && !extensionType.IsNested
from method in extensionType.GetMethods (BindingFlags.Static | BindingFlags.Public)
where method.IsDefined (typeof (ExtensionAttribute), false)
where method.GetParameters () [0].ParameterType == type
select method;
return query.ToArray<MethodInfo> ();
}
/// <summary>
/// Extends the System.Type-type to search for a given extended MethodeName.
/// </summary>
/// <param name="MethodeName">Name of the Methode</param>
/// <returns>the found Methode or null</returns>
public static MethodInfo GetExtensionMethod (this Type t, string name, IEnumerable<Assembly> assemblies = null)
{
var mi = from methode in t.GetExtensionMethods (assemblies)
where methode.Name == name
select methode;
if (!mi.Any<MethodInfo> ())
return null;
else
return mi.First<MethodInfo> ();
}
} }
static class StringExtensions static class StringExtensions
......
...@@ -404,7 +404,7 @@ namespace NLua ...@@ -404,7 +404,7 @@ namespace NLua
return GetMember (luaState, objType, obj, methodName, BindingFlags.Instance); return GetMember (luaState, objType, obj, methodName, BindingFlags.Instance);
} catch { } catch {
} }
// Try to access by array if the type is right and index is an int (lua numbers always come across as double) // Try to access by array if the type is right and index is an int (lua numbers always come across as double)
if (objType.IsArray && index is double) { if (objType.IsArray && index is double) {
int intIndex = (int)((double)index); int intIndex = (int)((double)index);
...@@ -422,7 +422,11 @@ namespace NLua ...@@ -422,7 +422,11 @@ namespace NLua
object[] arr = (object[])obj; object[] arr = (object[])obj;
translator.Push (luaState, arr [intIndex]); translator.Push (luaState, arr [intIndex]);
} }
} else { } else {
if (!string.IsNullOrEmpty (methodName) && IsExtensionMethodPresent (objType, methodName)) {
return GetExtensionMethod (luaState, objType, obj, methodName);
}
// Try to use get_Item to index into this .net object // Try to use get_Item to index into this .net object
var methods = objType.GetMethods (); var methods = objType.GetMethods ();
...@@ -527,6 +531,36 @@ namespace NLua ...@@ -527,6 +531,36 @@ namespace NLua
var members = objType.GetMember (methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public); var members = objType.GetMember (methodName, BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public);
return (members.Length > 0); return (members.Length > 0);
}
bool IsExtensionMethodPresent (Type type, string name)
{
object cachedMember = CheckMemberCache (memberCache, type, name);
if (cachedMember != null)
return true;
return translator.IsExtensionMethodPresent (type, name);
}
int GetExtensionMethod (LuaState luaState, Type type, object obj, string name)
{
object cachedMember = CheckMemberCache (memberCache, type, name);
if (cachedMember != null && cachedMember is LuaNativeFunction) {
translator.PushFunction (luaState, (LuaNativeFunction)cachedMember);
translator.Push (luaState, true);
return 2;
}
MethodInfo methodInfo = translator.GetExtensionMethod (type, name);
var wrapper = new LuaNativeFunction ((new LuaMethodWrapper (translator, obj, type, methodInfo)).invokeFunction);
SetMemberCache (memberCache, type, name, wrapper);
translator.PushFunction (luaState, wrapper);
translator.Push (luaState, true);
return 2;
} }
/* /*
......
...@@ -327,6 +327,16 @@ namespace NLua ...@@ -327,6 +327,16 @@ namespace NLua
return klass; return klass;
} }
return null; return null;
}
public bool IsExtensionMethodPresent (Type type, string name)
{
return GetExtensionMethod (type, name) != null;
}
public MethodInfo GetExtensionMethod (Type type, string name)
{
return type.GetExtensionMethod (name, assemblies);
} }
/* /*
......
...@@ -56,6 +56,19 @@ namespace NLuaTest ...@@ -56,6 +56,19 @@ namespace NLuaTest
r.y = v.y * k; r.y = v.y * k;
return r; return r;
} }
public void Func ()
{
Console.WriteLine ("Func");
}
}
public static class VectorExtension
{
public static double Lenght (this Vector v)
{
return v.x * v.x + v.y * v.y;
}
} }
[TestFixture] [TestFixture]
...@@ -2096,6 +2109,28 @@ namespace NLuaTest ...@@ -2096,6 +2109,28 @@ namespace NLuaTest
} }
} }
[Test]
public void TestExtensionMethods ()
{
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('NLuaTest')
v = Vector()
v.x = 10
v.y = 3
v = v*2 ");
var v = (Vector)lua ["v"];
double len = v.Lenght ();
lua.DoString (" v:Lenght() ");
lua.DoString (@" len2 = v:Lenght()");
double len2 = (double)lua ["len2"];
Assert.AreEqual (len, len2, "#1");
}
}
} }
......
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