private static object GetAttachedObject(string propertyName, object attachedTo) { // This function assumes that the propertyName is not a path (no '.' in it) int index = propertyName.IndexOf('['); string nonIndexedProperty = (index < 0) ? propertyName : propertyName.Substring(0, index); TrustedType trustedType = PT.Trust(attachedTo.GetType()); TrustedPropertyInfo property = trustedType.GetProperty(nonIndexedProperty); object returnValue = property.GetValue(attachedTo, null); if (index < 0) { // This isn't a collection, just return what we got. return(returnValue); } else { // This is a collection. Parse the index string and return the value at that index. int indexLength = propertyName.Length - nonIndexedProperty.Length - 2; string s = propertyName.Substring(index + 1, indexLength).Trim(); int i = StringConverter.ToInt(s); // Visual3DCollection does not implement IList like the other collections do :( if (returnValue is Visual3DCollection) { return(((Visual3DCollection)returnValue)[i]); } else { return(((IList)returnValue)[i]); } } }
private void VerifyCloneForFreezable(Freezable frozenObject) { if (frozenObject == null) { return; } TrustedType type = PT.Trust(frozenObject.GetType()); TrustedMethodInfo method = type.GetMethod("Clone", BindingFlags.Public | BindingFlags.Instance); if (method == null) { throw new ApplicationException("Could not find Clone method on " + type.Name); } Freezable copy = (Freezable)method.Invoke(frozenObject, null); if (!ObjectUtils.DeepEqualsToAnimatable(frozenObject, copy)) { AddFailure("{0}.Copy failed to produce an exact copy", type.Name); } method = type.GetMethod("CloneCurrentValue", BindingFlags.Public | BindingFlags.Instance); if (method == null) { throw new ApplicationException("Could not find CloneCurrentValue method on " + type.Name); } copy = (Freezable)method.Invoke(frozenObject, null); if (!ObjectUtils.DeepEqualsToAnimatable(frozenObject, copy)) { AddFailure("{0}.CloneCurrentValue failed to produce an exact copy", type.Name); } }
private bool MethodNeedsOverride(TrustedMethodBase method, TrustedType type) { // Property code generator will sometimes pass in null if (method == null) { return(false); } return(method.IsAbstract && (method.IsPublic || method.IsFamily) && !IsOverridden(method, type)); }
/// <summary/> public static void WaitForCompleteRender() { Type hwndTargetType = typeof(HwndTarget); TrustedAssembly mcasm = TrustedAssembly.GetAssembly(hwndTargetType); TrustedType mcType = mcasm.GetType("System.Windows.Media.MediaContext"); object mediaContext = mcType.InvokeMember("From", BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.InvokeMethod, null, null, new object[] { System.Windows.Threading.Dispatcher.CurrentDispatcher }); mcType.InvokeMember("CompleteRender", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, mediaContext, new object[] { }); }
private void CompareProperties(Type type, object obj1, object obj2, string space) { space += " "; // We don't want static properties. They're problematic. TrustedPropertyInfo[] properties = PT.Trust(type).GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (TrustedPropertyInfo property in properties) { string propertyName = property.Name; TrustedType propertyType = property.PropertyType; if (!property.DeclaringType.IsPublic) { continue; } Log(space + "{0} : {1}", propertyName, propertyType.Name); if (IsPropertyProblematic(propertyName)) { Log(space + "- Skipping problematic property"); continue; } // "Item" is the indexer property's name. // This property requires parameters to be evaluated and is therefore a problem. // - For IEnumerables, we can iterate through its items and compare them. // - We don't know how to dynamically deal with other types of indexers so we skip them. if (propertyName == "Item") { if (obj1 is IEnumerable) { CompareItems(type, (IEnumerable)obj1, (IEnumerable)obj2, space); } else { Log(space + "- Skipping indexer"); } continue; } object value1 = property.GetValue(obj1, null); object value2 = property.GetValue(obj2, null); if (propertyType.IsValueType) { CompareValueTypes(value1, value2, space); } else { CompareRefTypes(value1, value2, space); } } }
/// <summary> /// Iterate through the constructors available and choose the best one. /// Return null if the type is a struct or there are no "good" constructors. /// </summary> private static TrustedConstructorInfo GetBestConstructor(TrustedType type) { TrustedConstructorInfo[] constructors = type.GetConstructors(flags); TrustedConstructorInfo bestOverride = null; // We cheat with value types and return null // Reason: // Value types don't list the default constructor as theirs. // So rather than override a multiparameter constructor, we interpret a // null return value from this function as having a default constructor. if (constructors.Length > 0 && !type.IsValueType) { foreach (TrustedConstructorInfo constructor in constructors) { // Rules for choosing best constructor: // 1- The constructor must be public or protected. // 2- We prefer overriding public constructors to protected ones. // 3- We prefer overriding the constructor with the fewest parameters. if (constructor.IsPublic) { if (bestOverride == null || bestOverride.IsFamily) { bestOverride = constructor; continue; } } else if (constructor.IsFamily) { if (bestOverride == null) { bestOverride = constructor; continue; } } else { continue; } if (constructor.GetParameters().Length < bestOverride.GetParameters().Length) { bestOverride = constructor; } } } return(bestOverride); }
/// <summary> /// public wrapper of the internal API "DependencyProperty.FromName" /// </summary> /// <param name="propertyName">The name of the property to get</param> /// <param name="propertyType">The type of the property owner</param> /// <returns>The DependencyProperty represented by the name/type pair</returns> /// <exception cref="ArgumentException">Thrown when propertyName is not a valid DependencyProperty on propertyType</exception> public static DependencyProperty GetDependencyProperty(string propertyName, Type propertyType) { TrustedType trustedType = PT.Trust(propertyType); TrustedFieldInfo field = trustedType.GetField( propertyName + "Property", BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy ); if (field == null) { throw new ArgumentException("Could not locate property " + propertyName + " on " + propertyType.Name, "propertyName"); } return((DependencyProperty)field.GetValue(null)); }
/// <summary> /// Get the object that owns the property specified. /// </summary> /// <param name="complexPropertyPath">A "dot-down" path to a property</param> /// <param name="attachedTo">The object to start the search from</param> /// <returns>The object that owns the property specified</returns> /// <exception cref="ArgumentException">Thrown when the path does not lead to a valid object</exception> public static object GetPropertyOwner(string complexPropertyPath, object attachedTo) { // complexProperty will come in like this: // // path == Thickness attachedTo == ScreenSpaceLines3D return: ScreenSpaceLines3D // path == Material[0].Brush.Color attachedTo == GeometryModel3D return: Brush // path == Brush.Color attachedTo == Material return: Brush // path == Color attachedTo == Brush return: Brush // path == Children[0] attachedTo == Viewport3D return: Visual3DCollection int dotIndex = complexPropertyPath.IndexOf('.'); if (dotIndex < 0) { int bracketIndex = complexPropertyPath.IndexOf('['); if (bracketIndex < 0) { // The property should be on the object we're looking at right now. // Throw an exception if the property does not exist on this object. TrustedType trustedType = PT.Trust(attachedTo.GetType()); TrustedPropertyInfo property = trustedType.GetProperty(complexPropertyPath); if (property == null) { throw new ArgumentException(complexPropertyPath + " does not exist on " + trustedType.Name); } return(attachedTo); } else { // Trim the index from the property (the collection is the owner) string nonIndexedProperty = complexPropertyPath.Substring(0, bracketIndex); return(GetAttachedObject(nonIndexedProperty, attachedTo)); } } // The property is not on the current object string localPropertyName = complexPropertyPath.Substring(0, dotIndex); string remainingProperties = complexPropertyPath.Substring(dotIndex + 1); object next = GetAttachedObject(localPropertyName, attachedTo); return(GetPropertyOwner(remainingProperties, next)); }
public DeclarationsGenerator(TrustedType type, string generatedClassName) { ArrayList list = new ArrayList(); list.Add(new ConstructorGenerator(type, generatedClassName)); if (type.IsAbstract) { TrustedMethodInfo[] methodInfos = type.GetMethods(flags); if (methodInfos != null) { foreach (TrustedMethodInfo method in methodInfos) { // PropertyGenerators will be created in the next step. Don't add them here. if (!method.Name.Contains("get_") && !method.Name.Contains("set_") && MethodNeedsOverride(method, type)) { list.Add(new MethodGenerator(method)); } } } TrustedPropertyInfo[] properties = type.GetProperties(flags); if (properties != null) { foreach (TrustedPropertyInfo property in properties) { TrustedMethodInfo get = property.GetGetMethod(); TrustedMethodInfo set = property.GetSetMethod(); if (MethodNeedsOverride(get, type) || MethodNeedsOverride(set, type)) { list.Add(new PropertyGenerator(property)); } } } } methods = new MethodGeneratorBase[list.Count]; list.CopyTo(methods); }
/// <summary> /// Walk up the inheritance tree until we find an override /// or the class where the abstract method was defined /// </summary> private bool IsOverridden(TrustedMethodBase method, TrustedType type) { if (method.DeclaringType == type) { return(false); } TrustedMethodInfo[] methods = type.GetMethods(flags); if (methods != null) { foreach (TrustedMethodInfo info in methods) { if (MethodSignaturesMatch(info, method)) { MethodBody body = info.GetMethodBody(); if (body != null) { return(true); } } } } return(IsOverridden(method, type.BaseType)); }
public ConstructorGenerator(TrustedType typeToInherit, string className) : base(GetBestConstructor(typeToInherit)) { this.type = typeToInherit; this.className = className; }
public ClassGenerator(TrustedType classToInherit) { this.type = classToInherit; this.declarationsGenerator = new DeclarationsGenerator(classToInherit, newClassName); }
private static bool DeepEquals(object obj1, object obj2, bool skipUnimportant) { if (object.ReferenceEquals(obj1, obj2)) { // Shortcut- if they are the same object, return true; return(true); } Type type1 = obj1.GetType(); Type type2 = obj2.GetType(); if (type1 != type2) { return(false); } if (type1 == typeof(string)) { return(obj1.ToString() == obj2.ToString()); } bool equals; TrustedType trustedType = PT.Trust(type1); TrustedPropertyInfo[] properties = trustedType.GetProperties(BindingFlags.Public | BindingFlags.Instance); foreach (TrustedPropertyInfo property in properties) { if (skipUnimportant) { // If we don't care about the property (declared by Freezable or its ancestors), skip it! if (IsPropertyDeclaredByAncestorsOf(PT.Untrust(property.DeclaringType), typeof(Freezable)) || IsPropertyDeclaredByAncestorsOf(PT.Untrust(property.DeclaringType), typeof(FrameworkElement))) { continue; } } if (IsPropertyProblematic(property)) { continue; } if (property.Name == "Item") { if (obj1 is IEnumerable) { equals = DeepEquals((IEnumerable)obj1, (IEnumerable)obj2, skipUnimportant); } else { // This is an indexer. We can't really compare it. equals = true; } } else { object value1 = property.GetValue(obj1, null); object value2 = property.GetValue(obj2, null); if (property.PropertyType.IsValueType) { switch (property.PropertyType.Name) { case "Double": equals = MathEx.AreCloseEnough((double)value1, (double)value2); break; case "Point": equals = MathEx.AreCloseEnough((Point)value1, (Point)value2); break; case "Vector": equals = MathEx.AreCloseEnough((Vector)value1, (Vector)value2); break; case "Rect": equals = MathEx.AreCloseEnough((Rect)value1, (Rect)value2); break; case "Matrix": equals = MathEx.AreCloseEnough((Matrix)value1, (Matrix)value2); break; case "Point3D": equals = MathEx.AreCloseEnough((Point3D)value1, (Point3D)value2); break; case "Point4D": equals = MathEx.AreCloseEnough((Point4D)value1, (Point4D)value2); break; case "Quaternion": equals = MathEx.AreCloseEnough((Quaternion)value1, (Quaternion)value2); break; case "Vector3D": equals = MathEx.AreCloseEnough((Vector3D)value1, (Vector3D)value2); break; case "Rect3D": equals = MathEx.AreCloseEnough((Rect3D)value1, (Rect3D)value2); break; case "Matrix3D": equals = MathEx.AreCloseEnough((Matrix3D)value1, (Matrix3D)value2); break; default: equals = object.Equals(value1, value2); break; } } else { equals = DeepEquals(value1, value2, skipUnimportant); } } if (!equals) { return(false); } } return(true); }
/// <summary> /// This summary has not been prepared yet. NOSUMMARY - pantal07 /// </summary> public object MakeValue(string value, Type type) { TrustedType t = PT.Trust(typeof(StringConverter)); return(t.InvokeMember("To" + type.Name, BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, new object[] { value })); }