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;
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
{
......@@ -48,17 +28,19 @@ namespace ConsoleTest
using (Lua lua = new Lua ()) {
lua.LoadCLRPackage ();
lua.DoString (@" import ('ConsoleTest')
lua.DoString (@" import ('NLuaTest')
v = Vector()
v.x = 10
v.y = 3
v = v*2 ");
var v = (ConsoleTest.Vector)lua ["v"];
var v = (Vector)lua ["v"];
double len = v.Lenght ();
lua.DoString (" v:Lenght() ");
lua.DoString (@" len2 = v:Lenght()");
double len2 = (double)lua ["len2"];
lua.DoString (@" x = 2*v");
var x = (Vector)lua ["x"];
}
}
......
......@@ -26,6 +26,7 @@ using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.CompilerServices;
namespace NLua.Extensions
{
......@@ -140,6 +141,45 @@ namespace NLua.Extensions
{
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
......
......@@ -423,6 +423,10 @@ namespace NLua
translator.Push (luaState, arr [intIndex]);
}
} 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
var methods = objType.GetMethods ();
......@@ -529,6 +533,36 @@ namespace NLua
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;
}
/*
* Pushes the value of a member or a delegate to call it, depending on the type of
* the member. Works with static or instance members.
......
......@@ -329,6 +329,16 @@ namespace NLua
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);
}
/*
* Implementation of import_type. Returns nil if the
* type is not found.
......
......@@ -56,6 +56,19 @@ namespace NLuaTest
r.y = v.y * k;
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]
......@@ -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