示例#1
0
        protected IExpression GenerateConditionPartTo(FieldDefinition field, IReadOnlyCollection <int> toStateIds)
        {
            var host       = CciHostEnvironment.GetInstance();
            var conditions = new List <IExpression>();

            foreach (var toStateId in toStateIds)
            {
                var cond = new Equality
                {
                    Type        = host.PlatformType.SystemBoolean,
                    LeftOperand = new BoundExpression
                    {
                        Definition = field,
                        Instance   = new ThisReference(),
                        Type       = field.Type
                    },
                    RightOperand = new CompileTimeConstant
                    {
                        Type  = field.Type,
                        Value = toStateId
                    }
                };

                conditions.Add(cond);
            }

            return(Helper.JoinWithLogicalOr(host, conditions, false));
        }
示例#2
0
        public Precondition GeneratePrecondition(FieldDefinition field, IReadOnlyCollection <int> fromStateIds)
        {
            var host       = CciHostEnvironment.GetInstance();
            var conditions = new List <IExpression>();

            foreach (var fromId in fromStateIds)
            {
                var cond = new Equality
                {
                    Type        = host.PlatformType.SystemBoolean,
                    LeftOperand = new BoundExpression
                    {
                        Definition = field,
                        Instance   = new ThisReference(),
                        Type       = field.Type
                    },
                    RightOperand = new CompileTimeConstant
                    {
                        Type  = field.Type,
                        Value = fromId
                    }
                };

                conditions.Add(cond);
            }

            return(new Precondition
            {
                Condition = Helper.JoinWithLogicalOr(host, conditions, false),
                OriginalSource = new CciExpressionPrettyPrinter().PrintExpression(Helper.JoinWithLogicalOr(host, conditions, false))
            });
        }
示例#3
0
        protected Postcondition GeneratePostcondition(FieldDefinition field, int fromStateId, IReadOnlyCollection <int> toStateIds)
        {
            var         host = CciHostEnvironment.GetInstance();
            IExpression conditional;

            if (fromStateId.Equals(initialStateId))
            {
                //Initial state
                conditional = GenerateConditionPartTo(field, toStateIds);
            }
            else
            {
                conditional = new Conditional
                {
                    Type          = host.PlatformType.SystemBoolean,
                    Condition     = GenerateConditionPartFrom(field, fromStateId),
                    ResultIfTrue  = GenerateConditionPartTo(field, toStateIds),
                    ResultIfFalse = new CompileTimeConstant
                    {
                        Type  = host.PlatformType.SystemBoolean,
                        Value = true
                    }
                };
            }

            return(new Postcondition
            {
                Condition = conditional,
                OriginalSource = new CciExpressionPrettyPrinter().PrintExpression(conditional)
            });
        }
示例#4
0
        protected List <IExpression> GenerateStatesConditions(IReadOnlyCollection <State> states)
        {
            var host = CciHostEnvironment.GetInstance();

            //Optimizacion: calculamos la interseccion de todas las acciones habilitadas
            //y desabilitadas de todos los estados y se la restamos a todos
            var firstState          = states.First();
            var enabledIntersection =
                new List <Action>(states.Aggregate(firstState.EnabledActions, (IEnumerable <Action> a, State s) => a.Intersect(s.EnabledActions)));
            var disabledIntersection =
                new List <Action>(states.Aggregate(firstState.DisabledActions, (IEnumerable <Action> a, State s) => a.Intersect(s.DisabledActions)));

            var conditions = new List <IExpression>();

            foreach (var state in states)
            {
                var enabledActions  = state.EnabledActions.Except(enabledIntersection);
                var disabledActions = state.DisabledActions.Except(disabledIntersection);

                var exprs     = GenerateStateInvariant(enabledActions, disabledActions);
                var condition = Helper.JoinWithLogicalAnd(host, exprs, true);
                conditions.Add(condition);
            }

            return(conditions);
        }
