public VariableGetterHolder(PropertyInfo propertyInfo, VariableGetVal getter, bool isSerializable) { name = propertyInfo.Name; isProperty = true; this.isSerializable = isSerializable; this.getter = getter; }
public VariableGetterHolder(FieldInfo fieldInfo, VariableGetVal getter, bool isSerializable) { name = fieldInfo.Name; isProperty = false; this.isSerializable = isSerializable; this.getter = getter; }
public VariableGetterHolder(PropertyInfo propertyInfo, VariableGetVal getter) { Type type = propertyInfo.PropertyType; MethodInfo getMethod = propertyInfo.GetGetMethod(true); StringBuilder sb = Utilities.stringBuilder; sb.Length = 0; sb.Append("(P"); if (getMethod.IsPublic) { sb.Append("+)"); } else if (getMethod.IsFamily || getMethod.IsAssembly) { sb.Append("#)"); } else { sb.Append("-)"); } if (getMethod.IsStatic) { sb.Append("(S)"); } if (Attribute.IsDefined(propertyInfo, typeof(ObsoleteAttribute))) { sb.Append("(O)"); } sb.Append("("); AppendTypeToDescription(sb, type); sb.Append(") "); sb.Append(propertyInfo.Name); this.description = sb.ToString(); this.getter = getter; }
public VariableGetterHolder(FieldInfo fieldInfo, VariableGetVal getter) { Type type = fieldInfo.FieldType; StringBuilder sb = Utilities.stringBuilder; sb.Length = 0; sb.Append("(F"); if (fieldInfo.IsPublic) { sb.Append("+)"); } else if (fieldInfo.IsFamily || fieldInfo.IsAssembly) { sb.Append("#)"); } else { sb.Append("-)"); } if (fieldInfo.IsStatic) { sb.Append("(S)"); } if (Attribute.IsDefined(fieldInfo, typeof(ObsoleteAttribute))) { sb.Append("(O)"); } sb.Append("("); AppendTypeToDescription(sb, type); sb.Append(") "); sb.Append(fieldInfo.Name); this.description = sb.ToString(); this.getter = getter; }
// Get filtered variables for a type private VariableGetterHolder[] GetFilteredVariablesForType( Type type ) { VariableGetterHolder[] result; if( typeToVariables.TryGetValue( type, out result ) ) return result; // This is the first time this type of object is seen, filter and cache its variables // Variable filtering process: // 1- skip Obsolete variables // 2- skip primitive types, enums and strings // 3- skip common Unity types that can't hold any references (e.g. Vector3, Rect, Color, Quaternion) // // P.S. IsPrimitiveUnityType() extension function handles steps 2) and 3) validVariables.Clear(); // Filter the fields if( fieldModifiers != ( BindingFlags.Instance | BindingFlags.DeclaredOnly ) ) { Type currType = type; while( currType != typeof( object ) ) { FieldInfo[] fields = currType.GetFields( fieldModifiers ); for( int i = 0; i < fields.Length; i++ ) { // Skip obsolete fields if( Attribute.IsDefined( fields[i], typeof( ObsoleteAttribute ) ) ) continue; // Skip primitive types Type variableType = fields[i].FieldType; if( variableType.IsPrimitiveUnityType() ) continue; // Searching assembly variables for reference throws InvalidCastException on .NET 4.0 runtime if( typeof( Type ).IsAssignableFrom( variableType ) || variableType.Namespace == reflectionNameSpace ) continue; // Additional filtering for fields: // 1- Ignore "m_RectTransform", "m_CanvasRenderer" and "m_Canvas" fields of Graphic components string fieldName = fields[i].Name; if( typeof( Graphic ).IsAssignableFrom( currType ) && ( fieldName == "m_RectTransform" || fieldName == "m_CanvasRenderer" || fieldName == "m_Canvas" ) ) continue; VariableGetVal getter = fields[i].CreateGetter( type ); if( getter != null ) validVariables.Add( new VariableGetterHolder( fields[i], getter, fields[i].IsSerializable() ) ); } currType = currType.BaseType; } } if( propertyModifiers != ( BindingFlags.Instance | BindingFlags.DeclaredOnly ) ) { Type currType = type; while( currType != typeof( object ) ) { PropertyInfo[] properties = currType.GetProperties( propertyModifiers ); for( int i = 0; i < properties.Length; i++ ) { // Skip obsolete properties if( Attribute.IsDefined( properties[i], typeof( ObsoleteAttribute ) ) ) continue; // Skip primitive types Type variableType = properties[i].PropertyType; if( variableType.IsPrimitiveUnityType() ) continue; // Searching assembly variables for reference throws InvalidCastException on .NET 4.0 runtime if( typeof( Type ).IsAssignableFrom( variableType ) || variableType.Namespace == reflectionNameSpace ) continue; // No need to check properties with 'override' keyword if( properties[i].IsOverridden() ) continue; // Additional filtering for properties: // 1- Ignore "gameObject", "transform", "rectTransform" and "attachedRigidbody" properties of Component's to get more useful results // 2- Ignore "canvasRenderer" and "canvas" properties of Graphic components // 3 & 4- Prevent accessing properties of Unity that instantiate an existing resource (causing memory leak) string propertyName = properties[i].Name; if( typeof( Component ).IsAssignableFrom( currType ) && ( propertyName == "gameObject" || propertyName == "transform" || propertyName == "attachedRigidbody" || propertyName == "rectTransform" ) ) continue; else if( typeof( Graphic ).IsAssignableFrom( currType ) && ( propertyName == "canvasRenderer" || propertyName == "canvas" ) ) continue; else if( typeof( MeshFilter ).IsAssignableFrom( currType ) && propertyName == "mesh" ) continue; else if( typeof( Renderer ).IsAssignableFrom( currType ) && ( propertyName == "sharedMaterial" || propertyName == "sharedMaterials" ) ) continue; else if( ( propertyName == "material" || propertyName == "materials" ) && ( typeof( Renderer ).IsAssignableFrom( currType ) || typeof( Collider ).IsAssignableFrom( currType ) || typeof( Collider2D ).IsAssignableFrom( currType ) #if !UNITY_2019_3_OR_NEWER #pragma warning disable 0618 || typeof( GUIText ).IsAssignableFrom( currType ) ) ) #pragma warning restore 0618 #endif continue; else { VariableGetVal getter = properties[i].CreateGetter(); if( getter != null ) validVariables.Add( new VariableGetterHolder( properties[i], getter, properties[i].IsSerializable() ) ); } } currType = currType.BaseType; } } result = validVariables.ToArray(); // Cache the filtered fields typeToVariables.Add( type, result ); return result; }
public VariableGetterHolder(string description, VariableGetVal getter) { this.description = description; this.getter = getter; }
// Get filtered variables for a type public static VariableGetterHolder[] GetFilteredVariablesForType(Type type) { VariableGetterHolder[] result; if (typeToVariables.TryGetValue(type, out result)) { return(result); } validVariables.Clear(); // Filter the variables Type currType = type; while (currType != typeof(object)) { FieldInfo[] fields = currType.GetFields(VARIABLE_BINDING_FLAGS); for (int i = 0; i < fields.Length; i++) { FieldInfo field = fields[i]; Type variableType = field.FieldType; // Assembly variables can throw InvalidCastException on .NET 4.0 runtime if (typeof(Type).IsAssignableFrom(variableType) || variableType.Namespace == reflectionNameSpace) { continue; } // Pointer variables can throw ArgumentException if (variableType.IsPointer) { continue; } VariableGetVal getter = field.CreateGetter(); if (getter != null) { validVariables.Add(new VariableGetterHolder(field, getter)); } } currType = currType.BaseType; } currType = type; while (currType != typeof(object)) { PropertyInfo[] properties = currType.GetProperties(VARIABLE_BINDING_FLAGS); for (int i = 0; i < properties.Length; i++) { PropertyInfo property = properties[i]; Type variableType = property.PropertyType; // Assembly variables can throw InvalidCastException on .NET 4.0 runtime if (typeof(Type).IsAssignableFrom(variableType) || variableType.Namespace == reflectionNameSpace) { continue; } // Pointer variables can throw ArgumentException if (variableType.IsPointer) { continue; } // Skip properties without a getter function MethodInfo propertyGetter = property.GetGetMethod(true); if (propertyGetter == null) { continue; } // Skip indexer properties if (property.GetIndexParameters().Length > 0) { continue; } // No need to check properties with 'override' keyword if (propertyGetter.GetBaseDefinition().DeclaringType != propertyGetter.DeclaringType) { continue; } // Additional filtering for properties: // Prevent accessing properties of Unity that instantiate an existing resource (causing memory leak) // Hide obsolete useless Component properties like "rigidbody", "camera", "collider" and so on string propertyName = property.Name; if (typeof(MeshFilter).IsAssignableFrom(currType) && propertyName == "mesh") { continue; } else if ((propertyName == "material" || propertyName == "materials") && (typeof(Renderer).IsAssignableFrom(currType) || typeof(Collider).IsAssignableFrom(currType) || typeof(Collider2D).IsAssignableFrom(currType))) { continue; } else if ((propertyName == "transform" || propertyName == "gameObject") && (property.DeclaringType == typeof(Component) || property.DeclaringType == typeof(GameObject))) { continue; } else if ((typeof(Component).IsAssignableFrom(currType) || typeof(GameObject).IsAssignableFrom(currType)) && Attribute.IsDefined(property, typeof(ObsoleteAttribute)) && obsoleteComponentAccessors.Contains(propertyName)) { continue; } else { VariableGetVal getter = property.CreateGetter(); if (getter != null) { validVariables.Add(new VariableGetterHolder(property, getter)); } } } currType = currType.BaseType; } result = validVariables.ToArray(); // Cache the filtered variables typeToVariables.Add(type, result); return(result); }