<commit_before>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace NMF.Expressions
{
    internal abstract class ObservableMethodBase<T, TDelegate, TResult> : NotifyExpression<TResult>
        where TDelegate : class
    {
        public ObservableMethodBase(INotifyExpression<T> target, MethodInfo method)
        {
            if (method == null) throw new ArgumentNullException("method");
            if (target == null) throw new ArgumentNullException("target");

            Target = target;
            Method = method;
        }

        public MethodInfo Method { get; private set; }

        public TDelegate Function { get; private set; }

        public override ExpressionType NodeType { get { return ExpressionType.Invoke; } }

        public override bool CanBeConstant
        {
            get
            {
                return Target.CanBeConstant && !(Target.Value is INotifyCollectionChanged);
            }
        }

        public INotifyExpression<T> Target { get; private set; }

        private void RenewFunction()
        {
            Function = ReflectionHelper.CreateDelegate(typeof(TDelegate), Target.Value, Method) as TDelegate;
        }
        
        protected override void OnAttach()
        {
            AttachCollectionChangeListener(Target.Value);
            RenewFunction();
        }

        protected override void OnDetach()
        {
            DetachCollectionChangeListener(Target.Value);
        }

        public override INotificationResult Notify(IList<INotificationResult> sources)
        {
            ValueChangedNotificationResult<T> targetChange = null;
            foreach (var change in sources)
            {
                if (change.Source == Target)
                {
                    targetChange = change as ValueChangedNotificationResult<T>;
                    break;
                }
            }

            if (targetChange != null)
            {
                DetachCollectionChangeListener(targetChange.OldValue);
                AttachCollectionChangeListener(targetChange.NewValue);
                RenewFunction();
            }

            var oldValue = Value;
            var result = base.Notify(sources);

            if (result.Changed)
            {
                var disposable = oldValue as IDisposable;
                if (disposable != null)
                    disposable.Dispose();
            }

            return result;
        }

        private void AttachCollectionChangeListener(object target)
        {
            var newTarget = target as INotifyCollectionChanged;
            if (newTarget != null)
            {
                ExecutionContext.Instance.AddChangeListener<TResult>(this, newTarget);
            }
        }

        private void DetachCollectionChangeListener(object target)
        {
            var oldTarget = target as INotifyCollectionChanged;
            if (oldTarget != null)
                ExecutionContext.Instance.RemoveChangeListener(this, oldTarget);
        }
    }
}<commit_msg>Fixed type parameter in ObservableMethodCallBase.<commit_after>﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;

namespace NMF.Expressions
{
    internal abstract class ObservableMethodBase<T, TDelegate, TResult> : NotifyExpression<TResult>
        where TDelegate : class
    {
        public ObservableMethodBase(INotifyExpression<T> target, MethodInfo method)
        {
            if (method == null) throw new ArgumentNullException("method");
            if (target == null) throw new ArgumentNullException("target");

            Target = target;
            Method = method;
        }

        public MethodInfo Method { get; private set; }

        public TDelegate Function { get; private set; }

        public override ExpressionType NodeType { get { return ExpressionType.Invoke; } }

        public override bool CanBeConstant
        {
            get
            {
                return Target.CanBeConstant && !(Target.Value is INotifyCollectionChanged);
            }
        }

        public INotifyExpression<T> Target { get; private set; }

        private void RenewFunction()
        {
            Function = ReflectionHelper.CreateDelegate(typeof(TDelegate), Target.Value, Method) as TDelegate;
        }
        
        protected override void OnAttach()
        {
            AttachCollectionChangeListener(Target.Value);
            RenewFunction();
        }

        protected override void OnDetach()
        {
            DetachCollectionChangeListener(Target.Value);
        }

        public override INotificationResult Notify(IList<INotificationResult> sources)
        {
            ValueChangedNotificationResult<T> targetChange = null;
            foreach (var change in sources)
            {
                if (change.Source == Target)
                {
                    targetChange = change as ValueChangedNotificationResult<T>;
                    break;
                }
            }

            if (targetChange != null)
            {
                DetachCollectionChangeListener(targetChange.OldValue);
                AttachCollectionChangeListener(targetChange.NewValue);
                RenewFunction();
            }

            var oldValue = Value;
            var result = base.Notify(sources);

            if (result.Changed)
            {
                var disposable = oldValue as IDisposable;
                if (disposable != null)
                    disposable.Dispose();
            }

            return result;
        }

        private void AttachCollectionChangeListener(object target)
        {
            var newTarget = target as INotifyCollectionChanged;
            if (newTarget != null)
            {
                // Since we don't know the type of the items of the Target.Value collection
                // without using reflection, we use object here.
                ExecutionContext.Instance.AddChangeListener<object>(this, newTarget);
            }
        }

        private void DetachCollectionChangeListener(object target)
        {
            var oldTarget = target as INotifyCollectionChanged;
            if (oldTarget != null)
                ExecutionContext.Instance.RemoveChangeListener(this, oldTarget);
        }
    }
}
{'fraction_non_alphanumeric': 0.07153660012099214, 'fraction_numerical': 0.0, 'mean_word_length': 1.835763293310463, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, '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': '6608176', 'n_tokens_mistral': 1547, 'n_tokens_neox': 1488, 'n_words': 380}