示例#5
0
        protected FieldDefinition CreateStateField(NamedTypeDefinition typeDefinition, TypeContract typeContract)
        {
            var host = CciHostEnvironment.GetInstance();

            var field = new FieldDefinition
            {
                Name       = host.NameTable.GetNameFor("$state"),
                Type       = host.PlatformType.SystemInt32,
                Visibility = TypeMemberVisibility.Private,
                ContainingTypeDefinition = typeDefinition,
                InternFactory            = typeDefinition.InternFactory,
                CompileTimeValue         = new CompileTimeConstant
                {
                    Type  = host.PlatformType.SystemInt32,
                    Value = 0
                }
            };

            // Como el $state es int, necesito el invariante ya que no puede ser negativo.
            // Se usa int en vez de uint, para que no haya problemas con la traduccion de BCT
            if (typeContract == null)
            {
                typeContract = new TypeContract();
            }

            typeContract.Invariants.Add(new TypeInvariant
            {
                Condition = new GreaterThanOrEqual
                {
                    LeftOperand = new BoundExpression {
                        Definition = field, Instance = new ThisReference(), Type = field.Type
                    },
                    RightOperand = new CompileTimeConstant {
                        Type = host.PlatformType.SystemInt32, Value = 0
                    }
                }
            });

            return(field);
        }
示例#6
0
        // Do not include the type invariant
        protected List <IExpression> GenerateStateInvariant(IReadOnlyCollection <Action> enabledActions, IReadOnlyCollection <Action> disabledActions)
        {
            var host  = CciHostEnvironment.GetInstance();
            var exprs = new List <IExpression>();

            foreach (var action in enabledActions)
            {
                var conditions = from pre in action.Contract.Preconditions
                                 select pre.Condition;
                exprs.AddRange(conditions);
            }

            foreach (var action in disabledActions)
            {
                if (action.Contract == null || !action.Contract.Preconditions.Any())
                {
                    var literal = new CompileTimeConstant
                    {
                        Type  = host.PlatformType.SystemBoolean,
                        Value = false
                    };

                    exprs.Add(literal);
                    continue;
                }

                var conditions = (from pre in action.Contract.Preconditions select pre.Condition).ToList();
                var condition  = new LogicalNot
                {
                    Type    = host.PlatformType.SystemBoolean,
                    Operand = Helper.JoinWithLogicalAnd(host, conditions, true)
                };

                exprs.Add(condition);
            }

            return(exprs);
        }
示例#7
0
        protected IExpression GenerateConditionPartFrom(FieldDefinition field, int fromStateId)
        {
            var host = CciHostEnvironment.GetInstance();

            return(new Equality
            {
                Type = host.PlatformType.SystemBoolean,
                LeftOperand = new OldValue
                {
                    Type = field.Type,
                    Expression = new BoundExpression
                    {
                        Definition = field,
                        Instance = new ThisReference(),
                        Type = field.Type
                    }
                },
                RightOperand = new CompileTimeConstant
                {
                    Type = field.Type,
                    Value = fromStateId
                }
            });
        }
