/// <summary> /// Imports the specified object intto this <see cref="ScriptObject"/> context. See remarks. /// </summary> /// <param name="obj">The object.</param> /// <param name="filter">Optional member filterer</param> /// <param name="renamer">Optional renamer</param> /// <remarks> /// <ul> /// <li>If <paramref name="obj"/> is a <see cref="System.Type"/>, this method will import only the static field/properties of the specified object.</li> /// <li>If <paramref name="obj"/> is a <see cref="ScriptObject"/>, this method will import the members of the specified object into the new object.</li> /// <li>If <paramref name="obj"/> is a plain object, this method will import the public fields/properties of the specified object into the <see cref="ScriptObject"/>.</li> /// </ul> /// </remarks> public static void Import(this IScriptObject script, object obj, FilterMemberDelegate filter = null, MemberRenamerDelegate renamer = null) { if (obj is IScriptObject) { script.Import((IScriptObject)obj); return; } script.Import(obj, ScriptMemberImportFlags.All, filter, renamer); }
/// <summary> /// Imports the specified object. /// </summary> /// <param name="obj">The object.</param> /// <param name="flags">The import flags.</param> /// <param name="filter">A filter applied on each member</param> /// <param name="renamer">The member renamer.</param> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public static void Import(this IScriptObject script, object obj, ScriptMemberImportFlags flags, FilterMemberDelegate filter = null, MemberRenamerDelegate renamer = null) { if (obj == null) { return; } if (!ScriptObject.IsImportable(obj)) { throw new ArgumentOutOfRangeException(nameof(obj), $"Unsupported object type [{obj.GetType()}]. Expecting plain class or struct"); } var typeInfo = (obj as Type ?? obj.GetType()).GetTypeInfo(); bool useStatic = false; bool useInstance = false; bool useMethodInstance = false; if (obj is Type) { useStatic = true; obj = null; } else { useInstance = true; useMethodInstance = (flags & ScriptMemberImportFlags.MethodInstance) != 0; } renamer = renamer ?? StandardMemberRenamer.Default; if ((flags & ScriptMemberImportFlags.Field) != 0) { foreach (var field in typeInfo.GetDeclaredFields()) { if (!field.IsPublic) { continue; } if (filter != null && !filter(field.Name)) { continue; } var keep = field.GetCustomAttribute <ScriptMemberIgnoreAttribute>() == null; if (keep && ((field.IsStatic && useStatic) || useInstance)) { var newFieldName = renamer(field.Name); if (String.IsNullOrEmpty(newFieldName)) { newFieldName = field.Name; } // If field is init only or literal, it cannot be set back so we mark it as read-only script.SetValue(null, new SourceSpan(), newFieldName, field.GetValue(obj), field.IsInitOnly || field.IsLiteral); } } } if ((flags & ScriptMemberImportFlags.Property) != 0) { foreach (var property in typeInfo.GetDeclaredProperties()) { if (!property.CanRead || !property.GetGetMethod().IsPublic) { continue; } if (filter != null && !filter(property.Name)) { continue; } var keep = property.GetCustomAttribute <ScriptMemberIgnoreAttribute>() == null; if (keep && (((property.GetGetMethod().IsStatic&& useStatic) || useInstance))) { var newPropertyName = renamer(property.Name); if (String.IsNullOrEmpty(newPropertyName)) { newPropertyName = property.Name; } script.SetValue(null, new SourceSpan(), newPropertyName, property.GetValue(obj), property.GetSetMethod() == null || !property.GetSetMethod().IsPublic); } } } if ((flags & ScriptMemberImportFlags.Method) != 0 && (useStatic || useMethodInstance)) { foreach (var method in typeInfo.GetDeclaredMethods()) { if (filter != null && !filter(method.Name)) { continue; } var keep = method.GetCustomAttribute <ScriptMemberIgnoreAttribute>() == null; if (keep && method.IsPublic && ((useMethodInstance && !method.IsStatic) || (useStatic && method.IsStatic)) && !method.IsSpecialName) { var newMethodName = renamer(method.Name); if (String.IsNullOrEmpty(newMethodName)) { newMethodName = method.Name; } script.SetValue(null, new SourceSpan(), newMethodName, new ObjectFunctionWrapper(obj, method), true); } } } }
/// <summary> /// Imports the specified object. /// </summary> /// <param name="obj">The object.</param> /// <param name="flags">The import flags.</param> /// <param name="filter">A filter applied on each member</param> /// <param name="renamer">The member renamer.</param> /// <exception cref="System.ArgumentOutOfRangeException"></exception> public static void Import(this IScriptObject script, object obj, ScriptMemberImportFlags flags, FilterMemberDelegate filter = null, IMemberRenamer renamer = null) { if (obj == null) { return; } if (!ScriptObject.IsImportable(obj)) { throw new ArgumentOutOfRangeException(nameof(obj), $"Unsupported object type [{obj.GetType()}]. Expecting plain class or struct"); } var typeInfo = (obj as Type ?? obj.GetType()).GetTypeInfo(); bool useStatic = false; bool useInstance = false; bool useMethodInstance = false; if (obj is Type) { useStatic = true; obj = null; } else { useInstance = true; useMethodInstance = (flags & ScriptMemberImportFlags.MethodInstance) != 0; } renamer = renamer ?? StandardMemberRenamer.Default; if ((flags & ScriptMemberImportFlags.Field) != 0) { foreach (var field in typeInfo.GetDeclaredFields()) { if (!field.IsPublic) { continue; } if (filter != null && !filter(field.Name)) { continue; } var keep = field.GetCustomAttribute<ScriptMemberIgnoreAttribute>() == null; if (keep && ((field.IsStatic && useStatic) || useInstance)) { var newFieldName = renamer.GetName(field.Name); if (String.IsNullOrEmpty(newFieldName)) { newFieldName = field.Name; } // If field is init only or literal, it cannot be set back so we mark it as read-only script.SetValue(newFieldName, field.GetValue(obj), field.IsInitOnly || field.IsLiteral); } } } if ((flags & ScriptMemberImportFlags.Property) != 0) { foreach (var property in typeInfo.GetDeclaredProperties()) { if (!property.CanRead || !property.GetGetMethod().IsPublic) { continue; } if (filter != null && !filter(property.Name)) { continue; } var keep = property.GetCustomAttribute<ScriptMemberIgnoreAttribute>() == null; if (keep && (((property.GetGetMethod().IsStatic && useStatic) || useInstance))) { var newPropertyName = renamer.GetName(property.Name); if (String.IsNullOrEmpty(newPropertyName)) { newPropertyName = property.Name; } script.SetValue(newPropertyName, property.GetValue(obj), property.GetSetMethod() == null || !property.GetSetMethod().IsPublic); } } } if ((flags & ScriptMemberImportFlags.Method) != 0 && (useStatic || useMethodInstance)) { foreach (var method in typeInfo.GetDeclaredMethods()) { if (filter != null && !filter(method.Name)) { continue; } var keep = method.GetCustomAttribute<ScriptMemberIgnoreAttribute>() == null; if (keep && method.IsPublic && ((useMethodInstance && !method.IsStatic) || (useStatic && method.IsStatic)) && !method.IsSpecialName) { var newMethodName = renamer.GetName(method.Name); if (String.IsNullOrEmpty(newMethodName)) { newMethodName = method.Name; } script.SetValue(newMethodName, new ObjectFunctionWrapper(obj, method), true); } } } }