[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/Global-localhost/ClearScript/master/ClearScript/HostObject.cs [Back]  [Original]

// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.

using System;
using System.Collections;
using System.Reflection;
using System.Runtime.InteropServices.ComTypes;
using Microsoft.ClearScript.Util;

namespace Microsoft.ClearScript
{
    internal sealed class HostObject : HostTarget
    {
        #region data

        private readonly object target;
        private readonly Type type;
        private static readonly MethodInfo getNullWrapperGenericMethod = typeof(HostObject).GetMethod("GetNullWrapperGeneric", BindingFlags.NonPublic | BindingFlags.Static);

        #endregion

        #region constructors

        private HostObject(object target, Type type)
        {
            target = CanonicalRefTable.GetCanonicalRef(target);
            if (type == null)
            {
                type = target.GetType();
            }

            if (type.IsUnknownCOMObject())
            {
                if (target is IEnumVARIANT enumVariant)
                {
                    target = new EnumeratorWrapper(enumVariant);
                    type = typeof(IEnumerator);
                }
            }

            this.target = target;
            this.type = type;
        }

        #endregion

        #region wrappers

        public static HostObject Wrap(object target)
        {
            return Wrap(target, null);
        }

        public static HostObject Wrap(object target, Type type)
        {
            return (target != null) ? new HostObject(target, type) : null;
        }

        public static object WrapResult(object result, Type type, bool wrapNull)
        {
            if ((result is HostItem) || (result is HostTarget))
            {
                return result;
            }

            if (result == null)
            {
                return wrapNull ? GetNullWrapper(type) : null;
            }

            if ((type == typeof(void)) || (type == typeof(object)) || type.IsNullable())
            {
                return result;
            }

            if ((type == result.GetType()) || (Type.GetTypeCode(type) != TypeCode.Object))
            {
                return result;
            }

            return Wrap(result, type);
        }

        #endregion

        #region internal members

        private static HostObject GetNullWrapper(Type type)
        {
            return (HostObject)getNullWrapperGenericMethod.MakeGenericMethod(type).Invoke(null, ArrayHelpers.GetEmptyArray());
        }

        // ReSharper disable UnusedMember.Local

        private static HostObject GetNullWrapperGeneric()
        {
            return NullWrapper.Value;
        }

        // ReSharper restore UnusedMember.Local

        #endregion

        #region Object overrides

        public override string ToString()
        {
            if ((target is ScriptItem) && (typeof(ScriptItem).IsAssignableFrom(type)))
            {
                return "ScriptItem";
            }

            var objectName = target.GetFriendlyName(type);
            return MiscHelpers.FormatInvariant("HostObject:{0}", objectName);
        }

        #endregion

        #region HostTarget overrides

        public override Type Type => type;

        public override object Target => target;

        public override object InvokeTarget => target;

        public override object DynamicInvokeTarget => target;

        public override HostTargetFlags GetFlags(IHostInvokeContext context)
        {
            var flags = HostTargetFlags.AllowInstanceMembers | HostTargetFlags.AllowExtensionMethods;
            if (context.Engine.ExposeHostObjectStaticMembers)
            {
                flags |= HostTargetFlags.AllowStaticMembers;
            }

            return flags;
        }

        public override Invocability GetInvocability(BindingFlags bindFlags, Type accessContext, ScriptAccess defaultAccess, bool ignoreDynamic)
        {
            return type.GetInvocability(bindFlags, accessContext, defaultAccess, ignoreDynamic);
        }

        #endregion

        #region Nested type: NullWrapper

        // ReSharper disable UnusedMember.Local

        private static class NullWrapper
        {
            public static HostObject Value { get; } = new HostObject(null, typeof(T));
        }

        // ReSharper restore UnusedMember.Local

        #endregion
    }
}

Web Proxy Viewer  |  New URL  |  Original Page