public override Action<ITextControl> Apply(
            ValidationResult validationResult, CodeContractStatement contractStatement)
        {
            // This fix contains following steps:
            // 1. Removing original postcondition
            // 2. Looking for contract block of the current method
            // 3. If this block exists, fix should move postcondition to the appropriate place 
            //    (after last postcondition or precondition)
            // 4. Otherwise fix should move the precondition at the beginning of the method.

            // We should get contract block and potential target block before
            // removing current statement
            var contractBlock = GetContractBlock(contractStatement);

            var containingFunction = GetContainingFunction(contractStatement.Statement);

            contractStatement.Statement.RemoveOrReplaceByEmptyStatement();

            ICSharpStatement anchor = GetAnchor(contractBlock, contractStatement);

            ICSharpStatement updatedStatement;

            if (anchor != null)
            {
                updatedStatement = anchor.AddStatementsAfter(new[] {contractStatement.Statement}, contractStatement.Statement);
            }
            else
            {
                updatedStatement = containingFunction.Body.AddStatementAfter(contractStatement.Statement, null);
            }

            return textControl => textControl.Caret.MoveTo(updatedStatement);
        }
 public override bool IsApplicable(ValidationResult validationResult, CodeContractStatement contractStatement)
 {
     return validationResult.Match(_ => false,
         error => error.Error == MalformedContractError.ContractStatementInTheMiddleOfTheMethod &&
                  contractStatement.IsEndContractBlock,
         _ => false);
 }
        public ValidationResult Validate(CodeContractStatement statement)
        {
            Contract.Requires(statement != null);
            Contract.Ensures(Contract.Result<ValidationResult>() != null);

            return _statementValidationRule(statement);
        }
        private static ValidationResult CheckCompatibilityOfContractResultWithMethodReturnType(
            CodeContractStatement statement)
        {
            var contractResultTypes =
                statement.CodeContractExpression
                    .Value
                    .With(x => x as ContractEnsures)
                    .Return(ensures => ensures.ContractResultTypes, Enumerable.Empty<IDeclaredType>().ToList());

            var method = statement.GetDeclaredMethod();

            var methodResult = method
                .With(x => x.DeclaredElement)
                .Return(x => x.ReturnType);

            if (methodResult != null && contractResultTypes.Count != 0)
            {
                if (methodResult.IsVoid())
                {
                    return ValidationResult.CreateError(statement.Statement,
                        MalformedContractError.EnsuresInVoidReturnMethod,
                        ErrorForIncompatibleEnsuresAndReturnType(methodResult, contractResultTypes.First(), method));
                }

                if (!MethodResultIsCompatibleWith(methodResult, contractResultTypes))
                {
                    return ValidationResult.CreateError(statement.Statement,
                        MalformedContractError.ResultTypeInEnsuresIsIncompatibleWithMethodReturnType,
                        ErrorForIncompatibleEnsuresAndReturnType(methodResult, contractResultTypes.First(), method));
                }
            }

            return ValidationResult.CreateNoError(statement.Statement);
        }
        public static IMalformedContractStatementFix TryCreate(ValidationResult validationResult,
            CodeContractStatement contractStatement)
        {
            Contract.Requires(validationResult != null);
            Contract.Requires(contractStatement != null);

            return _fixes.FirstOrDefault(f => f.IsApplicable(validationResult, contractStatement));
        }
        internal MalformedContractErrorHighlighting(CodeContractStatement validatedStatement, ValidationResult validationResult)
        {
            Contract.Requires(validatedStatement != null);
            Contract.Requires(validationResult != null);

            _validatedStatement = validatedStatement;
            _validationResult = validationResult;
            _toolTip = _validationResult.GetErrorText();
        }
        public MalformedContractStatementQuickFix(MalformedContractErrorHighlighting highlighting)
        {
            Contract.Requires(highlighting != null);

            _fix = MalformedContractStatementFix.TryCreate(highlighting.ValidationResult,
                highlighting.ProcessedStatement);
            _validationResult = highlighting.ValidationResult;
            _contractStatement = highlighting.ProcessedStatement;
        }
 public override Action<ITextControl> Apply(
     ValidationResult validationResult, CodeContractStatement contractStatement)
 {
     contractStatement.Statement.RemoveOrReplaceByEmptyStatement();
     return null;
 }
 public abstract Action<ITextControl> Apply(ValidationResult validationResult, CodeContractStatement contractStatement);
 public abstract bool IsApplicable(ValidationResult validationResult, CodeContractStatement contractStatement);
        private ICSharpStatement CreateAssertStatement(CodeContractStatement contractStatement)
        {
            var invocationExpression = contractStatement.InvocationExpression;
            Contract.Assert(invocationExpression.Arguments.Count != 0);

            var factory = CSharpElementFactory.GetInstance(contractStatement.Statement);

            if (invocationExpression.Arguments.Count == 1)
            {
                return factory.CreateStatement("Contract.Assert($0);", invocationExpression.Arguments[0]);
            }
            return factory.CreateStatement("Contract.Assert($0, $1);", invocationExpression.Arguments[0], invocationExpression.Arguments[1]);
        }
        public override Action<ITextControl> Apply(ValidationResult validationResult, CodeContractStatement contractStatement)
        {
            var assertStatement = CreateAssertStatement(contractStatement);
            contractStatement.Statement.ReplaceBy(assertStatement);

            return null;
        }
 private static ICSharpStatement GetAnchor(IList<ProcessedStatement> statements, 
     CodeContractStatement contractStatement)
 {
     // Looking for the last precondition if we're moving precondition
     // or looking for the last postcondition or precondition for Ensures and EndContractBlock
     return statements
         .Where(s => s.CodeContractStatement != null)
         .Reverse()
         .FirstOrDefault(
             s =>
             {
                 if (contractStatement.IsPrecondition)
                     return s.CodeContractStatement.IsPostcondition;
                 return s.CodeContractStatement.IsPostcondition || s.CodeContractStatement.IsPrecondition;
             })
         .Return(x => x.CSharpStatement);
 }
        private IList<ProcessedStatement> GetContractBlock(CodeContractStatement contractStatement)
        {
            var method = contractStatement.Statement.GetContainingNode<ICSharpFunctionDeclaration>();
            Contract.Assert(method != null);

            return method.GetCodeContractBlockStatements();
        }
        private static bool HasPreconditionAfterCurrentStatement(IList<ProcessedStatement> contractBlock, CodeContractStatement currentStatement)
        {
            var index = contractBlock.IndexOf(ps => ps.ContractStatement == currentStatement);
            Contract.Assert(index != -1, "Current statement should be inside contract block");

            return
                contractBlock.Skip(index + 1)
                    .Any(cs => cs.CodeContractStatement != null && cs.CodeContractStatement.IsPrecondition);
        }