Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
ComBinderHelpers.cs137 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 4#pragma warning disable 618 // CurrencyWrapper is obsolete5 6using System;7using System.Collections.Generic;8using System.Diagnostics;9using System.Dynamic;10using System.Globalization;11using System.Linq.Expressions;12using System.Management.Automation.Language;13using System.Runtime.InteropServices;14 15namespace System.Management.Automation.ComInterop16{17    internal static class ComBinderHelpers18    {19        internal static bool PreferPut(Type type, bool holdsNull)20        {21            Debug.Assert(type != null);22 23            if (type.IsValueType24                || type.IsArray25                || type == typeof(string)26                || type == typeof(DBNull)27                || holdsNull28                || type == typeof(System.Reflection.Missing)29                || type == typeof(CurrencyWrapper))30            {31                return true;32            }33 34            return false;35        }36 37        internal static bool IsByRef(DynamicMetaObject mo)38        {39            return mo.Expression is ParameterExpression pe && pe.IsByRef;40        }41 42        internal static bool IsPSReferenceArg(DynamicMetaObject o)43        {44            Type t = o.LimitType;45            return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(PSReference<>);46        }47 48        // This helper prepares arguments for COM binding by transforming ByVal StrongBox arguments49        // into ByRef expressions that represent the argument's Value fields.50        internal static bool[] ProcessArgumentsForCom(ComMethodDesc method, ref DynamicMetaObject[] args,51            List<ParameterExpression> temps, List<Expression> initTemps)52        {53            Debug.Assert(args != null);54 55            DynamicMetaObject[] newArgs = new DynamicMetaObject[args.Length];56            bool[] isByRefArg = new bool[args.Length];57 58            for (int i = 0; i < args.Length; i++)59            {60                DynamicMetaObject curArgument = args[i];61 62                // set new arg infos to their original values or set default ones63                // we will do this fixup early so that we can assume we always have64                // arginfos in COM binder.65                if (IsByRef(curArgument))66                {67                    newArgs[i] = curArgument;68                    isByRefArg[i] = true;69                }70                else71                {72                    if (IsPSReferenceArg(curArgument))73                    {74                        var restrictions = curArgument.Restrictions.Merge(75                            GetTypeRestrictionForDynamicMetaObject(curArgument)76                        );77 78                        // we have restricted this argument to LimitType so we can convert and conversion will be trivial cast.79                        Expression boxedValueAccessor = Expression.Property(80                            Helpers.Convert(81                                curArgument.Expression,82                                curArgument.LimitType83                            ),84                            curArgument.LimitType.GetProperty("Value")85                        );86 87                        PSReference value = curArgument.Value as PSReference;88                        object boxedValue = value?.Value;89 90                        newArgs[i] = new DynamicMetaObject(91                            boxedValueAccessor,92                            restrictions,93                            boxedValue94                        );95 96                        isByRefArg[i] = true;97                    }98                    else99                    {100                        if ((method.ParameterInformation != null) && (i < method.ParameterInformation.Length))101                        {102                            newArgs[i] = new DynamicMetaObject(103                                curArgument.CastOrConvertMethodArgument(104                                    method.ParameterInformation[i].parameterType,105                                    i.ToString(CultureInfo.InvariantCulture),106                                    method.Name,107                                    allowCastingToByRefLikeType: false,108                                    temps,109                                    initTemps),110                                curArgument.Restrictions);111                        }112                        else113                        {114                            newArgs[i] = curArgument;115                        }116 117                        isByRefArg[i] = false;118                    }119                }120            }121 122            args = newArgs;123            return isByRefArg;124        }125 126        internal static BindingRestrictions GetTypeRestrictionForDynamicMetaObject(DynamicMetaObject obj)127        {128            if (obj.Value == null && obj.HasValue)129            {130                //If the meta object holds a null value, create an instance restriction for checking null131                return BindingRestrictions.GetInstanceRestriction(obj.Expression, null);132            }133            return BindingRestrictions.GetTypeRestriction(obj.Expression, obj.LimitType);134        }135    }136}137