<commit_before>#if LESSTHAN_NET35

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Dynamic.Utils;
using System.Linq.Expressions;
using Theraot.Collections.ThreadSafe;

namespace System.Dynamic
{
    /// <summary>
    /// Represents the dynamic binding and a binding logic of an object participating in the dynamic binding.
    /// </summary>
    public class DynamicMetaObject
    {
        /// <summary>
        /// Represents an empty array of type <see cref="DynamicMetaObject"/>. This field is read-only.
        /// </summary>
        public static readonly DynamicMetaObject[] EmptyMetaObjects = ArrayReservoir<DynamicMetaObject>.EmptyArray;

        // having sentinel value means having no value. (this way we do not need a separate hasValue field)
        private static readonly object _noValueSentinel = new object();

        private readonly object _value = _noValueSentinel;

        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicMetaObject"/> class.
        /// </summary>
        /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
        /// <param name="restrictions">The set of binding restrictions under which the binding is valid.</param>
        public DynamicMetaObject(Expression expression, BindingRestrictions restrictions)
        {
            ContractUtils.RequiresNotNull(expression, nameof(expression));
            ContractUtils.RequiresNotNull(restrictions, nameof(restrictions));

            Expression = expression;
            Restrictions = restrictions;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicMetaObject"/> class.
        /// </summary>
        /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
        /// <param name="restrictions">The set of binding restrictions under which the binding is valid.</param>
        /// <param name="value">The runtime value represented by the <see cref="DynamicMetaObject"/>.</param>
        public DynamicMetaObject(Expression expression, BindingRestrictions restrictions, object value)
            : this(expression, restrictions)
        {
            _value = value;
        }

        /// <summary>
        /// The expression representing the <see cref="DynamicMetaObject"/> during the dynamic binding process.
        /// </summary>
        public Expression Expression { get; }

        /// <summary>
        /// Gets a value indicating whether the <see cref="DynamicMetaObject"/> has the runtime value.
        /// </summary>
        public bool HasValue => _value != _noValueSentinel;

        /// <summary>
        /// Gets the limit type of the <see cref="DynamicMetaObject"/>.
        /// </summary>
        /// <remarks>Represents the most specific type known about the object represented by the <see cref="DynamicMetaObject"/>. <see cref="RuntimeType"/> if runtime value is available, a type of the <see cref="Expression"/> otherwise.</remarks>
        public Type LimitType => RuntimeType ?? Expression.Type;

        /// <summary>
        /// The set of binding restrictions under which the binding is valid.
        /// </summary>
        public BindingRestrictions Restrictions { get; }

        /// <summary>
        /// Gets the <see cref="Type"/> of the runtime value or null if the <see cref="DynamicMetaObject"/> has no value associated with it.
        /// </summary>
        public Type RuntimeType
        {
            get
            {
                if (HasValue)
                {
                    var ct = Expression.Type;
                    // ValueType at compile time, type cannot change.
                    if (ct.IsValueType)
                    {
                        return ct;
                    }

                    return Value?.GetType();
                }

                return null;
            }
        }

        /// <summary>
        /// The runtime value represented by this <see cref="DynamicMetaObject"/>.
        /// </summary>
        public object Value => HasValue ? _value : null;

        /// <summary>
        /// Creates a meta-object for the specified object.
        /// </summary>
        /// <param name="value">The object to get a meta-object for.</param>
        /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
        /// <returns>
        /// If the given object implements <see cref="IDynamicMetaObjectProvider"/> and is not a remote object from outside the current AppDomain,
        /// returns the object's specific meta-object returned by <see cref="IDynamicMetaObjectProvider.GetMetaObject"/>. Otherwise a plain new meta-object
        /// with no restrictions is created and returned.
        /// </returns>
        public static DynamicMetaObject Create(object value, Expression expression)
        {
            ContractUtils.RequiresNotNull(expression, nameof(expression));

            if (value is IDynamicMetaObjectProvider ido)
            {
                var idoMetaObject = ido.GetMetaObject(expression);

                if (idoMetaObject == null ||
                    !idoMetaObject.HasValue ||
                    idoMetaObject.Value == null ||
                    idoMetaObject.Expression != expression)
                {
                    throw Error.InvalidMetaObjectCreated(ido.GetType());
                }

                return idoMetaObject;
            }

            return new DynamicMetaObject(expression, BindingRestrictions.Empty, value);
        }

        /// <summary>
        /// Performs the binding of the dynamic binary operation.
        /// </summary>
        /// <param name="binder">An instance of the <see cref="BinaryOperationBinder"/> that represents the details of the dynamic operation.</param>
        /// <param name="arg">An instance of the <see cref="DynamicMetaObject"/> representing the right hand side of the binary operation.</param>
        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
        public virtual DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
        {
            ContractUtils.RequiresNotNull(binder, nameof(binder));
            return binder.FallbackBinaryOperation(this, arg);
        }

        /// <summary><commit_msg>DynamicMetaObject review<commit_after>#if LESSTHAN_NET35

// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System.Collections.Generic;
using System.Diagnostics;
using System.Dynamic.Utils;
using System.Linq.Expressions;
using Theraot.Collections.ThreadSafe;

namespace System.Dynamic
{
    /// <summary>
    /// Represents the dynamic binding and a binding logic of an object participating in the dynamic binding.
    /// </summary>
    public class DynamicMetaObject
    {
        /// <summary>
        /// Represents an empty array of type <see cref="DynamicMetaObject"/>. This field is read-only.
        /// </summary>
        public static readonly DynamicMetaObject[] EmptyMetaObjects = ArrayReservoir<DynamicMetaObject>.EmptyArray;

        // having sentinel value means having no value. (this way we do not need a separate hasValue field)
        private static readonly object _noValueSentinel = new object();

        private readonly object _value = _noValueSentinel;

        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicMetaObject"/> class.
        /// </summary>
        /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
        /// <param name="restrictions">The set of binding restrictions under which the binding is valid.</param>
        public DynamicMetaObject(Expression expression, BindingRestrictions restrictions)
        {
            ContractUtils.RequiresNotNull(expression, nameof(expression));
            ContractUtils.RequiresNotNull(restrictions, nameof(restrictions));

            Expression = expression;
            Restrictions = restrictions;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="DynamicMetaObject"/> class.
        /// </summary>
        /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
        /// <param name="restrictions">The set of binding restrictions under which the binding is valid.</param>
        /// <param name="value">The runtime value represented by the <see cref="DynamicMetaObject"/>.</param>
        public DynamicMetaObject(Expression expression, BindingRestrictions restrictions, object value)
            : this(expression, restrictions)
        {
            _value = value;
        }

        /// <summary>
        /// The expression representing the <see cref="DynamicMetaObject"/> during the dynamic binding process.
        /// </summary>
        public Expression Expression { get; }

        /// <summary>
        /// Gets a value indicating whether the <see cref="DynamicMetaObject"/> has the runtime value.
        /// </summary>
        public bool HasValue => _value != _noValueSentinel;

        /// <summary>
        /// Gets the limit type of the <see cref="DynamicMetaObject"/>.
        /// </summary>
        /// <remarks>Represents the most specific type known about the object represented by the <see cref="DynamicMetaObject"/>. <see cref="RuntimeType"/> if runtime value is available, a type of the <see cref="Expression"/> otherwise.</remarks>
        public Type LimitType => RuntimeType ?? Expression.Type;

        /// <summary>
        /// The set of binding restrictions under which the binding is valid.
        /// </summary>
        public BindingRestrictions Restrictions { get; }

        /// <summary>
        /// Gets the <see cref="Type"/> of the runtime value or null if the <see cref="DynamicMetaObject"/> has no value associated with it.
        /// </summary>
        public Type RuntimeType
        {
            get
            {
                if (HasValue)
                {
                    var ct = Expression.Type;
                    // ValueType at compile time, type cannot change.
                    if (ct.IsValueType)
                    {
                        return ct;
                    }

                    return Value?.GetType();
                }

                return null;
            }
        }

        /// <summary>
        /// The runtime value represented by this <see cref="DynamicMetaObject"/>.
        /// </summary>
        public object Value => HasValue ? _value : null;

        /// <summary>
        /// Creates a meta-object for the specified object.
        /// </summary>
        /// <param name="value">The object to get a meta-object for.</param>
        /// <param name="expression">The expression representing this <see cref="DynamicMetaObject"/> during the dynamic binding process.</param>
        /// <returns>
        /// If the given object implements <see cref="IDynamicMetaObjectProvider"/> and is not a remote object from outside the current AppDomain,
        /// returns the object's specific meta-object returned by <see cref="IDynamicMetaObjectProvider.GetMetaObject"/>. Otherwise a plain new meta-object
        /// with no restrictions is created and returned.
        /// </returns>
        public static DynamicMetaObject Create(object value, Expression expression)
        {
            ContractUtils.RequiresNotNull(expression, nameof(expression));

            if (value is IDynamicMetaObjectProvider ido)
            {
                var idoMetaObject = ido.GetMetaObject(expression);

                if (idoMetaObject?.HasValue != true
                    || idoMetaObject.Value == null
                    || idoMetaObject.Expression != expression)
                {
                    throw Error.InvalidMetaObjectCreated(ido.GetType());
                }

                return idoMetaObject;
            }

            return new DynamicMetaObject(expression, BindingRestrictions.Empty, value);
        }

        /// <summary>
        /// Performs the binding of the dynamic binary operation.
        /// </summary>
        /// <param name="binder">An instance of the <see cref="BinaryOperationBinder"/> that represents the details of the dynamic operation.</param>
        /// <param name="arg">An instance of the <see cref="DynamicMetaObject"/> representing the right hand side of the binary operation.</param>
        /// <returns>The new <see cref="DynamicMetaObject"/> representing the result of the binding.</returns>
        public virtual DynamicMetaObject BindBinaryOperation(BinaryOperationBinder binder, DynamicMetaObject arg)
        {
            ContractUtils.RequiresNotNull(binder, nameof(binder));
            return binder.FallbackBinaryOperation(this, arg);
        }

        /// <summary>
{'fraction_non_alphanumeric': 0.10022964664049189, 'fraction_numerical': 0.00029631824579598486, 'mean_word_length': 2.1854648419065597, 'pattern_counts': {'":': 0, '<': 145, '<?xml version=': 0, '>': 151, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1784081', 'n_tokens_mistral': 3150, 'n_tokens_neox': 3029, 'n_words': 1095}