Fix XMM scanning on Mac x86.
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Model / ModelUtilities.cs
1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //-----------------------------------------------------------------------------
4
5 namespace System.Activities.Presentation.Model
6 {
7     using System;
8     using System.Collections.Generic;
9     using System.ComponentModel;
10     using System.Runtime;
11
12     // This class provides useful shared utility functions that are
13     // needed by our ModelItemImpl class implementations.
14     internal static class ModelUtilities
15     {
16         internal static bool IsSwitchCase(ModelItem modelItem)
17         {
18             if (IsModelItemKeyValuePair(modelItem.ItemType))
19             {
20                 if (modelItem.Parent != null && //modelItem.Parent - ItemsCollection
21                     modelItem.Parent.Parent != null && //modelItem.Parent.Parent - Cases
22                     modelItem.Parent.Parent.Parent != null && //modelItem.Parent.Parent.Parent - Switch
23                     modelItem.Parent.Parent.Parent.ItemType.IsGenericType &&
24                     modelItem.Parent.Parent.Parent.ItemType.GetGenericTypeDefinition() == typeof(System.Activities.Statements.Switch<>))
25                 {
26                     return true;
27                 }
28             }
29             return false;
30         }
31
32         internal static bool IsModelItemKeyValuePair(Type type)
33         {
34             Fx.Assert(type != null, "Parameter type is null!");
35             return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(ModelItemKeyValuePair<,>);
36         }
37
38         // Returns a wrapped type converter for the given item.
39         internal static TypeConverter GetConverter(IModelTreeItem item)
40         {
41             return GetConverter(item.ModelTreeManager, item.ModelItem);
42         }
43
44         // Returns a wrapped converter for the given item.
45         internal static TypeConverter GetConverter(ModelTreeManager modelTreeManager, ModelItem item)
46         {
47             return new ModelTypeConverter(modelTreeManager, XamlUtilities.GetConverter(item.ItemType));
48         }
49
50         // Returns the default property on the item, or null if the item has
51         internal static PropertyDescriptor GetDefaultProperty(ModelItem item)
52         {
53             DefaultPropertyAttribute propAttr = TypeDescriptor.GetAttributes(item.ItemType)[typeof(DefaultPropertyAttribute)] as DefaultPropertyAttribute;
54             if (propAttr != null && !string.IsNullOrEmpty(propAttr.Name))
55             {
56                 ModelProperty prop = item.Properties.Find(propAttr.Name);
57                 if (prop != null)
58                 {
59                     return new ModelPropertyDescriptor(prop);
60                 }
61             }
62             return null;
63         }
64
65         // Wraps an item's properties in PropertyDescriptors and returns a
66         // collection of them.
67         internal static PropertyDescriptorCollection WrapProperties(ModelItem item)
68         {
69             List<PropertyDescriptor> descriptors = new List<PropertyDescriptor>();
70             foreach (ModelProperty prop in item.Properties)
71             {
72                 descriptors.Add(new ModelPropertyDescriptor(prop));
73             }
74             return new PropertyDescriptorCollection(descriptors.ToArray(), true);
75         }
76
77
78         internal static ModelItem ReverseFindFirst(ModelItem start, Predicate<ModelItem> matcher)
79         {
80             Fx.Assert(start != null, "start should not be null");
81             Fx.Assert(matcher != null, "matcher should not be null");
82
83             ModelItem result = null;
84             ModelUtilities.ReverseTraverse(start, (ModelItem current) =>
85             {
86                 if (matcher(current))
87                 {
88                     result = current;
89                     return false;
90                 }
91
92                 return true;
93             });
94             return result;
95         }
96
97         // Traverse model graph via ModelItem's parent. Stop traversing if shouldContinue returns false
98         internal static void ReverseTraverse(ModelItem start, Predicate<ModelItem> shouldContinue)
99         {
100             Fx.Assert(start != null, "start should not be null");
101             Fx.Assert(shouldContinue != null, "shouldContinue should not be null");
102
103             HashSet<ModelItem> visited = new HashSet<ModelItem>();
104             ModelItem current = start;
105
106             while (current != null)
107             {
108                 if (!shouldContinue(current))
109                 {
110                     return;
111                 }
112
113                 visited.Add(current);
114                 current = current.Parent;
115                 if (visited.Contains(current))
116                 {
117                     return;
118                 }
119             }
120         }
121     }
122 }