Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
CoreAdapter.cs6260 linesDownload Raw Back to engine
1// Copyright (c) Microsoft Corporation.2// Licensed under the MIT License.3 4using System.Collections.Concurrent;5using System.Collections.Generic;6using System.Collections.ObjectModel;7using System.ComponentModel;8using System.Data;9using System.Diagnostics;10using System.Diagnostics.CodeAnalysis;11using System.Dynamic;12using System.Globalization;13using System.Linq;14using System.Linq.Expressions;15using System.Management.Automation.Language;16using System.Management.Automation.Runspaces;17using System.Reflection;18using System.Reflection.Emit;19using System.Text;20using System.Threading;21using System.Xml;22 23using System.Management.Automation.Internal;24using Microsoft.PowerShell;25using Dbg = System.Management.Automation.Diagnostics;26 27#pragma warning disable 1634, 1691 // Stops compiler from warning about unknown warnings28 29namespace System.Management.Automation30{31    /// <summary>32    /// Base class for all Adapters33    /// This is the place to look every time you create a new Adapter. Consider if you34    /// should implement each of the virtual methods here.35    /// The base class deals with errors and performs additional operations before and after36    /// calling the derived virtual methods.37    /// </summary>38    internal abstract class Adapter39    {40        /// <summary>41        /// Tracer for this and derivative classes.42        /// </summary>43        [TraceSource("ETS", "Extended Type System")]44        protected static PSTraceSource tracer = PSTraceSource.GetTracer("ETS", "Extended Type System");45        #region virtual46 47        #region member48 49        internal virtual bool CanSiteBinderOptimize(MemberTypes typeToOperateOn) { return false; }50 51        protected static IEnumerable<string> GetDotNetTypeNameHierarchy(Type type)52        {53            for (; type != null; type = type.BaseType)54            {55                yield return type.FullName;56            }57        }58 59        protected static IEnumerable<string> GetDotNetTypeNameHierarchy(object obj)60        {61            return GetDotNetTypeNameHierarchy(obj.GetType());62        }63 64        /// <summary>65        /// Returns the TypeNameHierarchy out of an object.66        /// </summary>67        /// <param name="obj">Object to get the TypeNameHierarchy from.</param>68        protected virtual IEnumerable<string> GetTypeNameHierarchy(object obj)69        {70            return GetDotNetTypeNameHierarchy(obj);71        }72 73        /// <summary>74        /// Returns the cached typename, if it can be cached, otherwise constructs a new typename.75        /// By default, we don't return interned values, adapters can override if they choose.76        /// </summary>77        /// <param name="obj">Object to get the TypeNameHierarchy from.</param>78        protected virtual ConsolidatedString GetInternedTypeNameHierarchy(object obj)79        {80            return new ConsolidatedString(GetTypeNameHierarchy(obj));81        }82 83        /// <summary>84        /// Returns null if memberName is not a member in the adapter or85        /// the corresponding PSMemberInfo.86        /// </summary>87        /// <param name="obj">Object to retrieve the PSMemberInfo from.</param>88        /// <param name="memberName">Name of the member to be retrieved.</param>89        /// <returns>The PSMemberInfo corresponding to memberName from obj.</returns>90        protected abstract T GetMember<T>(object obj, string memberName) where T : PSMemberInfo;91 92        /// <summary>93        /// Returns the first PSMemberInfo whose name matches the specified <see cref="MemberNamePredicate"/>.94        /// Otherwise, return null.95        /// </summary>96        /// <param name="obj">Object to retrieve the PSMemberInfo from.</param>97        /// <param name="predicate">The predicate to find the matching member.</param>98        /// <returns>The PSMemberInfo corresponding to the predicate match.</returns>99        protected abstract T GetFirstMemberOrDefault<T>(object obj, MemberNamePredicate predicate) where T : PSMemberInfo;100 101        /// <summary>102        /// Retrieves all the members available in the object.103        /// The adapter implementation is encouraged to cache all properties/methods available104        /// in the first call to GetMember and GetMembers so that subsequent105        /// calls can use the cache.106        /// In the case of the .NET adapter that would be a cache from the .NET type to107        /// the public properties and fields available in that type.108        /// In the case of the DirectoryEntry adapter, this could be a cache of the objectClass109        /// to the properties available in it.110        /// </summary>111        /// <param name="obj">Object to get all the member information from.</param>112        /// <returns>All members in obj.</returns>113        protected abstract PSMemberInfoInternalCollection<T> GetMembers<T>(object obj) where T : PSMemberInfo;114 115        #endregion member116 117        #region property118 119        /// <summary>120        /// Returns the value from a property coming from a previous call to GetMember.121        /// </summary>122        /// <param name="property">PSProperty coming from a previous call to GetMember.</param>123        /// <returns>The value of the property.</returns>124        protected abstract object PropertyGet(PSProperty property);125 126        /// <summary>127        /// Sets the value of a property coming from a previous call to GetMember.128        /// </summary>129        /// <param name="property">PSProperty coming from a previous call to GetMember.</param>130        /// <param name="setValue">Value to set the property with.</param>131        /// <param name="convertIfPossible">Instructs the adapter to convert before setting, if the adapter supports conversion.</param>132        protected abstract void PropertySet(PSProperty property, object setValue, bool convertIfPossible);133 134        /// <summary>135        /// Returns true if the property is settable.136        /// </summary>137        /// <param name="property">Property to check.</param>138        /// <returns>True if the property is settable.</returns>139        protected abstract bool PropertyIsSettable(PSProperty property);140 141        /// <summary>142        /// Returns true if the property is gettable.143        /// </summary>144        /// <param name="property">Property to check.</param>145        /// <returns>True if the property is gettable.</returns>146        protected abstract bool PropertyIsGettable(PSProperty property);147 148        /// <summary>149        /// Returns the name of the type corresponding to the property's value.150        /// </summary>151        /// <param name="property">PSProperty obtained in a previous GetMember.</param>152        /// <param name="forDisplay">True if the result is for display purposes only.</param>153        /// <returns>The name of the type corresponding to the member.</returns>154        protected abstract string PropertyType(PSProperty property, bool forDisplay);155 156        /// <summary>157        /// Returns the string representation of the property in the object.158        /// </summary>159        /// <param name="property">Property obtained in a previous GetMember.</param>160        /// <returns>The string representation of the property in the object.</returns>161        protected abstract string PropertyToString(PSProperty property);162 163        /// <summary>164        /// Returns an array with the property attributes.165        /// </summary>166        /// <param name="property">Property we want the attributes from.</param>167        /// <returns>An array with the property attributes.</returns>168        protected abstract AttributeCollection PropertyAttributes(PSProperty property);169 170        #endregion property171 172        #region method173 174        /// <summary>175        /// Called after a non null return from GetMember to try to call176        /// the method with the arguments.177        /// </summary>178        /// <param name="method">The non empty return from GetMethods.</param>179        /// <param name="invocationConstraints">Invocation constraints.</param>180        /// <param name="arguments">The arguments to use.</param>181        /// <returns>The return value for the method.</returns>182        protected virtual object MethodInvoke(PSMethod method, PSMethodInvocationConstraints invocationConstraints, object[] arguments)183        {184            return this.MethodInvoke(method, arguments);185        }186 187        /// <summary>188        /// Called after a non null return from GetMember to try to call189        /// the method with the arguments.190        /// </summary>191        /// <param name="method">The non empty return from GetMethods.</param>192        /// <param name="arguments">The arguments to use.</param>193        /// <returns>The return value for the method.</returns>194        protected abstract object MethodInvoke(PSMethod method, object[] arguments);195 196        /// <summary>197        /// Called after a non null return from GetMember to return the overloads.198        /// </summary>199        /// <param name="method">The return of GetMember.</param>200        /// <returns></returns>201        protected abstract Collection<string> MethodDefinitions(PSMethod method);202 203        /// <summary>204        /// Returns the string representation of the method in the object.205        /// </summary>206        /// <returns>The string representation of the method in the object.</returns>207        protected virtual string MethodToString(PSMethod method)208        {209            StringBuilder returnValue = new StringBuilder();210            Collection<string> definitions = MethodDefinitions(method);211            for (int i = 0; i < definitions.Count; i++)212            {213                returnValue.Append(definitions[i]);214                returnValue.Append(", ");215            }216 217            returnValue.Remove(returnValue.Length - 2, 2);218            return returnValue.ToString();219        }220 221        #endregion method222 223        #region parameterized property224 225        /// <summary>226        /// Returns the name of the type corresponding to the property's value.227        /// </summary>228        /// <param name="property">Property obtained in a previous GetMember.</param>229        /// <returns>The name of the type corresponding to the member.</returns>230        /// <remarks>231        /// It is not necessary for derived methods to override this.232        /// This method is called only if ParameterizedProperties are present.233        /// </remarks>234        protected virtual string ParameterizedPropertyType(PSParameterizedProperty property)235        {236            Diagnostics.Assert(false, "adapter is not called for parameterized properties");237            throw PSTraceSource.NewNotSupportedException();238        }239 240        /// <summary>241        /// Returns true if the property is settable.242        /// </summary>243        /// <param name="property">Property to check.</param>244        /// <returns>True if the property is settable.</returns>245        /// <remarks>246        /// It is not necessary for derived methods to override this.247        /// This method is called only if ParameterizedProperties are present.248        /// </remarks>249        protected virtual bool ParameterizedPropertyIsSettable(PSParameterizedProperty property)250        {251            Diagnostics.Assert(false, "adapter is not called for parameterized properties");252            throw PSTraceSource.NewNotSupportedException();253        }254 255        /// <summary>256        /// Returns true if the property is gettable.257        /// </summary>258        /// <param name="property">Property to check.</param>259        /// <returns>True if the property is gettable.</returns>260        /// <remarks>261        /// It is not necessary for derived methods to override this.262        /// This method is called only if ParameterizedProperties are present.263        /// </remarks>264        protected virtual bool ParameterizedPropertyIsGettable(PSParameterizedProperty property)265        {266            Diagnostics.Assert(false, "adapter is not called for parameterized properties");267            throw PSTraceSource.NewNotSupportedException();268        }269 270        /// <summary>271        /// Called after a non null return from GetMember to return the overloads.272        /// </summary>273        /// <param name="property">The return of GetMember.</param>274        /// <remarks>275        /// It is not necessary for derived methods to override this.276        /// This method is called only if ParameterizedProperties are present.277        /// </remarks>278        protected virtual Collection<string> ParameterizedPropertyDefinitions(PSParameterizedProperty property)279        {280            Diagnostics.Assert(false, "adapter is not called for parameterized properties");281            throw PSTraceSource.NewNotSupportedException();282        }283 284        /// <summary>285        /// Called after a non null return from GetMember to get the property value.286        /// </summary>287        /// <param name="property">The non empty return from GetMember.</param>288        /// <param name="arguments">The arguments to use.</param>289        /// <returns>The return value for the property.</returns>290        /// <remarks>291        /// It is not necessary for derived methods to override this.292        /// This method is called only if ParameterizedProperties are present.293        /// </remarks>294        protected virtual object ParameterizedPropertyGet(PSParameterizedProperty property, object[] arguments)295        {296            Diagnostics.Assert(false, "adapter is not called for parameterized properties");297            throw PSTraceSource.NewNotSupportedException();298        }299 300        /// <summary>301        /// Called after a non null return from GetMember to set the property value.302        /// </summary>303        /// <param name="property">The non empty return from GetMember.</param>304        /// <param name="setValue">The value to set property with.</param>305        /// <param name="arguments">The arguments to use.</param>306        /// <remarks>307        /// It is not necessary for derived methods to override this.308        /// This method is called only if ParameterizedProperties are present.309        /// </remarks>310        protected virtual void ParameterizedPropertySet(PSParameterizedProperty property, object setValue, object[] arguments)311        {312            Diagnostics.Assert(false, "adapter is not called for parameterized properties");313            throw PSTraceSource.NewNotSupportedException();314        }315 316        /// <summary>317        /// Returns the string representation of the property in the object.318        /// </summary>319        /// <param name="property">Property obtained in a previous GetMember.</param>320        /// <returns>The string representation of the property in the object.</returns>321        /// <remarks>322        /// It is not necessary for derived methods to override this.323        /// This method is called only if ParameterizedProperties are present.324        /// </remarks>325        protected virtual string ParameterizedPropertyToString(PSParameterizedProperty property)326        {327            Diagnostics.Assert(false, "adapter is not called for parameterized properties");328            throw PSTraceSource.NewNotSupportedException();329        }330 331        #endregion parameterized property332 333        #endregion virtual334 335        #region base336 337        #region private338 339        private static Exception NewException(340            Exception e,341            string errorId,342            string targetErrorId,343            string resourceString,344            params object[] parameters)345        {346            object[] newParameters = new object[parameters.Length + 1];347            for (int i = 0; i < parameters.Length; i++)348            {349                newParameters[i + 1] = parameters[i];350            }351 352            Exception ex = e as TargetInvocationException;353            if (ex != null)354            {355                Exception inner = ex.InnerException ?? ex;356                newParameters[0] = inner.Message;357                return new ExtendedTypeSystemException(358                    targetErrorId,359                    inner,360                    resourceString,361                    newParameters);362            }363 364            newParameters[0] = e.Message;365            return new ExtendedTypeSystemException(366                errorId,367                e,368                resourceString,369                newParameters);370        }371 372        #endregion private373 374        #region member375 376        internal ConsolidatedString BaseGetTypeNameHierarchy(object obj)377        {378            try379            {380                return GetInternedTypeNameHierarchy(obj);381            }382            catch (ExtendedTypeSystemException) { throw; }383            catch (Exception e)384            {385                throw NewException(386                    e,387                    "CatchFromBaseGetTypeNameHierarchy",388                    "CatchFromBaseGetTypeNameHierarchyTI",389                    ExtendedTypeSystem.ExceptionRetrievingTypeNameHierarchy);390            }391        }392 393        internal T BaseGetMember<T>(object obj, string memberName) where T : PSMemberInfo394        {395            try396            {397                return this.GetMember<T>(obj, memberName);398            }399            catch (ExtendedTypeSystemException) { throw; }400            catch (Exception e)401            {402                throw NewException(403                    e,404                    "CatchFromBaseGetMember",405                    "CatchFromBaseGetMemberTI",406                    ExtendedTypeSystem.ExceptionGettingMember,407                    memberName);408            }409        }410 411        internal T BaseGetFirstMemberOrDefault<T>(object obj, MemberNamePredicate predicate) where T : PSMemberInfo412        {413            try414            {415                return this.GetFirstMemberOrDefault<T>(obj, predicate);416            }417            catch (ExtendedTypeSystemException) { throw; }418            catch (Exception e)419            {420                throw NewException(421                    e,422                    "CatchFromBaseGetMember",423                    "CatchFromBaseGetMemberTI",424                    ExtendedTypeSystem.ExceptionGettingMember,425                    nameof(predicate));426            }427        }428 429        internal PSMemberInfoInternalCollection<T> BaseGetMembers<T>(object obj) where T : PSMemberInfo430        {431            try432            {433                return this.GetMembers<T>(obj);434            }435            catch (ExtendedTypeSystemException) { throw; }436            catch (Exception e)437            {438                throw NewException(439                    e,440                    "CatchFromBaseGetMembers",441                    "CatchFromBaseGetMembersTI",442                    ExtendedTypeSystem.ExceptionGettingMembers);443            }444        }445 446        #endregion member447 448        #region property449 450        internal object BasePropertyGet(PSProperty property)451        {452            try453            {454                return PropertyGet(property);455            }456            catch (TargetInvocationException ex)457            {458                Exception inner = ex.InnerException ?? ex;459                throw new GetValueInvocationException(460                    "CatchFromBaseAdapterGetValueTI",461                    inner,462                    ExtendedTypeSystem.ExceptionWhenGetting,463                    property.Name, inner.Message);464            }465            catch (GetValueException) { throw; }466            catch (Exception e)467            {468                throw new GetValueInvocationException(469                    "CatchFromBaseAdapterGetValue",470                    e,471                    ExtendedTypeSystem.ExceptionWhenGetting,472                    property.Name, e.Message);473            }474        }475 476        internal void BasePropertySet(PSProperty property, object setValue, bool convert)477        {478            try479            {480                PropertySet(property, setValue, convert);481            }482            catch (TargetInvocationException ex)483            {484                Exception inner = ex.InnerException ?? ex;485                throw new SetValueInvocationException(486                    "CatchFromBaseAdapterSetValueTI",487                    inner,488                    ExtendedTypeSystem.ExceptionWhenSetting,489                    property.Name, inner.Message);490            }491            catch (SetValueException) { throw; }492            catch (Exception e)493            {494                throw new SetValueInvocationException(495                    "CatchFromBaseAdapterSetValue",496                    e,497                    ExtendedTypeSystem.ExceptionWhenSetting,498                    property.Name, e.Message);499            }500        }501 502        internal bool BasePropertyIsSettable(PSProperty property)503        {504            try505            {506                return this.PropertyIsSettable(property);507            }508            catch (ExtendedTypeSystemException) { throw; }509            catch (Exception e)510            {511                throw NewException(512                    e,513                    "CatchFromBasePropertyIsSettable",514                    "CatchFromBasePropertyIsSettableTI",515                    ExtendedTypeSystem.ExceptionRetrievingPropertyWriteState,516                    property.Name);517            }518        }519 520        internal bool BasePropertyIsGettable(PSProperty property)521        {522            try523            {524                return this.PropertyIsGettable(property);525            }526            catch (ExtendedTypeSystemException) { throw; }527            catch (Exception e)528            {529                throw NewException(530                    e,531                    "CatchFromBasePropertyIsGettable",532                    "CatchFromBasePropertyIsGettableTI",533                    ExtendedTypeSystem.ExceptionRetrievingPropertyReadState,534                    property.Name);535            }536        }537 538        internal string BasePropertyType(PSProperty property)539        {540            try541            {542                return this.PropertyType(property, forDisplay: false);543            }544            catch (ExtendedTypeSystemException) { throw; }545            catch (Exception e)546            {547                throw NewException(548                    e,549                    "CatchFromBasePropertyType",550                    "CatchFromBasePropertyTypeTI",551                    ExtendedTypeSystem.ExceptionRetrievingPropertyType,552                    property.Name);553            }554        }555 556        internal string BasePropertyToString(PSProperty property)557        {558            try559            {560                return this.PropertyToString(property);561            }562            catch (ExtendedTypeSystemException) { throw; }563            catch (Exception e)564            {565                throw NewException(566                    e,567                    "CatchFromBasePropertyToString",568                    "CatchFromBasePropertyToStringTI",569                    ExtendedTypeSystem.ExceptionRetrievingPropertyString,570                    property.Name);571            }572        }573 574        internal AttributeCollection BasePropertyAttributes(PSProperty property)575        {576            try577            {578                return this.PropertyAttributes(property);579            }580            catch (ExtendedTypeSystemException) { throw; }581            catch (Exception e)582            {583                throw NewException(584                    e,585                    "CatchFromBasePropertyAttributes",586                    "CatchFromBasePropertyAttributesTI",587                    ExtendedTypeSystem.ExceptionRetrievingPropertyAttributes,588                    property.Name);589            }590        }591 592        #endregion property593 594        #region method595        internal object BaseMethodInvoke(PSMethod method, PSMethodInvocationConstraints invocationConstraints, params object[] arguments)596        {597            try598            {599                return this.MethodInvoke(method, invocationConstraints, arguments);600            }601            catch (TargetInvocationException ex)602            {603                Exception inner = ex.InnerException ?? ex;604                throw new MethodInvocationException(605                    "CatchFromBaseAdapterMethodInvokeTI",606                    inner,607                    ExtendedTypeSystem.MethodInvocationException,608                    method.Name,609                    arguments.Length,610                    inner.Message);611            }612            catch (FlowControlException) { throw; }613            catch (ScriptCallDepthException) { throw; }614            catch (PipelineStoppedException) { throw; }615            catch (MethodException) { throw; }616            catch (Exception e)617            {618                if (method.baseObject is SteppablePipeline619                    && (method.Name.Equals("Begin", StringComparison.OrdinalIgnoreCase) ||620                        method.Name.Equals("Process", StringComparison.OrdinalIgnoreCase) ||621                        method.Name.Equals("End", StringComparison.OrdinalIgnoreCase)))622                {623                    throw;624                }625 626                throw new MethodInvocationException(627                    "CatchFromBaseAdapterMethodInvoke",628                    e,629                    ExtendedTypeSystem.MethodInvocationException,630                    method.Name,631                    arguments.Length,632                    e.Message);633            }634        }635 636        internal Collection<string> BaseMethodDefinitions(PSMethod method)637        {638            try639            {640                return this.MethodDefinitions(method);641            }642            catch (ExtendedTypeSystemException) { throw; }643            catch (Exception e)644            {645                throw NewException(646                    e,647                    "CatchFromBaseMethodDefinitions",648                    "CatchFromBaseMethodDefinitionsTI",649                    ExtendedTypeSystem.ExceptionRetrievingMethodDefinitions,650                    method.Name);651            }652        }653 654        internal string BaseMethodToString(PSMethod method)655        {656            try657            {658                return this.MethodToString(method);659            }660            catch (ExtendedTypeSystemException) { throw; }661            catch (Exception e)662            {663                throw NewException(664                    e,665                    "CatchFromBaseMethodToString",666                    "CatchFromBaseMethodToStringTI",667                    ExtendedTypeSystem.ExceptionRetrievingMethodString,668                    method.Name);669            }670        }671        #endregion method672 673        #region parameterized property674        internal string BaseParameterizedPropertyType(PSParameterizedProperty property)675        {676            try677            {678                return this.ParameterizedPropertyType(property);679            }680            catch (ExtendedTypeSystemException) { throw; }681            catch (Exception e)682            {683                throw NewException(684                    e,685                    "CatchFromBaseParameterizedPropertyType",686                    "CatchFromBaseParameterizedPropertyTypeTI",687                    ExtendedTypeSystem.ExceptionRetrievingParameterizedPropertytype,688                    property.Name);689            }690        }691 692        internal bool BaseParameterizedPropertyIsSettable(PSParameterizedProperty property)693        {694            try695            {696                return this.ParameterizedPropertyIsSettable(property);697            }698            catch (ExtendedTypeSystemException) { throw; }699            catch (Exception e)700            {701                throw NewException(702                    e,703                    "CatchFromBaseParameterizedPropertyIsSettable",704                    "CatchFromBaseParameterizedPropertyIsSettableTI",705                    ExtendedTypeSystem.ExceptionRetrievingParameterizedPropertyWriteState,706                    property.Name);707            }708        }709 710        internal bool BaseParameterizedPropertyIsGettable(PSParameterizedProperty property)711        {712            try713            {714                return this.ParameterizedPropertyIsGettable(property);715            }716            catch (ExtendedTypeSystemException) { throw; }717            catch (Exception e)718            {719                throw NewException(720                    e,721                    "CatchFromBaseParameterizedPropertyIsGettable",722                    "CatchFromBaseParameterizedPropertyIsGettableTI",723                    ExtendedTypeSystem.ExceptionRetrievingParameterizedPropertyReadState,724                    property.Name);725            }726        }727 728        internal Collection<string> BaseParameterizedPropertyDefinitions(PSParameterizedProperty property)729        {730            try731            {732                return this.ParameterizedPropertyDefinitions(property);733            }734            catch (ExtendedTypeSystemException) { throw; }735            catch (Exception e)736            {737                throw NewException(738                    e,739                    "CatchFromBaseParameterizedPropertyDefinitions",740                    "CatchFromBaseParameterizedPropertyDefinitionsTI",741                    ExtendedTypeSystem.ExceptionRetrievingParameterizedPropertyDefinitions,742                    property.Name);743            }744        }745 746        internal object BaseParameterizedPropertyGet(PSParameterizedProperty property, params object[] arguments)747        {748            try749            {750                return this.ParameterizedPropertyGet(property, arguments);751            }752            catch (TargetInvocationException ex)753            {754                Exception inner = ex.InnerException ?? ex;755                throw new GetValueInvocationException(756                    "CatchFromBaseAdapterParameterizedPropertyGetValueTI",757                    inner,758                    ExtendedTypeSystem.ExceptionWhenGetting,759                    property.Name,760                    inner.Message);761            }762            catch (GetValueException) { throw; }763            catch (Exception e)764            {765                throw new GetValueInvocationException(766                    "CatchFromBaseParameterizedPropertyAdapterGetValue",767                    e,768                    ExtendedTypeSystem.ExceptionWhenGetting,769                    property.Name,770                    e.Message);771            }772        }773 774        internal void BaseParameterizedPropertySet(PSParameterizedProperty property, object setValue, params object[] arguments)775        {776            try777            {778                this.ParameterizedPropertySet(property, setValue, arguments);779            }780            catch (TargetInvocationException ex)781            {782                Exception inner = ex.InnerException ?? ex;783                throw new SetValueInvocationException(784                    "CatchFromBaseAdapterParameterizedPropertySetValueTI",785                    inner,786                    ExtendedTypeSystem.ExceptionWhenSetting,787                    property.Name,788                    inner.Message);789            }790            catch (SetValueException) { throw; }791            catch (Exception e)792            {793                throw new SetValueInvocationException(794                    "CatchFromBaseAdapterParameterizedPropertySetValue",795                    e,796                    ExtendedTypeSystem.ExceptionWhenSetting,797                    property.Name,798                    e.Message);799            }800        }801 802        internal string BaseParameterizedPropertyToString(PSParameterizedProperty property)803        {804            try805            {806                return this.ParameterizedPropertyToString(property);807            }808            catch (ExtendedTypeSystemException) { throw; }809            catch (Exception e)810            {811                throw NewException(812                    e,813                    "CatchFromBaseParameterizedPropertyToString",814                    "CatchFromBaseParameterizedPropertyToStringTI",815                    ExtendedTypeSystem.ExceptionRetrievingParameterizedPropertyString,816                    property.Name);817            }818        }819 820        #endregion parameterized property821 822        #region Internal Helper Methods823 824        private static Type GetArgumentType(object argument, bool isByRefParameter)825        {826            if (argument == null)827            {828                return typeof(LanguagePrimitives.Null);829            }830 831            if (isByRefParameter && argument is PSReference psref)832            {833                return GetArgumentType(PSObject.Base(psref.Value), isByRefParameter: false);834            }835 836            return GetObjectType(argument, debase: false);837        }838 839        internal static ConversionRank GetArgumentConversionRank(object argument, Type parameterType, bool isByRef, bool allowCastingToByRefLikeType)840        {841            Type fromType = null;842            ConversionRank rank = ConversionRank.None;843 844            if (allowCastingToByRefLikeType && parameterType.IsByRefLike)845            {846                // When resolving best method for use in binders, we can accept implicit/explicit casting conversions to847                // a ByRef-like target type, because when generating IL from a call site with the binder, the IL includes848                // the casting operation. However, we don't accept such conversions when it's for invoking the method via849                // reflection, because reflection just doesn't support ByRef-like type.850                fromType = GetArgumentType(PSObject.Base(argument), isByRefParameter: false);851                if (fromType != typeof(LanguagePrimitives.Null))852                {853                    LanguagePrimitives.FigureCastConversion(fromType, parameterType, ref rank);854                }855 856                return rank;857            }858 859            fromType = GetArgumentType(argument, isByRef);860            rank = LanguagePrimitives.GetConversionRank(fromType, parameterType);861 862            if (rank == ConversionRank.None)863            {864                fromType = GetArgumentType(PSObject.Base(argument), isByRef);865                rank = LanguagePrimitives.GetConversionRank(fromType, parameterType);866            }867 868            return rank;869        }870 871        private static ParameterInformation[] ExpandParameters(int argCount, ParameterInformation[] parameters, Type elementType)872        {873            Diagnostics.Assert(parameters[parameters.Length - 1].isParamArray, "ExpandParameters shouldn't be called on non-param method");874 875            ParameterInformation[] newParameters = new ParameterInformation[argCount];876            Array.Copy(parameters, newParameters, parameters.Length - 1);877            for (int i = parameters.Length - 1; i < argCount; ++i)878            {879                newParameters[i] = new ParameterInformation(elementType, false, null, false);880            }881 882            return newParameters;883        }884 885        /// <summary>886        /// Compare the 2 methods, determining which method is better.887        /// </summary>888        /// <returns>1 if method1 is better, -1 if method2 is better, 0 otherwise.</returns>889        private static int CompareOverloadCandidates(OverloadCandidate candidate1, OverloadCandidate candidate2, object[] arguments)890        {891            Diagnostics.Assert(candidate1.conversionRanks.Length == candidate2.conversionRanks.Length,892                               "should have same number of conversions regardless of the number of parameters - default arguments are not included here");893 894            ParameterInformation[] params1 = candidate1.expandedParameters ?? candidate1.parameters;895            ParameterInformation[] params2 = candidate2.expandedParameters ?? candidate2.parameters;896 897            int betterCount = 0;898            int multiplier = candidate1.conversionRanks.Length;899            for (int i = 0; i < candidate1.conversionRanks.Length; ++i, --multiplier)900            {901                if (candidate1.conversionRanks[i] < candidate2.conversionRanks[i])902                {903                    betterCount -= multiplier;904                }905                else if (candidate1.conversionRanks[i] > candidate2.conversionRanks[i])906                {907                    betterCount += multiplier;908                }909                else if (candidate1.conversionRanks[i] == ConversionRank.UnrelatedArrays)910                {911                    // If both are unrelated arrays, then use the element type conversions instead.912                    Type argElemType = EffectiveArgumentType(arguments[i]).GetElementType();913                    ConversionRank rank1 = LanguagePrimitives.GetConversionRank(argElemType, params1[i].parameterType.GetElementType());914                    ConversionRank rank2 = LanguagePrimitives.GetConversionRank(argElemType, params2[i].parameterType.GetElementType());915                    if (rank1 < rank2)916                    {917                        betterCount -= multiplier;918                    }919                    else if (rank1 > rank2)920                    {921                        betterCount += multiplier;922                    }923                }924            }925 926            if (betterCount == 0)927            {928                multiplier = candidate1.conversionRanks.Length;929                for (int i = 0; i < candidate1.conversionRanks.Length; ++i, multiplier = Math.Abs(multiplier) - 1)930                {931                    // The following rather tricky logic tries to pick the best method in 2 very different cases -932                    //   - Pick the most specific method when conversions aren't losing information933                    //   - Pick the most general method when conversions will lose information.934                    // Consider:935                    //    f(uint32), f(decimal), call with f([byte]$i)936                    //        in this case, we want to call f(uint32) because it is more specific937                    //        while not losing information938                    //    f(byte), f(int16), call with f([int]$i)939                    //        in this case, we want to call f(int16) because it is more general,940                    //        we know we could lose information with either call, but we will lose941                    //        less information calling f(int16).942                    ConversionRank rank1 = candidate1.conversionRanks[i];943                    ConversionRank rank2 = candidate2.conversionRanks[i];944                    if (rank1 < ConversionRank.NullToValue || rank2 < ConversionRank.NullToValue)945                    {946                        // The tie breaking rules here do not apply to conversions that are not947                        // numeric or inheritance related.948                        continue;949                    }950 951                    if ((rank1 >= ConversionRank.NumericImplicit) != (rank2 >= ConversionRank.NumericImplicit))952                    {953                        // Skip trying to break ties when argument conversions are not both implicit or both954                        // explicit.  If we have that situation, there are multiple arguments and an955                        // ambiguity is probably the best choice.956                        continue;957                    }958 959                    // We will now compare the parameter types, ignoring the actual argument type.  To choose960                    // the right method, we need to know if we want the "most specific" or the "most general".961                    // If we have implicit argument conversions, we'll want the most specific, so invert the multiplier.962                    if (rank1 >= ConversionRank.NumericImplicit)963                    {964                        multiplier = -multiplier;965                    }966 967                    // With a positive multiplier, we'll choose the "most general" type, and a negative968                    // multiplier will choose the "most specific".969                    rank1 = LanguagePrimitives.GetConversionRank(params1[i].parameterType, params2[i].parameterType);970                    rank2 = LanguagePrimitives.GetConversionRank(params2[i].parameterType, params1[i].parameterType);971                    if (rank1 < rank2)972                    {973                        betterCount += multiplier;974                    }975                    else if (rank1 > rank2)976                    {977                        betterCount -= multiplier;978                    }979                }980            }981 982            if (betterCount == 0)983            {984                // Check if parameters are the same.  If so, we have a few tiebreakering rules down below.985                for (int i = 0; i < candidate1.conversionRanks.Length; ++i)986                {987                    if (params1[i].parameterType != params2[i].parameterType)988                    {989                        return 0;990                    }991                }992 993                // Apply tie breaking rules, related to expanded parameters994                if (candidate1.expandedParameters != null && candidate2.expandedParameters != null)995                {996                    // Both are using expanded parameters.  The one with more parameters is better997                    return (candidate1.parameters.Length > candidate2.parameters.Length) ? 1 : -1;998                }999                else if (candidate1.expandedParameters != null)1000                {1001                    return -1;1002                }1003                else if (candidate2.expandedParameters != null)1004                {1005                    return 1;1006                }1007 1008                // Apply tie breaking rules, related to specificity of parameters1009                betterCount = CompareTypeSpecificity(candidate1, candidate2);1010            }1011 1012            // The methods with fewer parameter wins1013            // Need to revisit this if we support named arguments1014            if (betterCount == 0)1015            {1016                if (candidate1.parameters.Length < candidate2.parameters.Length)1017                {1018                    return 1;1019                }1020                else if (candidate1.parameters.Length > candidate2.parameters.Length)1021                {1022                    return -1;1023                }1024            }1025 1026            return betterCount;1027        }1028 1029        private static OverloadCandidate FindBestCandidate(List<OverloadCandidate> candidates, object[] arguments)1030        {1031            Dbg.Assert(candidates != null, "Caller should verify candidates != null");1032 1033            OverloadCandidate bestCandidateSoFar = null;1034            bool multipleBestCandidates = false;1035 1036            for (int i = 0; i < candidates.Count; i++)1037            {1038                OverloadCandidate currentCandidate = candidates[i];1039                if (bestCandidateSoFar == null) // first iteration1040                {1041                    bestCandidateSoFar = currentCandidate;1042                    continue;1043                }1044 1045                int comparisonResult = CompareOverloadCandidates(bestCandidateSoFar, currentCandidate, arguments);1046                if (comparisonResult == 0)1047                {1048                    multipleBestCandidates = true;1049                }1050                else if (comparisonResult < 0)1051                {1052                    bestCandidateSoFar = currentCandidate;1053                    multipleBestCandidates = false;1054                }1055            }1056 1057            Dbg.Assert(1058                !candidates.Any(otherCandidate => otherCandidate != bestCandidateSoFar && CompareOverloadCandidates(otherCandidate, bestCandidateSoFar, arguments) > 0),1059                "No other candidates are better than bestCandidateSoFar");1060 1061            return multipleBestCandidates ? null : bestCandidateSoFar;1062        }1063 1064        private static OverloadCandidate FindBestCandidate(List<OverloadCandidate> candidates, object[] arguments, PSMethodInvocationConstraints invocationConstraints)1065        {1066            List<OverloadCandidate> filteredCandidates = candidates.Where(candidate => IsInvocationConstraintSatisfied(candidate, invocationConstraints)).ToList();1067            if (filteredCandidates.Count > 0)1068            {1069                candidates = filteredCandidates;1070            }1071 1072            OverloadCandidate bestCandidate = FindBestCandidate(candidates, arguments);1073            return bestCandidate;1074        }1075 1076        private static int CompareTypeSpecificity(Type type1, Type type2)1077        {1078            if (type1.IsGenericParameter || type2.IsGenericParameter)1079            {1080                int result = 0;1081                if (type1.IsGenericParameter)1082                {1083                    result -= 1;1084                }1085 1086                if (type2.IsGenericParameter)1087                {1088                    result += 1;1089                }1090 1091                return result;1092            }1093 1094            if (type1.IsArray)1095            {1096                Dbg.Assert(type2.IsArray, "Caller should verify that both overload candidates have the same parameter types");1097                Dbg.Assert(type1.GetArrayRank() == type2.GetArrayRank(), "Caller should verify that both overload candidates have the same parameter types");1098                return CompareTypeSpecificity(type1.GetElementType(), type2.GetElementType());1099            }1100 1101            if (type1.IsGenericType)1102            {1103                Dbg.Assert(type2.IsGenericType, "Caller should verify that both overload candidates have the same parameter types");1104                Dbg.Assert(type1.GetGenericTypeDefinition() == type2.GetGenericTypeDefinition(), "Caller should verify that both overload candidates have the same parameter types");1105                return CompareTypeSpecificity(type1.GetGenericArguments(), type2.GetGenericArguments());1106            }1107 1108            return 0;1109        }1110 1111        private static int CompareTypeSpecificity(Type[] params1, Type[] params2)1112        {1113            Dbg.Assert(params1.Length == params2.Length, "Caller should verify that both overload candidates have the same number of parameters");1114 1115            bool candidate1hasAtLeastOneMoreSpecificParameter = false;1116            bool candidate2hasAtLeastOneMoreSpecificParameter = false;1117            for (int i = 0; i < params1.Length; ++i)1118            {1119                int specificityComparison = CompareTypeSpecificity(params1[i], params2[i]);1120                if (specificityComparison > 0)1121                {1122                    candidate1hasAtLeastOneMoreSpecificParameter = true;1123                }1124                else if (specificityComparison < 0)1125                {1126                    candidate2hasAtLeastOneMoreSpecificParameter = true;1127                }1128 1129                if (candidate1hasAtLeastOneMoreSpecificParameter && candidate2hasAtLeastOneMoreSpecificParameter)1130                {1131                    break;1132                }1133            }1134 1135            if (candidate1hasAtLeastOneMoreSpecificParameter && !candidate2hasAtLeastOneMoreSpecificParameter)1136            {1137                return 1;1138            }1139            else if (candidate2hasAtLeastOneMoreSpecificParameter && !candidate1hasAtLeastOneMoreSpecificParameter)1140            {1141                return -1;1142            }1143            else1144            {1145                return 0;1146            }1147        }1148 1149        /// <summary>1150        /// Returns -1 if <paramref name="candidate1"/> is less specific than <paramref name="candidate2"/>1151        /// (1 otherwise, or 0 if both are equally specific or non-comparable)1152        /// </summary>1153        private static int CompareTypeSpecificity(OverloadCandidate candidate1, OverloadCandidate candidate2)1154        {1155            if (!(candidate1.method.isGeneric || candidate2.method.isGeneric))1156            {1157                return 0;1158            }1159 1160            Type[] params1 = GetGenericMethodDefinitionIfPossible(candidate1.method.method).GetParameters().Select(static p => p.ParameterType).ToArray();1161            Type[] params2 = GetGenericMethodDefinitionIfPossible(candidate2.method.method).GetParameters().Select(static p => p.ParameterType).ToArray();1162            return CompareTypeSpecificity(params1, params2);1163        }1164 1165        private static MethodBase GetGenericMethodDefinitionIfPossible(MethodBase method)1166        {1167            if (method.IsGenericMethod && !method.IsGenericMethodDefinition)1168            {1169                MethodInfo methodInfo = method as MethodInfo;1170                if (methodInfo != null)1171                {1172                    return methodInfo.GetGenericMethodDefinition();1173                }1174            }1175 1176            return method;1177        }1178 1179        [DebuggerDisplay("OverloadCandidate: {method.methodDefinition}")]1180        private sealed class OverloadCandidate1181        {1182            internal MethodInformation method;1183            internal ParameterInformation[] parameters;1184            internal ParameterInformation[] expandedParameters;1185            internal ConversionRank[] conversionRanks;1186 1187            internal OverloadCandidate(MethodInformation method, int argCount)1188            {1189                this.method = method;1190                this.parameters = method.parameters;1191                conversionRanks = new ConversionRank[argCount];1192            }1193        }1194 1195        private static bool IsInvocationTargetConstraintSatisfied(MethodInformation method, PSMethodInvocationConstraints invocationConstraints)1196        {1197            Dbg.Assert(method != null, "Caller should verify method != null");1198 1199            if (method.method == null)1200            {

Showing the first 1,200 of 6260 lines. Download the file for the rest.