示例#8
0
        public IAssembly InstrumentType(CciAssembly assembly, Epa epa)
        {
            Contract.Requires(assembly != null);
            Contract.Requires(epa != null);
            Contract.Requires(assembly.Types().Contains(epa.Type));

            // Clone assembly
            var host   = CciHostEnvironment.GetInstance();
            var module = new CodeAndContractDeepCopier(host).Copy(assembly.Module);

            var contractExtractor = host.GetContractExtractor(module.UnitIdentity);
            var contractProvider  = new AggregatingContractProvider(contractExtractor);

            var preconditions = new Dictionary <string, List <IPrecondition> >();

            var actions = new List <Action>(from transition in epa.Transitions.GroupBy(t => t.Action) select transition.Key);

            Contract.Assert(actions.Any());

            foreach (var action in actions)
            {
                // TODO (lleraromero): Es necesario? NullObject Pattern?
                var mc = action.Contract as MethodContract;
                if (mc == null)
                {
                    continue;
                }

                preconditions.Add(action.Name, action.Contract.Preconditions.ToList());
            }

            var typeDefinition    = epa.Type;
            var cciTypeDefinition =
                module.AllTypes.First(
                    t => TypeHelper.GetTypeName(t, NameFormattingOptions.UseGenericTypeNameSuffix).Equals(typeDefinition.Name)) as NamedTypeDefinition;

            Contract.Assert(cciTypeDefinition != null);

            var typeContract = RemoveInvariantMethods(typeDefinition, cciTypeDefinition);

            // Add a field to represent the state
            var field = CreateStateField(cciTypeDefinition, typeContract);

            cciTypeDefinition.Fields.Add(field);

            // Associate type contract to the contract provider
            contractProvider.AssociateTypeWithContract(cciTypeDefinition, typeContract);

            // Create Ids
            var stateNumberMap = new Dictionary <State, int>();

            foreach (var state in epa.States)
            {
                stateNumberMap.Add(state, stateNumberMap.Keys.Count);
            }

            foreach (var action in actions)
            {
                // voy a agrupar las transiciones que usan esta accion por sourceState.Id
                // transitions = Dicc<int, List<int>> o sea: "Dicc<from, List<to>>"
                var transitionsUsingAction = new List <Transition>(from t in epa.Transitions where t.Action.Equals(action) select t);
                var transitionsSourceIds   = new HashSet <int>(from t in transitionsUsingAction select stateNumberMap[t.SourceState]).Distinct();

                var transitions = new Dictionary <int, List <int> >();
                foreach (var t in transitionsUsingAction)
                {
                    var sourceStateId = stateNumberMap[t.SourceState];
                    if (!transitions.ContainsKey(sourceStateId))
                    {
                        transitions.Add(sourceStateId, new List <int>());
                    }

                    var targetStateId = stateNumberMap[t.TargetState];
                    transitions[sourceStateId].Add(targetStateId);
                }

                var methodContract   = action.Contract as MethodContract ?? new MethodContract();
                var methodDefinition = cciTypeDefinition.Methods.First(m => m.GetUniqueName().Equals(action.Method.GetUniqueName()));

                BlockStatement actionBodyBlock = null;
                if (methodDefinition.Body is SourceMethodBody)
                {
                    var actionBody = (SourceMethodBody)methodDefinition.Body;
                    actionBodyBlock = actionBody.Block as BlockStatement;
                }
                else if (methodDefinition.Body is Microsoft.Cci.MutableCodeModel.SourceMethodBody)
                {
                    var actionBody = (Microsoft.Cci.MutableCodeModel.SourceMethodBody)methodDefinition.Body;
                    actionBodyBlock = actionBody.Block as BlockStatement;
                }
                Contract.Assert(actionBodyBlock != null);

                //Por tratarse de un constructor insertamos en 1 porque en 0 esta base..ctor()
                var insertAtIndex = methodDefinition.IsConstructor ? 1 : 0;

                // CodeContracts no permite utilizar 'this' en los requires de los constructores
                if (!methodDefinition.IsConstructor)
                {
                    var pre = new PreconditionGenerator().GeneratePrecondition(field, transitions.Keys.ToList());
                    methodContract.Preconditions.Add(pre);
                }

                var posts = new PostconditionGenerator(stateNumberMap[epa.Initial]).GeneratePostconditions(field, transitions);
                methodContract.Postconditions.AddRange(posts);

                // Associate contract
                contractProvider.AssociateMethodWithContract(methodDefinition, methodContract);

                var stmt = new SwitchGenerator(epa, stateNumberMap).GenerateSwitch(field, transitions);

                // Se actualiza el $state en un finally porque los if de adentro del switch tienen que ser ejecutados despues del cuerpo de este metodo
                var stmtsCount = actionBodyBlock.Statements.Count - insertAtIndex;
                var tryBlock   = new BlockStatement();
                var bodyStmts  = new List <IStatement>(actionBodyBlock.Statements.GetRange(insertAtIndex, stmtsCount));
                tryBlock.Statements.AddRange(bodyStmts);

                var finallyBlock = new BlockStatement();
                finallyBlock.Statements.Add(stmt);

                var tryStmt = new TryCatchFinallyStatement
                {
                    TryBody     = tryBlock,
                    FinallyBody = finallyBlock
                };

                actionBodyBlock.Statements.RemoveRange(insertAtIndex, stmtsCount);
                actionBodyBlock.Statements.Insert(insertAtIndex, tryStmt);
            }

            return(new CciAssembly(module, contractProvider));
        }
示例#9
0
 public CciContractRewriter()
 {
     host = CciHostEnvironment.GetInstance();
 }