public void ReturnsOneSequenceIfNoDebugInfoIsPresent()
        {
            var sequences = new InstructionSequences(new Instruction[] { Instruction.Create(OpCodes.Nop) }, null);

            Assert.Single(sequences);
            Assert.Single(sequences[0]);
        }
            public ExtensionMethodProcessor(ILogger logger, ISymbolReader?symbolReader, MethodDefinition method, AutoPropertyToBackingFieldMap autoPropertyToBackingFieldMap)
            {
                _logger = logger;
                _method = method;
                _autoPropertyToBackingFieldMap = autoPropertyToBackingFieldMap;

                _instructionSequences = new InstructionSequences(method.Body.Instructions, method.ReadSequencePoints(symbolReader));
            }
            public ExtensionMethodProcessor([NotNull] ILogger logger, [CanBeNull] ISymbolReader symbolReader, [NotNull] MethodDefinition method, [NotNull] AutoPropertyToBackingFieldMap autoPropertyToBackingFieldMap)
            {
                _logger = logger;
                _method = method;
                _autoPropertyToBackingFieldMap = autoPropertyToBackingFieldMap;

                Debug.Assert(method.Body?.Instructions != null, "method.Body.Instructions != null");

                _instructionSequences = new InstructionSequences(method.Body.Instructions, method.ReadSequencePoints(symbolReader));
            }
        public static void ReplaceFieldAccessWithPropertySetter([NotNull] this MethodDefinition constructor, [NotNull] IMemberDefinition field, [NotNull] PropertyDefinition property, [CanBeNull] ISymbolReader symbolReader)
        {
            var setMethod = property.SetMethod;

            if (setMethod == null)
            {
                return;
            }

            // field initializers are called before the call to the base constructor, but property setters must be called after!

            var instructions = constructor.Body?.Instructions;

            if (instructions == null)
            {
                return;
            }

            var instructionSequences = new InstructionSequences(instructions, constructor.ReadSequencePoints(symbolReader));

            var newInstructions = new List <Instruction>();

            foreach (var sequence in instructionSequences)
            {
                for (var i = 0; i < sequence.Count; i++)
                {
                    var instruction = sequence[i];

                    if ((instruction.OpCode != OpCodes.Stfld) || (instruction.Operand != field) || (i < 2))
                    {
                        continue;
                    }

                    sequence[i] = Instruction.Create(OpCodes.Call, setMethod);
                    newInstructions.AddRange(sequence.Take(i + 1));

                    for (var k = 0; k <= i; k++)
                    {
                        sequence.RemoveAt(0);
                    }

                    break;
                }
            }

            var index = instructions.TakeWhile(inst => !inst.IsBaseConstructorCall(constructor)).Count() + 1;

            if (index <= instructions.Count)
            {
                instructions.InsertRange(index, newInstructions.ToArray());
            }
        }