Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
DispCallableMetaObject.cs135 linesDownload Raw Back to ComInterop
1// Licensed to the .NET Foundation under one or more agreements.2// The .NET Foundation licenses this file to you under the MIT license.3 4using System.Collections.Generic;5using System.Dynamic;6using System.Linq;7using System.Linq.Expressions;8using System.Management.Automation.Language;9 10namespace System.Management.Automation.ComInterop11{12    internal class DispCallableMetaObject : DynamicMetaObject13    {14        private readonly DispCallable _callable;15 16        internal DispCallableMetaObject(Expression expression, DispCallable callable)17            : base(expression, BindingRestrictions.Empty, callable)18        {19            _callable = callable;20        }21 22        public override DynamicMetaObject BindGetIndex(GetIndexBinder binder, DynamicMetaObject[] indexes)23        {24            return BindGetOrInvoke(indexes, binder.CallInfo) ??25                base.BindGetIndex(binder, indexes);26        }27 28        public override DynamicMetaObject BindInvoke(InvokeBinder binder, DynamicMetaObject[] args)29        {30            return BindGetOrInvoke(args, binder.CallInfo) ??31                base.BindInvoke(binder, args);32        }33 34        private DynamicMetaObject BindGetOrInvoke(DynamicMetaObject[] args, CallInfo callInfo)35        {36            IDispatchComObject target = _callable.DispatchComObject;37            string name = _callable.MemberName;38 39            if (target.TryGetMemberMethod(name, out ComMethodDesc method) ||40                target.TryGetMemberMethodExplicit(name, out method))41            {42                List<ParameterExpression> temps = new List<ParameterExpression>();43                List<Expression> initTemps = new List<Expression>();44 45                bool[] isByRef = ComBinderHelpers.ProcessArgumentsForCom(method, ref args, temps, initTemps);46                return BindComInvoke(method, args, callInfo, isByRef, temps, initTemps);47            }48            return null;49        }50 51        public override DynamicMetaObject BindSetIndex(SetIndexBinder binder, DynamicMetaObject[] indexes, DynamicMetaObject value)52        {53            IDispatchComObject target = _callable.DispatchComObject;54            string name = _callable.MemberName;55 56            bool holdsNull = value.Value == null && value.HasValue;57            if (target.TryGetPropertySetter(name, out ComMethodDesc method, value.LimitType, holdsNull) ||58                target.TryGetPropertySetterExplicit(name, out method, value.LimitType, holdsNull))59            {60                List<ParameterExpression> temps = new List<ParameterExpression>();61                List<Expression> initTemps = new List<Expression>();62 63                bool[] isByRef = ComBinderHelpers.ProcessArgumentsForCom(method, ref indexes, temps, initTemps);64                isByRef = isByRef.AddLast(false);65                // Convert the value to the target type66                DynamicMetaObject updatedValue = new DynamicMetaObject(67                    value.CastOrConvertMethodArgument(68                        value.LimitType,69                        name,70                        "SetIndex",71                        allowCastingToByRefLikeType: false,72                        temps,73                        initTemps),74                    value.Restrictions);75 76                var result = BindComInvoke(method, indexes.AddLast(updatedValue), binder.CallInfo, isByRef, temps, initTemps);77 78                // Make sure to return the value; some languages need it.79                return new DynamicMetaObject(80                    Expression.Block(result.Expression, Expression.Convert(value.Expression, typeof(object))),81                    result.Restrictions82                );83            }84 85            return base.BindSetIndex(binder, indexes, value);86        }87 88        private DynamicMetaObject BindComInvoke(ComMethodDesc method, DynamicMetaObject[] indexes, CallInfo callInfo, bool[] isByRef,89            List<ParameterExpression> temps, List<Expression> initTemps)90        {91            Expression callable = Expression;92            Expression dispCall = Helpers.Convert(callable, typeof(DispCallable));93 94            DynamicMetaObject invoke = new ComInvokeBinder(95                callInfo,96                indexes,97                isByRef,98                DispCallableRestrictions(),99                Expression.Constant(method),100                Expression.Property(101                    dispCall,102                    typeof(DispCallable).GetProperty(nameof(DispCallable.DispatchObject))103                ),104                method105            ).Invoke();106 107            if (temps != null && temps.Count > 0)108            {109                Expression invokeExpression = invoke.Expression;110                Expression call = Expression.Block(invokeExpression.Type, temps, initTemps.Append(invokeExpression));111                invoke = new DynamicMetaObject(call, invoke.Restrictions);112            }113 114            return invoke;115        }116 117        private BindingRestrictions DispCallableRestrictions()118        {119            Expression callable = Expression;120 121            BindingRestrictions callableTypeRestrictions = BindingRestrictions.GetTypeRestriction(callable, typeof(DispCallable));122            Expression dispCall = Helpers.Convert(callable, typeof(DispCallable));123            MemberExpression dispatch = Expression.Property(dispCall, typeof(DispCallable).GetProperty(nameof(DispCallable.DispatchComObject)));124            MemberExpression dispId = Expression.Property(dispCall, typeof(DispCallable).GetProperty(nameof(DispCallable.DispId)));125 126            BindingRestrictions dispatchRestriction = IDispatchMetaObject.IDispatchRestriction(dispatch, _callable.DispatchComObject.ComTypeDesc);127            BindingRestrictions memberRestriction = BindingRestrictions.GetExpressionRestriction(128                Expression.Equal(dispId, Expression.Constant(_callable.DispId))129            );130 131            return callableTypeRestrictions.Merge(dispatchRestriction).Merge(memberRestriction);132        }133    }134}135