<commit_before>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnPropertyChangedWeaver.cs" company="Catel development team">
//   Copyright (c) 2008 - 2014 Catel development team. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------


namespace Catel.Fody.Weaving.AutoProperties
{
    using System.Collections.Generic;
    using System.Linq;
    using Catel.Fody.Weaving.Argument;
    using Mono.Cecil;
    using Mono.Cecil.Cil;
    using Mono.Cecil.Rocks;

    internal class RaisePropertyChangedWeaver
    {
        #region Fields
        private readonly CatelType _catelType;

        private readonly MsCoreReferenceFinder _msCoreReferenceFinder;
        #endregion

        #region Constructors
        public RaisePropertyChangedWeaver(CatelType catelType, MsCoreReferenceFinder msCoreReferenceFinder)
        {
            _catelType = catelType;
            _msCoreReferenceFinder = msCoreReferenceFinder;
        }
        #endregion

        #region Methods
        public void Execute()
        {
            FodyEnvironment.WriteDebug($"\tExecuting '{GetType().Name}' for '{_catelType.TypeDefinition.FullName}'");

            foreach (var method in _catelType.TypeDefinition.Methods)
            {
                FixRaisePropertyChangedMethod(method);
            }
        }

        private void FixRaisePropertyChangedMethod(MethodDefinition method)
        {
            var methodBody = method.Body;

            methodBody.SimplifyMacros();

            var instructions = methodBody.Instructions;

            for (var i = 0; i < instructions.Count; i++)
            {
                // ORIGINAL:
                // 
                // IL_0001: ldarg.0      // this
                // IL_0002: ldarg.0      // this
                // IL_0003: ldtoken      Catel.Fody.TestAssembly.ObservableObjectTest
                // IL_0008: call         class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
                // IL_000d: call         class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
                // IL_0012: ldtoken      method instance string Catel.Fody.TestAssembly.ObservableObjectTest::get_ManualChangeNotificationProperty()
                // IL_0017: call         class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
                // IL_001c: castclass    [mscorlib]System.Reflection.MethodInfo
                // IL_0021: call         class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
                // IL_0026: call         !!0/*class [System.Core]System.Linq.Expressions.ParameterExpression*/[] [mscorlib]System.Array::Empty<class [System.Core]System.Linq.Expressions.ParameterExpression>()
                // IL_002b: call         class [System.Core]System.Linq.Expressions.Expression`1<!!0/*class [mscorlib]System.Func`1<string>*/> [System.Core]System.Linq.Expressions.Expression::Lambda<class [mscorlib]System.Func`1<string>>(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
                // IL_0030: call         instance void [Catel.Core]Catel.Data.ObservableObject::RaisePropertyChanged<string>(class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`1<!!0/*string*/>>)
                // IL_0035: nop

                // REPLACED:
                //
                // IL_0001: ldarg.0      // this<commit_msg>Fix issue weaving abstract methods<commit_after>﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="OnPropertyChangedWeaver.cs" company="Catel development team">
//   Copyright (c) 2008 - 2014 Catel development team. All rights reserved.
// </copyright>
// --------------------------------------------------------------------------------------------------------------------


namespace Catel.Fody.Weaving.AutoProperties
{
    using System.Collections.Generic;
    using System.Linq;
    using Catel.Fody.Weaving.Argument;
    using Mono.Cecil;
    using Mono.Cecil.Cil;
    using Mono.Cecil.Rocks;

    internal class RaisePropertyChangedWeaver
    {
        #region Fields
        private readonly CatelType _catelType;

        private readonly MsCoreReferenceFinder _msCoreReferenceFinder;
        #endregion

        #region Constructors
        public RaisePropertyChangedWeaver(CatelType catelType, MsCoreReferenceFinder msCoreReferenceFinder)
        {
            _catelType = catelType;
            _msCoreReferenceFinder = msCoreReferenceFinder;
        }
        #endregion

        #region Methods
        public void Execute()
        {
            FodyEnvironment.WriteDebug($"\tExecuting '{GetType().Name}' for '{_catelType.TypeDefinition.FullName}'");

            foreach (var method in _catelType.TypeDefinition.Methods)
            {
                FixRaisePropertyChangedMethod(method);
            }
        }

        private void FixRaisePropertyChangedMethod(MethodDefinition method)
        {
            if (method.IsAbstract || method.IsStatic)
            {
                return;
            }

            var methodBody = method.Body;

            methodBody.SimplifyMacros();

            var instructions = methodBody.Instructions;

            for (var i = 0; i < instructions.Count; i++)
            {
                // ORIGINAL:
                // 
                // IL_0001: ldarg.0      // this
                // IL_0002: ldarg.0      // this
                // IL_0003: ldtoken      Catel.Fody.TestAssembly.ObservableObjectTest
                // IL_0008: call         class [mscorlib]System.Type [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)
                // IL_000d: call         class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type)
                // IL_0012: ldtoken      method instance string Catel.Fody.TestAssembly.ObservableObjectTest::get_ManualChangeNotificationProperty()
                // IL_0017: call         class [mscorlib]System.Reflection.MethodBase [mscorlib]System.Reflection.MethodBase::GetMethodFromHandle(valuetype [mscorlib]System.RuntimeMethodHandle)
                // IL_001c: castclass    [mscorlib]System.Reflection.MethodInfo
                // IL_0021: call         class [System.Core]System.Linq.Expressions.MemberExpression [System.Core]System.Linq.Expressions.Expression::Property(class [System.Core]System.Linq.Expressions.Expression, class [mscorlib]System.Reflection.MethodInfo)
                // IL_0026: call         !!0/*class [System.Core]System.Linq.Expressions.ParameterExpression*/[] [mscorlib]System.Array::Empty<class [System.Core]System.Linq.Expressions.ParameterExpression>()
                // IL_002b: call         class [System.Core]System.Linq.Expressions.Expression`1<!!0/*class [mscorlib]System.Func`1<string>*/> [System.Core]System.Linq.Expressions.Expression::Lambda<class [mscorlib]System.Func`1<string>>(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.ParameterExpression[])
                // IL_0030: call         instance void [Catel.Core]Catel.Data.ObservableObject::RaisePropertyChanged<string>(class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`1<!!0/*string*/>>)
                // IL_0035: nop

                // REPLACED:
                //
                // IL_0001: ldarg.0      // this
{'fraction_non_alphanumeric': 0.15459472776545946, 'fraction_numerical': 0.01798472530179847, 'mean_word_length': 2.062617880045266, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 23, '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': '1565443', 'n_tokens_mistral': 2258, 'n_tokens_neox': 2094, 'n_words': 337}