mscorlib(4.0.0.0) API with additions
BindingRestrictions.cs
2 using System.Diagnostics;
3 using System.Dynamic.Utils;
6 
7 namespace System.Dynamic
8 {
10  [DebuggerTypeProxy(typeof(BindingRestrictionsProxy))]
11  [DebuggerDisplay("{DebugView}")]
12  [global::__DynamicallyInvokable]
13  public abstract class BindingRestrictions
14  {
15  private sealed class TestBuilder
16  {
17  private struct AndNode
18  {
19  internal int Depth;
20 
21  internal Expression Node;
22  }
23 
24  private readonly Set<BindingRestrictions> _unique = new Set<BindingRestrictions>();
25 
26  private readonly Stack<AndNode> _tests = new Stack<AndNode>();
27 
28  internal void Append(BindingRestrictions restrictions)
29  {
30  if (!_unique.Contains(restrictions))
31  {
32  _unique.Add(restrictions);
33  Push(restrictions.GetExpression(), 0);
34  }
35  }
36 
37  internal Expression ToExpression()
38  {
39  Expression expression = _tests.Pop().Node;
40  while (_tests.Count > 0)
41  {
42  expression = Expression.AndAlso(_tests.Pop().Node, expression);
43  }
44  return expression;
45  }
46 
47  private void Push(Expression node, int depth)
48  {
49  while (_tests.Count > 0 && _tests.Peek().Depth == depth)
50  {
51  node = Expression.AndAlso(_tests.Pop().Node, node);
52  depth++;
53  }
54  _tests.Push(new AndNode
55  {
56  Node = node,
57  Depth = depth
58  });
59  }
60  }
61 
62  private sealed class MergedRestriction : BindingRestrictions
63  {
64  internal readonly BindingRestrictions Left;
65 
66  internal readonly BindingRestrictions Right;
67 
68  internal MergedRestriction(BindingRestrictions left, BindingRestrictions right)
69  {
70  Left = left;
71  Right = right;
72  }
73 
74  internal override Expression GetExpression()
75  {
76  throw ContractUtils.Unreachable;
77  }
78  }
79 
80  private sealed class CustomRestriction : BindingRestrictions
81  {
82  private readonly Expression _expression;
83 
84  internal CustomRestriction(Expression expression)
85  {
86  _expression = expression;
87  }
88 
89  public override bool Equals(object obj)
90  {
91  CustomRestriction customRestriction = obj as CustomRestriction;
92  if (customRestriction != null)
93  {
94  return customRestriction._expression == _expression;
95  }
96  return false;
97  }
98 
99  public override int GetHashCode()
100  {
101  return 0x40000000 ^ _expression.GetHashCode();
102  }
103 
104  internal override Expression GetExpression()
105  {
106  return _expression;
107  }
108  }
109 
110  private sealed class TypeRestriction : BindingRestrictions
111  {
112  private readonly Expression _expression;
113 
114  private readonly Type _type;
115 
116  internal TypeRestriction(Expression parameter, Type type)
117  {
118  _expression = parameter;
119  _type = type;
120  }
121 
122  public override bool Equals(object obj)
123  {
124  TypeRestriction typeRestriction = obj as TypeRestriction;
125  if (typeRestriction != null && TypeUtils.AreEquivalent(typeRestriction._type, _type))
126  {
127  return typeRestriction._expression == _expression;
128  }
129  return false;
130  }
131 
132  public override int GetHashCode()
133  {
134  return 0x10000000 ^ _expression.GetHashCode() ^ _type.GetHashCode();
135  }
136 
137  internal override Expression GetExpression()
138  {
139  return Expression.TypeEqual(_expression, _type);
140  }
141  }
142 
143  private sealed class InstanceRestriction : BindingRestrictions
144  {
145  private readonly Expression _expression;
146 
147  private readonly object _instance;
148 
149  internal InstanceRestriction(Expression parameter, object instance)
150  {
151  _expression = parameter;
152  _instance = instance;
153  }
154 
155  public override bool Equals(object obj)
156  {
157  InstanceRestriction instanceRestriction = obj as InstanceRestriction;
158  if (instanceRestriction != null && instanceRestriction._instance == _instance)
159  {
160  return instanceRestriction._expression == _expression;
161  }
162  return false;
163  }
164 
165  public override int GetHashCode()
166  {
167  return 0x20000000 ^ RuntimeHelpers.GetHashCode(_instance) ^ _expression.GetHashCode();
168  }
169 
170  internal override Expression GetExpression()
171  {
172  if (_instance == null)
173  {
174  return Expression.Equal(Expression.Convert(_expression, typeof(object)), Expression.Constant(null));
175  }
176  ParameterExpression parameterExpression = Expression.Parameter(typeof(object), null);
177  return Expression.Block(new ParameterExpression[1]
178  {
179  parameterExpression
180  }, Expression.Assign(parameterExpression, Expression.Property(Expression.Constant(new WeakReference(_instance)), typeof(WeakReference).GetProperty("Target"))), Expression.AndAlso(Expression.NotEqual(parameterExpression, Expression.Constant(null)), Expression.Equal(Expression.Convert(_expression, typeof(object)), parameterExpression)));
181  }
182  }
183 
184  private sealed class BindingRestrictionsProxy
185  {
186  private readonly BindingRestrictions _node;
187 
188  public bool IsEmpty => _node == Empty;
189 
190  public Expression Test => _node.ToExpression();
191 
192  public BindingRestrictions[] Restrictions
193  {
194  get
195  {
198  stack.Push(_node);
199  do
200  {
201  BindingRestrictions bindingRestrictions = stack.Pop();
202  MergedRestriction mergedRestriction = bindingRestrictions as MergedRestriction;
203  if (mergedRestriction != null)
204  {
205  stack.Push(mergedRestriction.Right);
206  stack.Push(mergedRestriction.Left);
207  }
208  else
209  {
210  list.Add(bindingRestrictions);
211  }
212  }
213  while (stack.Count > 0);
214  return list.ToArray();
215  }
216  }
217 
218  public BindingRestrictionsProxy(BindingRestrictions node)
219  {
220  _node = node;
221  }
222 
223  public override string ToString()
224  {
225  return _node.DebugView;
226  }
227  }
228 
230  [global::__DynamicallyInvokable]
231  public static readonly BindingRestrictions Empty = new CustomRestriction(Expression.Constant(true));
232 
233  private const int TypeRestrictionHash = 268435456;
234 
235  private const int InstanceRestrictionHash = 536870912;
236 
237  private const int CustomRestrictionHash = 1073741824;
238 
239  private string DebugView => ToExpression().ToString();
240 
241  private BindingRestrictions()
242  {
243  }
244 
245  internal abstract Expression GetExpression();
246 
250  [global::__DynamicallyInvokable]
252  {
253  ContractUtils.RequiresNotNull(restrictions, "restrictions");
254  if (this == Empty)
255  {
256  return restrictions;
257  }
258  if (restrictions == Empty)
259  {
260  return this;
261  }
262  return new MergedRestriction(this, restrictions);
263  }
264 
269  [global::__DynamicallyInvokable]
270  public static BindingRestrictions GetTypeRestriction(Expression expression, Type type)
271  {
272  ContractUtils.RequiresNotNull(expression, "expression");
273  ContractUtils.RequiresNotNull(type, "type");
274  return new TypeRestriction(expression, type);
275  }
276 
278  {
279  if (obj.Value == null && obj.HasValue)
280  {
281  return GetInstanceRestriction(obj.Expression, null);
282  }
283  return GetTypeRestriction(obj.Expression, obj.LimitType);
284  }
285 
290  [global::__DynamicallyInvokable]
291  public static BindingRestrictions GetInstanceRestriction(Expression expression, object instance)
292  {
293  ContractUtils.RequiresNotNull(expression, "expression");
294  return new InstanceRestriction(expression, instance);
295  }
296 
300  [global::__DynamicallyInvokable]
302  {
303  ContractUtils.RequiresNotNull(expression, "expression");
304  ContractUtils.Requires(expression.Type == typeof(bool), "expression");
305  return new CustomRestriction(expression);
306  }
307 
311  [global::__DynamicallyInvokable]
312  public static BindingRestrictions Combine(IList<DynamicMetaObject> contributingObjects)
313  {
314  BindingRestrictions bindingRestrictions = Empty;
315  if (contributingObjects != null)
316  {
317  foreach (DynamicMetaObject contributingObject in contributingObjects)
318  {
319  if (contributingObject != null)
320  {
321  bindingRestrictions = bindingRestrictions.Merge(contributingObject.Restrictions);
322  }
323  }
324  return bindingRestrictions;
325  }
326  return bindingRestrictions;
327  }
328 
331  [global::__DynamicallyInvokable]
333  {
334  if (this == Empty)
335  {
336  return Expression.Constant(true);
337  }
338  TestBuilder testBuilder = new TestBuilder();
340  stack.Push(this);
341  do
342  {
343  BindingRestrictions bindingRestrictions = stack.Pop();
344  MergedRestriction mergedRestriction = bindingRestrictions as MergedRestriction;
345  if (mergedRestriction != null)
346  {
347  stack.Push(mergedRestriction.Right);
348  stack.Push(mergedRestriction.Left);
349  }
350  else
351  {
352  testBuilder.Append(bindingRestrictions);
353  }
354  }
355  while (stack.Count > 0);
356  return testBuilder.ToExpression();
357  }
358  }
359 }
static int GetHashCode(object o)
Serves as a hash function for a particular object, and is suitable for use in algorithms and data str...
static BindingRestrictions GetExpressionRestriction(Expression expression)
Creates the binding restriction that checks the expression for arbitrary immutable properties.
Represents the dynamic binding and a binding logic of an object participating in the dynamic binding.
Definition: __Canon.cs:3
static BindingRestrictions GetTypeRestriction(Expression expression, Type type)
Creates the binding restriction that check the expression for runtime type identity.
static readonly BindingRestrictions Empty
Represents an empty set of binding restrictions. This field is read only.
BindingRestrictions Merge(BindingRestrictions restrictions)
Merges the set of binding restrictions with the current binding restrictions.
Represents a weak reference, which references an object while still allowing that object to be reclai...
Provides the base class from which the classes that represent expression tree nodes are derived....
Definition: Expression.cs:17
BindingRestrictions Restrictions
The set of binding restrictions under which the binding is valid.
Represents type declarations: class types, interface types, array types, value types,...
Definition: Type.cs:18
static BindingRestrictions GetInstanceRestriction(Expression expression, object instance)
Creates the binding restriction that checks the expression for object instance identity.
Represents a named parameter expression.
Represents a set of binding restrictions on the T:System.Dynamic.DynamicMetaObject under which the dy...
Represents a collection of objects that can be individually accessed by index.
Definition: IList.cs:9
Represents a strongly typed list of objects that can be accessed by index. Provides methods to search...
Definition: List.cs:14
static BindingRestrictions Combine(IList< DynamicMetaObject > contributingObjects)
Combines binding restrictions from the list of T:System.Dynamic.DynamicMetaObject instances into one ...
Expression ToExpression()
Creates the T:System.Linq.Expressions.Expression representing the binding restrictions.
Provides a set of static methods and properties that provide support for compilers....