public static int importType(IntPtr luaState) { ObjectTranslator translator = ObjectTranslator.FromState(luaState); string className = LuaDLL.lua_tostring(luaState, 1); Type klass = translator.FindType(className); if (klass != null) translator.pushType(luaState, klass); else LuaDLL.lua_pushnil(luaState); return 1; }
public static int importType(IntPtr luaState) { ObjectTranslator objectTranslator = ObjectTranslator.FromState(luaState); string className = LuaDLL.lua_tostring(luaState, 1); Type type = objectTranslator.FindType(className); if (type != null) { objectTranslator.pushType(luaState, type); } else { LuaDLL.lua_pushnil(luaState); } return(1); }
/* * 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. * Uses reflection to find members, and stores the reflected MemberInfo object in * a cache (indexed by the type of the object and the name of the member). */ private int getMember(KopiLua.Lua.lua_State luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType) { bool implicitStatic = false; MemberInfo member = null; object cachedMember = checkMemberCache(memberCache, objType, methodName); //object cachedMember=null; if (cachedMember is KopiLua.Lua.lua_CFunction) { translator.pushFunction(luaState, (KopiLua.Lua.lua_CFunction)cachedMember); translator.push(luaState, true); return(2); } else if (cachedMember != null) { member = (MemberInfo)cachedMember; } else { MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.NonPublic); if (members.Length > 0) { member = members[0]; } else { // If we can't find any suitable instance members, try to find them as statics - but we only want to allow implicit static // lookups for fields/properties/events -kevinh members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); if (members.Length > 0) { member = members[0]; implicitStatic = true; } } } if (member != null) { if (member.MemberType == MemberTypes.Field) { FieldInfo field = (FieldInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { translator.push(luaState, field.GetValue(obj)); } catch { LuaDLL.lua_pushnil(luaState); } } else if (member.MemberType == MemberTypes.Property) { PropertyInfo property = (PropertyInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { object val = property.GetValue(obj, null); translator.push(luaState, val); } catch (ArgumentException) { // If we can't find the getter in our class, recurse up to the base class and see // if they can help. if (objType is Type && !(((Type)objType) == typeof(object))) { return(getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType)); } else { LuaDLL.lua_pushnil(luaState); } } catch (TargetInvocationException e) // Convert this exception into a Lua error { ThrowError(luaState, e); LuaDLL.lua_pushnil(luaState); } } else if (member.MemberType == MemberTypes.Event) { EventInfo eventInfo = (EventInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } translator.push(luaState, new RegisterEventHandler(translator.pendingEvents, obj, eventInfo)); } else if (!implicitStatic) { if (member.MemberType == MemberTypes.NestedType) { // kevinh - added support for finding nested types // cache us if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } // Find the name of our class string name = member.Name; Type dectype = member.DeclaringType; // Build a new long name and try to find the type by name string longname = dectype.FullName + "+" + name; Type nestedType = translator.FindType(longname); translator.pushType(luaState, nestedType); } else { // Member type must be 'method' KopiLua.Lua.lua_CFunction wrapper = new KopiLua.Lua.lua_CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, wrapper); } translator.pushFunction(luaState, wrapper); translator.push(luaState, true); return(2); } } else { // If we reach this point we found a static method, but can't use it in this context because the user passed in an instance translator.throwError(luaState, "can't pass instance to static method " + methodName); LuaDLL.lua_pushnil(luaState); } } else { // kevinh - we want to throw an exception because meerly returning 'nil' in this case // is not sufficient. valid data members may return nil and therefore there must be some // way to know the member just doesn't exist. translator.throwError(luaState, "unknown member name " + methodName); LuaDLL.lua_pushnil(luaState); } // push false because we are NOT returning a function (see luaIndexFunction) translator.push(luaState, false); return(2); }
/// <summary>[-0, +2, e] /// Returns to Lua the value of a member or a delegate to call it, depending on the type of the member. /// Works with static or instance members. Uses reflection to find members, /// and stores the reflected MemberInfo object in a cache (indexed by <paramref name="objType"/> and <paramref name="methodName"/>). /// </summary> /// <exception cref="ArgumentNullException"><paramref name="objType"/> and <paramref name="methodName"/> are required</exception> int getMember(lua.State L, IReflect objType, object obj, string methodName, BindingFlags bindingType) { Debug.Assert(interpreter.IsSameLua(L)); Debug.Assert(objType != null && methodName != null); Debug.Assert((obj == null) == (objType is ProxyType)); Debug.Assert((obj == null) != (objType is Type)); Debug.Assert((obj == null) == ((bindingType & BindingFlags.Static) == BindingFlags.Static)); Debug.Assert((obj == null) != ((bindingType & BindingFlags.Instance) == BindingFlags.Instance)); MemberInfo member = null; object cachedMember = checkMemberCache(objType, methodName); if (cachedMember != null) { var cachedMethod = cachedMember as lua.CFunction; if (cachedMethod != null) { luaclr.pushcfunction(L, cachedMethod); lua.pushboolean(L, true); return(2); } Debug.Assert(cachedMember is MemberInfo); member = (MemberInfo)cachedMember; } else { MemberInfo[] members = objType.GetMember(methodName, bindingType | luanet.LuaBindingFlags); if (members.Length != 0) { member = members[0]; #if DEBUG if (!(members.Length == 1 || member is MethodBase)) // todo { return(luaL.error(L, "Overloads for members other than methods are not implemented.")); } #endif } } object value = null; switch (member == null ? MemberTypes.All : member.MemberType) { default: // not found or found a constructor // kevinh - we want to throw an error because merely returning 'nil' in this case // is not sufficient. valid data members may return nil and therefore there must be some // way to know the member just doesn't exist. return(luaL.error(L, string.Format("'{0}' does not contain a definition for '{1}'", objType.UnderlyingSystemType.FullName, methodName))); case MemberTypes.Method: var wrapper = new lua.CFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(objType, methodName, wrapper); } luaclr.pushcfunction(L, wrapper); lua.pushboolean(L, true); return(2); case MemberTypes.Field: if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "field read failed (access denied)")); } try { value = ((FieldInfo)member).GetValue(obj); } catch { goto default; } translator.push(L, value); break; case MemberTypes.Property: // todo: support indexed properties if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "property call failed (access denied)")); } try { value = ((PropertyInfo)member).GetValue(obj, null); } catch (TargetInvocationException ex) { return(translator.throwError(L, luaclr.verifyex(ex.InnerException))); } catch { goto default; } translator.push(L, value); break; case MemberTypes.Event: if (!translator.memberIsAllowed(member)) { return(luaL.error(L, "event read failed (access denied)")); } value = new RegisterEventHandler(translator.pendingEvents, obj, (EventInfo)member); translator.push(L, value); break; case MemberTypes.NestedType: var nestedType = (Type)member; if (translator.FindType(nestedType)) // don't hand out class references unless loaded/whitelisted { ObjectTranslator.pushType(L, nestedType); } else { lua.pushnil(L); } break; } if (cachedMember == null) { setMemberCache(objType, methodName, member); } // push false because we are NOT returning a function (see luaIndexFunction) lua.pushboolean(L, false); 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. * Uses reflection to find members, and stores the reflected MemberInfo object in * a cache (indexed by the type of the object and the name of the member). */ private int getMember(IntPtr luaState, IReflect objType, object obj, string methodName, BindingFlags bindingType) { bool implicitStatic = false; MemberInfo member = null; object cachedMember = checkMemberCache(memberCache, objType, methodName); if (cachedMember is LuaCSFunction) { translator.pushFunction(luaState, (LuaCSFunction)cachedMember); translator.push(luaState, true); return(2); } else if (cachedMember != null) { member = (MemberInfo)cachedMember; } else { //CP: Removed NonPublic binding search MemberInfo[] members = objType.GetMember(methodName, bindingType | BindingFlags.Public | BindingFlags.IgnoreCase /*| BindingFlags.NonPublic*/); if (members.Length > 0) { member = members[0]; } else { members = objType.GetMember(methodName, bindingType | BindingFlags.Static | BindingFlags.Public | BindingFlags.IgnoreCase /*| BindingFlags.NonPublic*/); if (members.Length > 0) { member = members[0]; implicitStatic = true; } } } if (member != null) { if (member.MemberType == MemberTypes.Field) { FieldInfo field = (FieldInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { translator.push(luaState, field.GetValue(obj)); } catch { LuaAPI.lua_pushnil(luaState); } } else if (member.MemberType == MemberTypes.Property) { PropertyInfo property = (PropertyInfo)member; if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } try { object val = property.GetGetMethod().Invoke(obj, null); translator.push(luaState, val); } catch (ArgumentException) { if (objType is Type && !(((Type)objType) == typeof(object))) { return(getMember(luaState, ((Type)objType).BaseType, obj, methodName, bindingType)); } else { LuaAPI.lua_pushnil(luaState); } } catch (TargetInvocationException e) // Convert this exception into a Lua error { ThrowError(luaState, e); LuaAPI.lua_pushnil(luaState); } } else if (!implicitStatic) { if (member.MemberType == MemberTypes.NestedType) { // cache us if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, member); } // Find the name of our class string name = member.Name; Type dectype = member.DeclaringType; // Build a new long name and try to find the type by name string longname = dectype.FullName + "+" + name; Type nestedType = translator.FindType(longname); translator.pushType(luaState, nestedType); } else { // Member type must be 'method' LuaCSFunction wrapper = new LuaCSFunction((new LuaMethodWrapper(translator, objType, methodName, bindingType)).call); if (cachedMember == null) { setMemberCache(memberCache, objType, methodName, wrapper); } translator.pushFunction(luaState, wrapper); translator.push(luaState, true); return(2); } } else { // If we reach this point we found a static method, but can't use it in this context because the user passed in an instance translator.throwError(luaState, "can't pass instance to static method " + methodName); LuaAPI.lua_pushnil(luaState); } } else { // kevinh - we want to throw an exception because meerly returning 'nil' in this case // is not sufficient. valid data members may return nil and therefore there must be some // way to know the member just doesn't exist. translator.throwError(luaState, "unknown member name " + methodName); LuaAPI.lua_pushnil(luaState); } // push false because we are NOT returning a function (see luaIndexFunction) translator.push(luaState, false); return(2); }