// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT license. using System; using System.Reflection; using Microsoft.ClearScript.Util; namespace Microsoft.ClearScript { internal interface IByRefArg { Type Type { get; } object Value { get; set; } } internal interface IOutArg : IByRefArg { } internal interface IRefArg : IByRefArg { } internal abstract class ByRefArg : HostTarget, IByRefArg { private readonly HostVariable target; protected ByRefArg(HostVariable target) { this.target = target; } public T Value { get => target.Value; set => target.Value = value; } #region HostTarget overrides public override Type Type => target.Type; public override object Target => this; public override object InvokeTarget => target.InvokeTarget; public override object DynamicInvokeTarget => target.DynamicInvokeTarget; public override HostTargetFlags GetFlags(IHostInvokeContext context) { return target.GetFlags(context); } public override string[] GetAuxMethodNames(IHostInvokeContext context, BindingFlags bindFlags) { return target.GetAuxMethodNames(context, bindFlags); } public override string[] GetAuxPropertyNames(IHostInvokeContext context, BindingFlags bindFlags) { return target.GetAuxPropertyNames(context, bindFlags); } public override bool TryInvokeAuxMember(IHostInvokeContext context, string name, BindingFlags invokeFlags, object[] args, object[] bindArgs, out object result) { return target.TryInvokeAuxMember(context, name, invokeFlags, args, bindArgs, out result); } public override bool TryInvoke(IHostInvokeContext context, BindingFlags invokeFlags, object[] args, object[] bindArgs, out object result) { return target.TryInvoke(context, invokeFlags, args, bindArgs, out result); } public override Invocability GetInvocability(BindingFlags bindFlags, Type accessContext, ScriptAccess defaultAccess, bool ignoreDynamic) { return target.GetInvocability(bindFlags, accessContext, defaultAccess, ignoreDynamic); } #endregion #region IByRefArg implementation object IByRefArg.Value { get => target.Value; set => ((IHostVariable)target).Value = value; } #endregion } internal sealed class OutArg : ByRefArg, IOutArg { public OutArg(HostVariable target) : base(target) { } public OutArg(T initValue) : this(new HostVariable(initValue)) { } #region Object overrides public override string ToString() { return MiscHelpers.FormatInvariant("out {0}", Type.GetFriendlyName()); } #endregion } internal sealed class RefArg : ByRefArg, IRefArg { public RefArg(HostVariable target) : base(target) { } public RefArg(T initValue) : this(new HostVariable(initValue)) { } #region Object overrides public override string ToString() { return MiscHelpers.FormatInvariant("ref {0}", Type.GetFriendlyName()); } #endregion } }