Code:
/ 4.0 / 4.0 / untmp / 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.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- WebServiceReceive.cs
- HttpListenerException.cs
- EventLogTraceListener.cs
- PreloadedPackages.cs
- ApplicationFileParser.cs
- ApplicationGesture.cs
- Application.cs
- BitmapFrame.cs
- ResolveNameEventArgs.cs
- DisplayNameAttribute.cs
- AuthenticationConfig.cs
- ScalarConstant.cs
- ISFTagAndGuidCache.cs
- AnnotationResourceChangedEventArgs.cs
- ContentDesigner.cs
- XmlCharType.cs
- SqlServer2KCompatibilityAnnotation.cs
- SoapObjectWriter.cs
- EventLogSession.cs
- ContextMenuStripGroupCollection.cs
- InstanceData.cs
- TextLineResult.cs
- StrongNamePublicKeyBlob.cs
- KeyValueConfigurationCollection.cs
- TypeConverterValueSerializer.cs
- DSASignatureDeformatter.cs
- CodeTryCatchFinallyStatement.cs
- FontWeight.cs
- OleStrCAMarshaler.cs
- AdapterUtil.cs
- GridViewRowEventArgs.cs
- ConfigurationSection.cs
- IdentifierCreationService.cs
- HttpPostedFileBase.cs
- XNodeSchemaApplier.cs
- ListView.cs
- UriTemplateTrieLocation.cs
- HostingEnvironment.cs
- EnumValAlphaComparer.cs
- Events.cs
- storagemappingitemcollection.viewdictionary.cs
- RoutedUICommand.cs
- UnsafeMethods.cs
- DrawToolTipEventArgs.cs
- HtmlEncodedRawTextWriter.cs
- SyndicationDeserializer.cs
- Splitter.cs
- COM2ExtendedTypeConverter.cs
- NamespaceInfo.cs
- OutKeywords.cs
- JsonServiceDocumentSerializer.cs
- SettingsBindableAttribute.cs
- RegexCompilationInfo.cs
- DataTableMappingCollection.cs
- BindingManagerDataErrorEventArgs.cs
- NavigationEventArgs.cs
- newinstructionaction.cs
- GCHandleCookieTable.cs
- SelectedDatesCollection.cs
- ObjectConverter.cs
- unsafenativemethodstextservices.cs
- CookieProtection.cs
- EdmComplexTypeAttribute.cs
- LoginName.cs
- ReferenceAssemblyAttribute.cs
- FormViewPageEventArgs.cs
- CodeDOMProvider.cs
- TemplateControlCodeDomTreeGenerator.cs
- DoubleAnimationUsingKeyFrames.cs
- WsdlBuildProvider.cs
- SchemaNamespaceManager.cs
- IncrementalHitTester.cs
- FileChangeNotifier.cs
- ObjectFactoryCodeDomTreeGenerator.cs
- HttpCachePolicyWrapper.cs
- EncoderFallback.cs
- DesignRelation.cs
- Validator.cs
- SelectionRangeConverter.cs
- ApplyTemplatesAction.cs
- DataGridColumn.cs
- CqlLexer.cs
- WebMessageEncodingElement.cs
- XsdBuildProvider.cs
- XmlSchemaFacet.cs
- ResourceSet.cs
- ServicePointManager.cs
- InvokeProviderWrapper.cs
- TextEffect.cs
- KeySpline.cs
- PackWebRequestFactory.cs
- ErrorStyle.cs
- CompModSwitches.cs
- PersistNameAttribute.cs
- SqlErrorCollection.cs
- CompilationSection.cs
- SynchronousReceiveElement.cs
- RightsManagementPermission.cs
- DataServiceRequestOfT.cs
- Graphics.cs