MegaBites-AI/Windows-powershell
0372
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 