[runtime] Fix corlib out of date error with disabled COM
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / View / TypeResolvingOptions.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.View
5 {
6     using System.Runtime;
7     using System.Collections.ObjectModel;
8     using System.Diagnostics.CodeAnalysis;
9     using System.Collections.Generic;
10
11     [Fx.Tag.XamlVisible(false)]
12     public class TypeResolvingOptions
13     {
14         private IDictionary<string, string> hintTextMap;
15
16         public TypeResolvingOptions() : this(null)
17         {
18         }
19
20         public TypeResolvingOptions(IEnumerable<Type> defaultTypes)
21         {
22             if (defaultTypes != null)
23             {
24                 this.MostRecentlyUsedTypes = new ObservableCollection<Type>();
25                 foreach (Type item in defaultTypes)
26                 {
27                     if (item == null)
28                     {
29                         throw FxTrace.Exception.AsError(new ArgumentException(SR.TypeResolvingOptionsArgumentExceptionMessage));
30                     }
31                     this.MostRecentlyUsedTypes.Add(item);
32                 }
33             }
34         }
35
36         public Func<Type, bool> Filter
37         {
38             get;
39             set;
40         }
41
42         [SuppressMessage(FxCop.Category.Usage, FxCop.Rule.CollectionPropertiesShouldBeReadOnly,
43             Justification = "Setter is provided to data binding on this property.")]
44         internal ObservableCollection<Type> MostRecentlyUsedTypes
45         {
46             get;
47             set;
48         }
49
50         /// <summary>
51         /// A dictionary that maps the name of a generic type argument to a hint text.
52         /// </summary>
53         internal IDictionary<string, string> HintTextMap
54         {
55             get
56             {
57                 if (this.hintTextMap == null)
58                 {
59                     this.hintTextMap = new Dictionary<string, string>();
60                 }
61
62                 return this.hintTextMap;
63             }
64         }
65
66         public bool BrowseTypeDirectly
67         {
68             get;
69             set;
70         }
71
72         internal static TypeResolvingOptions Merge(TypeResolvingOptions lhs, TypeResolvingOptions rhs)
73         {
74             if (lhs == null)
75             {
76                 return rhs;
77             }
78             else if (rhs == null)
79             {
80                 return lhs;
81             }
82
83             TypeResolvingOptions result = new TypeResolvingOptions
84             {
85                 Filter = FuncAnd(lhs.Filter, rhs.Filter),
86                 MostRecentlyUsedTypes = Intersect(lhs.MostRecentlyUsedTypes, rhs.MostRecentlyUsedTypes),
87                 BrowseTypeDirectly = lhs.BrowseTypeDirectly && rhs.BrowseTypeDirectly
88             };
89
90             // Pass in the fields directly to prevent triggering lazy initialization.
91             IDictionary<string, string> mergedHintTextMap = MergeDictionaries<string, string>(lhs.hintTextMap, rhs.hintTextMap);
92             if (mergedHintTextMap != null && mergedHintTextMap.Count > 0)
93             {
94                 foreach (KeyValuePair<string, string> kvp in mergedHintTextMap)
95                 {
96                     result.HintTextMap.Add(kvp.Key, kvp.Value);
97                 }
98             }
99
100             return result;
101         }
102
103         static Func<Type, bool> FuncAnd(Func<Type, bool> lhs, Func<Type, bool> rhs)
104         {
105             if (lhs == null)
106             {
107                 return rhs;
108             }
109             else if (rhs == null)
110             {
111                 return lhs;
112             }
113
114             return new Func<Type, bool>((e) => lhs(e) && rhs(e));
115         }
116
117         static ObservableCollection<T> Intersect<T>(ObservableCollection<T> lhs, ObservableCollection<T> rhs)
118         {
119             if (lhs == null)
120             {
121                 return rhs;
122             }
123             else if (rhs == null)
124             {
125                 return lhs;
126             }
127
128             ObservableCollection<T> collection = new ObservableCollection<T>();
129             foreach (T t in lhs)
130             {
131                 if (rhs.Contains(t))
132                 {
133                     collection.Add(t);
134                 }
135             }
136
137             return collection;
138         }
139
140         static IDictionary<TKey, TValue> MergeDictionaries<TKey, TValue>(IDictionary<TKey, TValue> lhs, IDictionary<TKey, TValue> rhs)
141         {
142             if (lhs == null || lhs.Count == 0)
143             {
144                 return rhs;
145             }
146
147             if (rhs == null || rhs.Count == 0)
148             {
149                 return lhs;
150             }
151
152             Dictionary<TKey, TValue> result = new Dictionary<TKey, TValue>();
153             foreach (KeyValuePair<TKey, TValue> kvp in lhs)
154             {
155                 result.Add(kvp.Key, kvp.Value);
156             }
157
158             foreach (KeyValuePair<TKey, TValue> kvp in rhs)
159             {
160                 if (!result.ContainsKey(kvp.Key))
161                 {
162                     result.Add(kvp.Key, kvp.Value);
163                 }
164             }
165
166             return result;
167         }
168     }
169 }