Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Actions / BindingRestrictions.cs / 1305376 / BindingRestrictions.cs
/* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.Generic; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions; using System.Runtime.CompilerServices; namespace System.Dynamic { ////// Represents a set of binding restrictions on the #if !SILVERLIGHT [DebuggerTypeProxy(typeof(BindingRestrictionsProxy)), DebuggerDisplay("{DebugView}")] #endif public abstract class BindingRestrictions { ///under which the dynamic binding is valid. /// /// Represents an empty set of binding restrictions. This field is read only. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly BindingRestrictions Empty = new CustomRestriction(Expression.Constant(true)); private const int TypeRestrictionHash = 0x10000000; private const int InstanceRestrictionHash = 0x20000000; private const int CustomRestrictionHash = 0x40000000; private BindingRestrictions() { } // Overridden by specialized subclasses internal abstract Expression GetExpression(); ////// Merges the set of binding restrictions with the current binding restrictions. /// /// The set of restrictions with which to merge the current binding restrictions. ///The new set of binding restrictions. public BindingRestrictions Merge(BindingRestrictions restrictions) { ContractUtils.RequiresNotNull(restrictions, "restrictions"); if (this == Empty) { return restrictions; } if (restrictions == Empty) { return this; } return new MergedRestriction(this, restrictions); } ////// Creates the binding restriction that check the expression for runtime type identity. /// /// The expression to test. /// The exact type to test. ///The new binding restrictions. public static BindingRestrictions GetTypeRestriction(Expression expression, Type type) { ContractUtils.RequiresNotNull(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); return new TypeRestriction(expression, type); } ////// The method takes a DynamicMetaObject, and returns an instance restriction for testing null if the object /// holds a null value, otherwise returns a type restriction. /// internal static BindingRestrictions GetTypeRestriction(DynamicMetaObject obj) { if (obj.Value == null && obj.HasValue) { return BindingRestrictions.GetInstanceRestriction(obj.Expression, null); } else { return BindingRestrictions.GetTypeRestriction(obj.Expression, obj.LimitType); } } ////// Creates the binding restriction that checks the expression for object instance identity. /// /// The expression to test. /// The exact object instance to test. ///The new binding restrictions. public static BindingRestrictions GetInstanceRestriction(Expression expression, object instance) { ContractUtils.RequiresNotNull(expression, "expression"); return new InstanceRestriction(expression, instance); } ////// Creates the binding restriction that checks the expression for arbitrary immutable properties. /// /// The expression expression the restrictions. ///The new binding restrictions. ////// By convention, the general restrictions created by this method must only test /// immutable object properties. /// public static BindingRestrictions GetExpressionRestriction(Expression expression) { ContractUtils.RequiresNotNull(expression, "expression"); ContractUtils.Requires(expression.Type == typeof(bool), "expression"); return new CustomRestriction(expression); } ////// Combines binding restrictions from the list of /// The list ofinstances into one set of restrictions. /// instances from which to combine restrictions. /// The new set of binding restrictions. public static BindingRestrictions Combine(IListcontributingObjects) { BindingRestrictions res = BindingRestrictions.Empty; if (contributingObjects != null) { foreach (DynamicMetaObject mo in contributingObjects) { if (mo != null) { res = res.Merge(mo.Restrictions); } } } return res; } /// /// Builds a balanced tree of AndAlso nodes. /// We do this so the compiler won't stack overflow if we have many /// restrictions. /// private sealed class TestBuilder { private readonly Set_unique = new Set (); private readonly Stack _tests = new Stack (); private struct AndNode { internal int Depth; internal Expression Node; } internal void Append(BindingRestrictions restrictions) { if (_unique.Contains(restrictions)) { return; } _unique.Add(restrictions); Push(restrictions.GetExpression(), 0); } internal Expression ToExpression() { Expression result = _tests.Pop().Node; while (_tests.Count > 0) { result = Expression.AndAlso(_tests.Pop().Node, result); } return result; } private void Push(Expression node, int depth) { while (_tests.Count > 0 && _tests.Peek().Depth == depth) { node = Expression.AndAlso(_tests.Pop().Node, node); depth++; } _tests.Push(new AndNode { Node = node, Depth = depth }); } } /// /// Creates the ///representing the binding restrictions. /// The expression tree representing the restrictions. public Expression ToExpression() { // We could optimize this better, e.g. common subexpression elimination // But for now, it's good enough. if (this == Empty) { return Expression.Constant(true); } var testBuilder = new TestBuilder(); // Visit the tree, left to right. // Use an explicit stack so we don't stack overflow. // // Left-most node is on top of the stack, so we always expand the // left most node each iteration. var stack = new Stack(); stack.Push(this); do { var top = stack.Pop(); var m = top as MergedRestriction; if (m != null) { stack.Push(m.Right); stack.Push(m.Left); } else { testBuilder.Append(top); } } while (stack.Count > 0); return testBuilder.ToExpression(); } private sealed class MergedRestriction : BindingRestrictions { internal readonly BindingRestrictions Left; internal readonly BindingRestrictions Right; internal MergedRestriction(BindingRestrictions left, BindingRestrictions right) { Left = left; Right = right; } internal override Expression GetExpression() { throw ContractUtils.Unreachable; } } private sealed class CustomRestriction : BindingRestrictions { private readonly Expression _expression; internal CustomRestriction(Expression expression) { _expression = expression; } public override bool Equals(object obj) { var other = obj as CustomRestriction; return other != null && other._expression == _expression; } public override int GetHashCode() { return CustomRestrictionHash ^ _expression.GetHashCode(); } internal override Expression GetExpression() { return _expression; } } private sealed class TypeRestriction : BindingRestrictions { private readonly Expression _expression; private readonly Type _type; internal TypeRestriction(Expression parameter, Type type) { _expression = parameter; _type = type; } public override bool Equals(object obj) { var other = obj as TypeRestriction; return other != null && TypeUtils.AreEquivalent(other._type, _type) && other._expression == _expression; } public override int GetHashCode() { return TypeRestrictionHash ^ _expression.GetHashCode() ^ _type.GetHashCode(); } internal override Expression GetExpression() { return Expression.TypeEqual(_expression, _type); } } private sealed class InstanceRestriction : BindingRestrictions { private readonly Expression _expression; private readonly object _instance; internal InstanceRestriction(Expression parameter, object instance) { _expression = parameter; _instance = instance; } public override bool Equals(object obj) { var other = obj as InstanceRestriction; return other != null && other._instance == _instance && other._expression == _expression; } public override int GetHashCode() { return InstanceRestrictionHash ^ RuntimeHelpers.GetHashCode(_instance) ^ _expression.GetHashCode(); } internal override Expression GetExpression() { if (_instance == null) { return Expression.Equal( Expression.Convert(_expression, typeof(object)), Expression.Constant(null) ); } ParameterExpression temp = Expression.Parameter(typeof(object), null); return Expression.Block( new[] { temp }, Expression.Assign( temp, Expression.Property( Expression.Constant(new WeakReference(_instance)), typeof(WeakReference).GetProperty("Target") ) ), Expression.AndAlso( //check that WeekReference was not collected. Expression.NotEqual(temp, Expression.Constant(null)), Expression.Equal( Expression.Convert(_expression, typeof(object)), temp ) ) ); } } private string DebugView { get { return ToExpression().ToString(); } } private sealed class BindingRestrictionsProxy { private readonly BindingRestrictions _node; public BindingRestrictionsProxy(BindingRestrictions node) { _node = node; } public bool IsEmpty { get { return _node == Empty; } } public Expression Test { get { return _node.ToExpression(); } } public BindingRestrictions[] Restrictions { get { var restrictions = new List (); // Visit the tree, left to right // // Left-most node is on top of the stack, so we always expand the // left most node each iteration. var stack = new Stack (); stack.Push(_node); do { var top = stack.Pop(); var m = top as MergedRestriction; if (m != null) { stack.Push(m.Right); stack.Push(m.Left); } else { restrictions.Add(top); } } while (stack.Count > 0); return restrictions.ToArray(); } } public override string ToString() { // To prevent fxcop warning about this field return _node.DebugView; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. /* **************************************************************************** * * Copyright (c) Microsoft Corporation. * * This source code is subject to terms and conditions of the Microsoft Public License. A * copy of the license can be found in the License.html file at the root of this distribution. If * you cannot locate the Microsoft Public License, please send an email to * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound * by the terms of the Microsoft Public License. * * You must not remove this notice, or any other, from this software. * * * ***************************************************************************/ using System.Collections.Generic; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions; using System.Runtime.CompilerServices; namespace System.Dynamic { /// /// Represents a set of binding restrictions on the #if !SILVERLIGHT [DebuggerTypeProxy(typeof(BindingRestrictionsProxy)), DebuggerDisplay("{DebugView}")] #endif public abstract class BindingRestrictions { ///under which the dynamic binding is valid. /// /// Represents an empty set of binding restrictions. This field is read only. /// [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2104:DoNotDeclareReadOnlyMutableReferenceTypes")] public static readonly BindingRestrictions Empty = new CustomRestriction(Expression.Constant(true)); private const int TypeRestrictionHash = 0x10000000; private const int InstanceRestrictionHash = 0x20000000; private const int CustomRestrictionHash = 0x40000000; private BindingRestrictions() { } // Overridden by specialized subclasses internal abstract Expression GetExpression(); ////// Merges the set of binding restrictions with the current binding restrictions. /// /// The set of restrictions with which to merge the current binding restrictions. ///The new set of binding restrictions. public BindingRestrictions Merge(BindingRestrictions restrictions) { ContractUtils.RequiresNotNull(restrictions, "restrictions"); if (this == Empty) { return restrictions; } if (restrictions == Empty) { return this; } return new MergedRestriction(this, restrictions); } ////// Creates the binding restriction that check the expression for runtime type identity. /// /// The expression to test. /// The exact type to test. ///The new binding restrictions. public static BindingRestrictions GetTypeRestriction(Expression expression, Type type) { ContractUtils.RequiresNotNull(expression, "expression"); ContractUtils.RequiresNotNull(type, "type"); return new TypeRestriction(expression, type); } ////// The method takes a DynamicMetaObject, and returns an instance restriction for testing null if the object /// holds a null value, otherwise returns a type restriction. /// internal static BindingRestrictions GetTypeRestriction(DynamicMetaObject obj) { if (obj.Value == null && obj.HasValue) { return BindingRestrictions.GetInstanceRestriction(obj.Expression, null); } else { return BindingRestrictions.GetTypeRestriction(obj.Expression, obj.LimitType); } } ////// Creates the binding restriction that checks the expression for object instance identity. /// /// The expression to test. /// The exact object instance to test. ///The new binding restrictions. public static BindingRestrictions GetInstanceRestriction(Expression expression, object instance) { ContractUtils.RequiresNotNull(expression, "expression"); return new InstanceRestriction(expression, instance); } ////// Creates the binding restriction that checks the expression for arbitrary immutable properties. /// /// The expression expression the restrictions. ///The new binding restrictions. ////// By convention, the general restrictions created by this method must only test /// immutable object properties. /// public static BindingRestrictions GetExpressionRestriction(Expression expression) { ContractUtils.RequiresNotNull(expression, "expression"); ContractUtils.Requires(expression.Type == typeof(bool), "expression"); return new CustomRestriction(expression); } ////// Combines binding restrictions from the list of /// The list ofinstances into one set of restrictions. /// instances from which to combine restrictions. /// The new set of binding restrictions. public static BindingRestrictions Combine(IListcontributingObjects) { BindingRestrictions res = BindingRestrictions.Empty; if (contributingObjects != null) { foreach (DynamicMetaObject mo in contributingObjects) { if (mo != null) { res = res.Merge(mo.Restrictions); } } } return res; } /// /// Builds a balanced tree of AndAlso nodes. /// We do this so the compiler won't stack overflow if we have many /// restrictions. /// private sealed class TestBuilder { private readonly Set_unique = new Set (); private readonly Stack _tests = new Stack (); private struct AndNode { internal int Depth; internal Expression Node; } internal void Append(BindingRestrictions restrictions) { if (_unique.Contains(restrictions)) { return; } _unique.Add(restrictions); Push(restrictions.GetExpression(), 0); } internal Expression ToExpression() { Expression result = _tests.Pop().Node; while (_tests.Count > 0) { result = Expression.AndAlso(_tests.Pop().Node, result); } return result; } private void Push(Expression node, int depth) { while (_tests.Count > 0 && _tests.Peek().Depth == depth) { node = Expression.AndAlso(_tests.Pop().Node, node); depth++; } _tests.Push(new AndNode { Node = node, Depth = depth }); } } /// /// Creates the ///representing the binding restrictions. /// The expression tree representing the restrictions. public Expression ToExpression() { // We could optimize this better, e.g. common subexpression elimination // But for now, it's good enough. if (this == Empty) { return Expression.Constant(true); } var testBuilder = new TestBuilder(); // Visit the tree, left to right. // Use an explicit stack so we don't stack overflow. // // Left-most node is on top of the stack, so we always expand the // left most node each iteration. var stack = new Stack(); stack.Push(this); do { var top = stack.Pop(); var m = top as MergedRestriction; if (m != null) { stack.Push(m.Right); stack.Push(m.Left); } else { testBuilder.Append(top); } } while (stack.Count > 0); return testBuilder.ToExpression(); } private sealed class MergedRestriction : BindingRestrictions { internal readonly BindingRestrictions Left; internal readonly BindingRestrictions Right; internal MergedRestriction(BindingRestrictions left, BindingRestrictions right) { Left = left; Right = right; } internal override Expression GetExpression() { throw ContractUtils.Unreachable; } } private sealed class CustomRestriction : BindingRestrictions { private readonly Expression _expression; internal CustomRestriction(Expression expression) { _expression = expression; } public override bool Equals(object obj) { var other = obj as CustomRestriction; return other != null && other._expression == _expression; } public override int GetHashCode() { return CustomRestrictionHash ^ _expression.GetHashCode(); } internal override Expression GetExpression() { return _expression; } } private sealed class TypeRestriction : BindingRestrictions { private readonly Expression _expression; private readonly Type _type; internal TypeRestriction(Expression parameter, Type type) { _expression = parameter; _type = type; } public override bool Equals(object obj) { var other = obj as TypeRestriction; return other != null && TypeUtils.AreEquivalent(other._type, _type) && other._expression == _expression; } public override int GetHashCode() { return TypeRestrictionHash ^ _expression.GetHashCode() ^ _type.GetHashCode(); } internal override Expression GetExpression() { return Expression.TypeEqual(_expression, _type); } } private sealed class InstanceRestriction : BindingRestrictions { private readonly Expression _expression; private readonly object _instance; internal InstanceRestriction(Expression parameter, object instance) { _expression = parameter; _instance = instance; } public override bool Equals(object obj) { var other = obj as InstanceRestriction; return other != null && other._instance == _instance && other._expression == _expression; } public override int GetHashCode() { return InstanceRestrictionHash ^ RuntimeHelpers.GetHashCode(_instance) ^ _expression.GetHashCode(); } internal override Expression GetExpression() { if (_instance == null) { return Expression.Equal( Expression.Convert(_expression, typeof(object)), Expression.Constant(null) ); } ParameterExpression temp = Expression.Parameter(typeof(object), null); return Expression.Block( new[] { temp }, Expression.Assign( temp, Expression.Property( Expression.Constant(new WeakReference(_instance)), typeof(WeakReference).GetProperty("Target") ) ), Expression.AndAlso( //check that WeekReference was not collected. Expression.NotEqual(temp, Expression.Constant(null)), Expression.Equal( Expression.Convert(_expression, typeof(object)), temp ) ) ); } } private string DebugView { get { return ToExpression().ToString(); } } private sealed class BindingRestrictionsProxy { private readonly BindingRestrictions _node; public BindingRestrictionsProxy(BindingRestrictions node) { _node = node; } public bool IsEmpty { get { return _node == Empty; } } public Expression Test { get { return _node.ToExpression(); } } public BindingRestrictions[] Restrictions { get { var restrictions = new List (); // Visit the tree, left to right // // Left-most node is on top of the stack, so we always expand the // left most node each iteration. var stack = new Stack (); stack.Push(_node); do { var top = stack.Pop(); var m = top as MergedRestriction; if (m != null) { stack.Push(m.Right); stack.Push(m.Left); } else { restrictions.Add(top); } } while (stack.Count > 0); return restrictions.ToArray(); } } public override string ToString() { // To prevent fxcop warning about this field return _node.DebugView; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- StreamWithDictionary.cs
- WorkflowOwnershipException.cs
- MetafileEditor.cs
- NullExtension.cs
- TextRangeProviderWrapper.cs
- InstancePersistence.cs
- HtmlControlPersistable.cs
- GenericEnumConverter.cs
- ContextMenuService.cs
- FormViewInsertedEventArgs.cs
- HwndStylusInputProvider.cs
- BlobPersonalizationState.cs
- SqlProfileProvider.cs
- MultiBindingExpression.cs
- ReadOnlyAttribute.cs
- MatrixTransform3D.cs
- SafePEFileHandle.cs
- BinaryUtilClasses.cs
- BamlRecords.cs
- SurrogateChar.cs
- IISMapPath.cs
- PersianCalendar.cs
- Operators.cs
- Decoder.cs
- TextRangeBase.cs
- DockAndAnchorLayout.cs
- ResolvedKeyFrameEntry.cs
- TypeConverterHelper.cs
- XmlCharCheckingReader.cs
- HMACMD5.cs
- DataGridColumnCollection.cs
- XmlUtil.cs
- TickBar.cs
- Event.cs
- ErrorTolerantObjectWriter.cs
- SamlSecurityTokenAuthenticator.cs
- MILUtilities.cs
- ListViewGroupConverter.cs
- SessionIDManager.cs
- DataGridDefaultColumnWidthTypeConverter.cs
- MulticastNotSupportedException.cs
- XmlSchema.cs
- PerformanceCounterNameAttribute.cs
- TemplateColumn.cs
- QuaternionConverter.cs
- OleDbConnectionInternal.cs
- RowParagraph.cs
- PostBackOptions.cs
- Expressions.cs
- ComplexPropertyEntry.cs
- GridViewDeleteEventArgs.cs
- DependencyPropertyHelper.cs
- Int64.cs
- DataObjectAttribute.cs
- UserInitiatedRoutedEventPermissionAttribute.cs
- ReceiveActivityValidator.cs
- EntitySqlQueryState.cs
- SaveWorkflowAsyncResult.cs
- RelatedCurrencyManager.cs
- PhysicalAddress.cs
- CssClassPropertyAttribute.cs
- UmAlQuraCalendar.cs
- StylusLogic.cs
- PaperSource.cs
- BuildProviderInstallComponent.cs
- coordinatorfactory.cs
- ListItemParagraph.cs
- BigInt.cs
- EditorBrowsableAttribute.cs
- CodeThrowExceptionStatement.cs
- CalendarKeyboardHelper.cs
- LongAverageAggregationOperator.cs
- SortFieldComparer.cs
- DelegatingTypeDescriptionProvider.cs
- RouteParametersHelper.cs
- TextEncodedRawTextWriter.cs
- SourceFileInfo.cs
- SpeakCompletedEventArgs.cs
- recordstatefactory.cs
- QueryInterceptorAttribute.cs
- HostProtectionException.cs
- DataGridViewSelectedRowCollection.cs
- FileSystemEventArgs.cs
- ColumnCollection.cs
- IxmlLineInfo.cs
- ProxyFragment.cs
- ImageButton.cs
- CommonProperties.cs
- WizardSideBarListControlItemEventArgs.cs
- MsmqTransportReceiveParameters.cs
- MeasureItemEvent.cs
- MergeFailedEvent.cs
- PinnedBufferMemoryStream.cs
- CurrentTimeZone.cs
- configsystem.cs
- AudioSignalProblemOccurredEventArgs.cs
- PathGeometry.cs
- ComNativeDescriptor.cs
- SocketElement.cs
- FaultCallbackWrapper.cs