Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / Core / Microsoft / Scripting / Actions / DynamicMetaObjectBinder.cs / 1305376 / DynamicMetaObjectBinder.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.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions; using System.Linq.Expressions.Compiler; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #else using System.Runtime.Remoting; #endif namespace System.Dynamic { ////// The dynamic call site binder that participates in the ///binding protocol. /// /// The public abstract class DynamicMetaObjectBinder : CallSiteBinder { #region Public APIs ///performs the binding of the dynamic operation using the runtime values /// as input. On the other hand, the participates in the /// binding protocol. /// /// Initializes a new instance of the protected DynamicMetaObjectBinder() { } ///class. /// /// The result type of the operation. /// public virtual Type ReturnType { get { return typeof(object); } } ////// Performs the runtime binding of the dynamic operation on a set of arguments. /// /// An array of arguments to the dynamic operation. /// The array ofinstances that represent the parameters of the call site in the binding process. /// A LabelTarget used to return the result of the dynamic binding. /// /// An Expression that performs tests on the dynamic operation arguments, and /// performs the dynamic operation if hte tests are valid. If the tests fail on /// subsequent occurrences of the dynamic operation, Bind will be called again /// to produce a new public sealed override Expression Bind(object[] args, ReadOnlyCollectionfor the new argument types. /// parameters, LabelTarget returnLabel) { ContractUtils.RequiresNotNull(args, "args"); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNull(returnLabel, "returnLabel"); if (args.Length == 0) { throw Error.OutOfRange("args.Length", 1); } if (parameters.Count == 0) { throw Error.OutOfRange("parameters.Count", 1); } if (args.Length != parameters.Count) { throw new ArgumentOutOfRangeException("args"); } // Ensure that the binder's ReturnType matches CallSite's return // type. We do this so meta objects and language binders can // compose trees together without needing to insert converts. Type expectedResult; if (IsStandardBinder) { expectedResult = ReturnType; if (returnLabel.Type != typeof(void) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, expectedResult)) { throw Error.BinderNotCompatibleWithCallSite(expectedResult, this, returnLabel.Type); } } else { // Even for non-standard binders, we have to at least make sure // it works with the CallSite's type to build the return. expectedResult = returnLabel.Type; } DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]); DynamicMetaObject[] metaArgs = CreateArgumentMetaObjects(args, parameters); DynamicMetaObject binding = Bind(target, metaArgs); if (binding == null) { throw Error.BindingCannotBeNull(); } Expression body = binding.Expression; BindingRestrictions restrictions = binding.Restrictions; // Ensure the result matches the expected result type. if (expectedResult != typeof(void) && !TypeUtils.AreReferenceAssignable(expectedResult, body.Type)) { // // Blame the last person that handled the result: assume it's // the dynamic object (if any), otherwise blame the language. // if (target.Value is IDynamicMetaObjectProvider) { throw Error.DynamicObjectResultNotAssignable(body.Type, target.Value.GetType(), this, expectedResult); } else { throw Error.DynamicBinderResultNotAssignable(body.Type, this, expectedResult); } } // if the target is IDO, standard binders ask it to bind the rule so we may have a target-specific binding. // it makes sense to restrict on the target's type in such cases. // ideally IDO metaobjects should do this, but they often miss that type of "this" is significant. if (IsStandardBinder && args[0] as IDynamicMetaObjectProvider != null) { if (restrictions == BindingRestrictions.Empty) { throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this); } } restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters); // Add the return if (body.NodeType != ExpressionType.Goto) { body = Expression.Return(returnLabel, body); } // Finally, add restrictions if (restrictions != BindingRestrictions.Empty) { body = Expression.IfThen(restrictions.ToExpression(), body); } return body; } private static DynamicMetaObject[] CreateArgumentMetaObjects(object[] args, ReadOnlyCollection parameters) { DynamicMetaObject[] mos; if (args.Length != 1) { mos = new DynamicMetaObject[args.Length - 1]; for (int i = 1; i < args.Length; i++) { mos[i - 1] = DynamicMetaObject.Create(args[i], parameters[i]); } } else { mos = DynamicMetaObject.EmptyMetaObjects; } return mos; } private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection parameters) { #if !SILVERLIGHT for (int i = 0; i < parameters.Count; i++) { var expr = parameters[i]; var value = args[i] as MarshalByRefObject; // special case for MBR objects. // when MBR objects are remoted they can have different conversion behavior // so bindings created for local and remote objects should not be mixed. if (value != null && !IsComObject(value)) { BindingRestrictions remotedRestriction; if (RemotingServices.IsObjectOutOfAppDomain(value)) { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ); } else { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Not( Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ) ); } restrictions = restrictions.Merge(remotedRestriction); } } #endif return restrictions; } /// /// When overridden in the derived class, performs the binding of the dynamic operation. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public abstract DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args); ///representing the result of the binding. /// Gets an expression that will cause the binding to be updated. It /// indicates that the expression's binding is no longer valid. /// This is typically used when the "version" of a dynamic object has /// changed. /// /// TheType property of the resulting expression; any type is allowed. ///The update expression. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] public Expression GetUpdateExpression(Type type) { return Expression.Goto(CallSiteBinder.UpdateLabel, type); } ////// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNull(target, "target"); if (args == null) { return MakeDeferred(target.Restrictions, target); } else { return MakeDeferred( target.Restrictions.Merge(BindingRestrictions.Combine(args)), args.AddFirst(target) ); } } ///representing the result of the binding. /// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(params DynamicMetaObject[] args) { return MakeDeferred(BindingRestrictions.Combine(args), args); } private DynamicMetaObject MakeDeferred(BindingRestrictions rs, params DynamicMetaObject[] args) { var exprs = DynamicMetaObject.GetExpressions(args); Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, ReturnType); // Because we know the arguments match the delegate type (we just created the argument types) // we go directly to DynamicExpression.Make to avoid a bunch of unnecessary argument validation return new DynamicMetaObject( DynamicExpression.Make(ReturnType, delegateType, this, new TrueReadOnlyCollectionrepresenting the result of the binding. (exprs)), rs ); } #endregion // used to detect standard MetaObjectBinders. internal virtual bool IsStandardBinder { get { return false; } } #if !SILVERLIGHT private static readonly Type ComObjectType = typeof(object).Assembly.GetType("System.__ComObject"); private static bool IsComObject(object obj) { // we can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust return obj != null && ComObjectType.IsAssignableFrom(obj.GetType()); } #endif } } // 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.ObjectModel; using System.Diagnostics; using System.Dynamic.Utils; using System.Linq.Expressions; using System.Linq.Expressions.Compiler; using System.Runtime.CompilerServices; #if SILVERLIGHT using System.Core; #else using System.Runtime.Remoting; #endif namespace System.Dynamic { /// /// The dynamic call site binder that participates in the ///binding protocol. /// /// The public abstract class DynamicMetaObjectBinder : CallSiteBinder { #region Public APIs ///performs the binding of the dynamic operation using the runtime values /// as input. On the other hand, the participates in the /// binding protocol. /// /// Initializes a new instance of the protected DynamicMetaObjectBinder() { } ///class. /// /// The result type of the operation. /// public virtual Type ReturnType { get { return typeof(object); } } ////// Performs the runtime binding of the dynamic operation on a set of arguments. /// /// An array of arguments to the dynamic operation. /// The array ofinstances that represent the parameters of the call site in the binding process. /// A LabelTarget used to return the result of the dynamic binding. /// /// An Expression that performs tests on the dynamic operation arguments, and /// performs the dynamic operation if hte tests are valid. If the tests fail on /// subsequent occurrences of the dynamic operation, Bind will be called again /// to produce a new public sealed override Expression Bind(object[] args, ReadOnlyCollectionfor the new argument types. /// parameters, LabelTarget returnLabel) { ContractUtils.RequiresNotNull(args, "args"); ContractUtils.RequiresNotNull(parameters, "parameters"); ContractUtils.RequiresNotNull(returnLabel, "returnLabel"); if (args.Length == 0) { throw Error.OutOfRange("args.Length", 1); } if (parameters.Count == 0) { throw Error.OutOfRange("parameters.Count", 1); } if (args.Length != parameters.Count) { throw new ArgumentOutOfRangeException("args"); } // Ensure that the binder's ReturnType matches CallSite's return // type. We do this so meta objects and language binders can // compose trees together without needing to insert converts. Type expectedResult; if (IsStandardBinder) { expectedResult = ReturnType; if (returnLabel.Type != typeof(void) && !TypeUtils.AreReferenceAssignable(returnLabel.Type, expectedResult)) { throw Error.BinderNotCompatibleWithCallSite(expectedResult, this, returnLabel.Type); } } else { // Even for non-standard binders, we have to at least make sure // it works with the CallSite's type to build the return. expectedResult = returnLabel.Type; } DynamicMetaObject target = DynamicMetaObject.Create(args[0], parameters[0]); DynamicMetaObject[] metaArgs = CreateArgumentMetaObjects(args, parameters); DynamicMetaObject binding = Bind(target, metaArgs); if (binding == null) { throw Error.BindingCannotBeNull(); } Expression body = binding.Expression; BindingRestrictions restrictions = binding.Restrictions; // Ensure the result matches the expected result type. if (expectedResult != typeof(void) && !TypeUtils.AreReferenceAssignable(expectedResult, body.Type)) { // // Blame the last person that handled the result: assume it's // the dynamic object (if any), otherwise blame the language. // if (target.Value is IDynamicMetaObjectProvider) { throw Error.DynamicObjectResultNotAssignable(body.Type, target.Value.GetType(), this, expectedResult); } else { throw Error.DynamicBinderResultNotAssignable(body.Type, this, expectedResult); } } // if the target is IDO, standard binders ask it to bind the rule so we may have a target-specific binding. // it makes sense to restrict on the target's type in such cases. // ideally IDO metaobjects should do this, but they often miss that type of "this" is significant. if (IsStandardBinder && args[0] as IDynamicMetaObjectProvider != null) { if (restrictions == BindingRestrictions.Empty) { throw Error.DynamicBindingNeedsRestrictions(target.Value.GetType(), this); } } restrictions = AddRemoteObjectRestrictions(restrictions, args, parameters); // Add the return if (body.NodeType != ExpressionType.Goto) { body = Expression.Return(returnLabel, body); } // Finally, add restrictions if (restrictions != BindingRestrictions.Empty) { body = Expression.IfThen(restrictions.ToExpression(), body); } return body; } private static DynamicMetaObject[] CreateArgumentMetaObjects(object[] args, ReadOnlyCollection parameters) { DynamicMetaObject[] mos; if (args.Length != 1) { mos = new DynamicMetaObject[args.Length - 1]; for (int i = 1; i < args.Length; i++) { mos[i - 1] = DynamicMetaObject.Create(args[i], parameters[i]); } } else { mos = DynamicMetaObject.EmptyMetaObjects; } return mos; } private static BindingRestrictions AddRemoteObjectRestrictions(BindingRestrictions restrictions, object[] args, ReadOnlyCollection parameters) { #if !SILVERLIGHT for (int i = 0; i < parameters.Count; i++) { var expr = parameters[i]; var value = args[i] as MarshalByRefObject; // special case for MBR objects. // when MBR objects are remoted they can have different conversion behavior // so bindings created for local and remote objects should not be mixed. if (value != null && !IsComObject(value)) { BindingRestrictions remotedRestriction; if (RemotingServices.IsObjectOutOfAppDomain(value)) { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ); } else { remotedRestriction = BindingRestrictions.GetExpressionRestriction( Expression.AndAlso( Expression.NotEqual(expr, Expression.Constant(null)), Expression.Not( Expression.Call( typeof(RemotingServices).GetMethod("IsObjectOutOfAppDomain"), expr ) ) ) ); } restrictions = restrictions.Merge(remotedRestriction); } } #endif return restrictions; } /// /// When overridden in the derived class, performs the binding of the dynamic operation. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public abstract DynamicMetaObject Bind(DynamicMetaObject target, DynamicMetaObject[] args); ///representing the result of the binding. /// Gets an expression that will cause the binding to be updated. It /// indicates that the expression's binding is no longer valid. /// This is typically used when the "version" of a dynamic object has /// changed. /// /// TheType property of the resulting expression; any type is allowed. ///The update expression. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")] public Expression GetUpdateExpression(Type type) { return Expression.Goto(CallSiteBinder.UpdateLabel, type); } ////// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// The target of the dynamic operation. /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(DynamicMetaObject target, params DynamicMetaObject[] args) { ContractUtils.RequiresNotNull(target, "target"); if (args == null) { return MakeDeferred(target.Restrictions, target); } else { return MakeDeferred( target.Restrictions.Merge(BindingRestrictions.Combine(args)), args.AddFirst(target) ); } } ///representing the result of the binding. /// Defers the binding of the operation until later time when the runtime values of all dynamic operation arguments have been computed. /// /// An array of arguments of the dynamic operation. ///The public DynamicMetaObject Defer(params DynamicMetaObject[] args) { return MakeDeferred(BindingRestrictions.Combine(args), args); } private DynamicMetaObject MakeDeferred(BindingRestrictions rs, params DynamicMetaObject[] args) { var exprs = DynamicMetaObject.GetExpressions(args); Type delegateType = DelegateHelpers.MakeDeferredSiteDelegate(args, ReturnType); // Because we know the arguments match the delegate type (we just created the argument types) // we go directly to DynamicExpression.Make to avoid a bunch of unnecessary argument validation return new DynamicMetaObject( DynamicExpression.Make(ReturnType, delegateType, this, new TrueReadOnlyCollectionrepresenting the result of the binding. (exprs)), rs ); } #endregion // used to detect standard MetaObjectBinders. internal virtual bool IsStandardBinder { get { return false; } } #if !SILVERLIGHT private static readonly Type ComObjectType = typeof(object).Assembly.GetType("System.__ComObject"); private static bool IsComObject(object obj) { // we can't use System.Runtime.InteropServices.Marshal.IsComObject(obj) since it doesn't work in partial trust return obj != null && ComObjectType.IsAssignableFrom(obj.GetType()); } #endif } } // 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
- FilteredXmlReader.cs
- ObjectDataSourceEventArgs.cs
- UnsafeNativeMethods.cs
- SoapProcessingBehavior.cs
- NamespaceDisplay.xaml.cs
- StateValidator.cs
- XPathDocumentBuilder.cs
- MdImport.cs
- StagingAreaInputItem.cs
- PermissionRequestEvidence.cs
- FixedHighlight.cs
- DataGridRelationshipRow.cs
- LinqToSqlWrapper.cs
- LinqExpressionNormalizer.cs
- HScrollProperties.cs
- DeclaredTypeElement.cs
- TableLayoutPanelResizeGlyph.cs
- ParameterCollection.cs
- DecoratedNameAttribute.cs
- DetailsViewCommandEventArgs.cs
- Translator.cs
- RawKeyboardInputReport.cs
- XmlAttributeCollection.cs
- BindingManagerDataErrorEventArgs.cs
- ClientSettingsStore.cs
- DocumentStatusResources.cs
- DataGridViewRowHeaderCell.cs
- Button.cs
- WindowsContainer.cs
- InitializerFacet.cs
- PDBReader.cs
- JoinTreeSlot.cs
- ConnectionManager.cs
- ListParaClient.cs
- GeometryDrawing.cs
- EventRoute.cs
- ButtonChrome.cs
- EditorAttribute.cs
- HttpApplication.cs
- ToolstripProfessionalRenderer.cs
- ComPlusContractBehavior.cs
- SortableBindingList.cs
- SimpleExpression.cs
- LogSwitch.cs
- DataListItemCollection.cs
- ParserHooks.cs
- MobileControlsSection.cs
- DiscriminatorMap.cs
- XmlQueryStaticData.cs
- SQLDecimalStorage.cs
- FileSystemEventArgs.cs
- FontStretch.cs
- StdValidatorsAndConverters.cs
- MatrixTransform.cs
- DataGridViewLinkColumn.cs
- OperationInvokerBehavior.cs
- TransportOutputChannel.cs
- TrustSection.cs
- ColumnResult.cs
- Int32CollectionConverter.cs
- StorageComplexTypeMapping.cs
- XmlCountingReader.cs
- SqlNode.cs
- SimpleBitVector32.cs
- ArrayElementGridEntry.cs
- IgnoreDataMemberAttribute.cs
- DesigntimeLicenseContextSerializer.cs
- BatchServiceHost.cs
- RijndaelManaged.cs
- QuaternionAnimationBase.cs
- SrgsGrammar.cs
- NotifyCollectionChangedEventArgs.cs
- StreamResourceInfo.cs
- MulticastIPAddressInformationCollection.cs
- ToolStripOverflowButton.cs
- Literal.cs
- RSAPKCS1SignatureDeformatter.cs
- DataGridViewLinkCell.cs
- TabControlEvent.cs
- SqlAliaser.cs
- ObjectIDGenerator.cs
- x509store.cs
- BuildDependencySet.cs
- TextTreePropertyUndoUnit.cs
- DnsPermission.cs
- GACMembershipCondition.cs
- CaseInsensitiveOrdinalStringComparer.cs
- EmptyReadOnlyDictionaryInternal.cs
- FileNameEditor.cs
- TransformationRules.cs
- EmbeddedMailObject.cs
- SerializationEventsCache.cs
- XmlMembersMapping.cs
- ArrayMergeHelper.cs
- Converter.cs
- ColumnMapTranslator.cs
- PolyLineSegment.cs
- HandlerFactoryCache.cs
- CodeGenerator.cs
- SyntaxCheck.cs