Ejemplo n.º 1
0
 public override ModelfieldContract VisitModelfieldContract(ModelfieldContract mfC) {
   if (mfC == null) return null;
   SpecSharpCompilerOptions options = this.currentOptions as SpecSharpCompilerOptions;
   if (options != null && options.CheckContractAdmissibility) {
     AdmissibilityChecker checker = new AdmissibilityChecker(this);
     this.TransferStateTo(checker);
     checker.CheckModelfieldAdmissibility(mfC);
   }
   return base.VisitModelfieldContract(mfC);
 }
Ejemplo n.º 2
0
 public override MethodContract VisitMethodContract (MethodContract contract) {
   if (contract == null) return null;
   ExpressionList modifies = contract.Modifies;
   if (modifies != null) {
     for (int i = 0, n = modifies.Count; i < n; i++) {
       #region modifies g, E.x, E[E0, E1, ... ]
       UnaryExpression ue = modifies[i] as UnaryExpression;
       if (ue != null) {
         Expression operand = ue.Operand;
         if (operand == null) continue; // something else is wrong: let other parts of the compiler warn about it
         MemberBinding mb = operand as MemberBinding;
         if (mb != null && mb.BoundMember is Field) {
           Field field = mb.BoundMember as Field;
           #region modifies g
           if (field != null && field.IsStatic) {
             if (mb.TargetObject != null) {
               this.HandleError(modifies[i], Error.InvalidModifiesClause, ": invalid static field reference");
               modifies[i] = null;
               continue;
             }
             continue; // OK
           }
           #endregion
           #region modifies E.x
           // last conjunct is because at this stage, parameters look like "<implicit this>.p"
           if (field != null && !field.IsStatic && IsReferenceTypeButNotArray(mb.TargetObject.Type) && (!(field is ParameterField))) continue;
           this.HandleError(modifies[i], Error.InvalidModifiesClause, ": 'E.x' is allowed only when E has a reference type, not '" + this.GetTypeName(mb.TargetObject.Type) + "'");
           modifies[i] = null;
           continue;
         #endregion
         }
         #region modifies E[E0, E1, ... ]
         Indexer ie = ue.Operand as Indexer;
         if (ie != null) continue; // other checks will make sure that E is an array with the right rank and the indices are the right type
         #endregion
         #region Exhausted all possibilities, but don't issue an error.
         // Assume (!!?!) that some other check will complain, e.g., "modifies o.f" where the type of o doesn't have a field f
         //this.HandleError(modifies[i], Error.InvalidModifiesClause, "");
         //modifies[i] = null;
         continue;
         #endregion
       }
       #endregion
       #region modifies E*, E.**, E.0, E[*]
       ModifiesClause mc = modifies[i] as ModifiesClause;
       if (mc == null || mc.Operands == null || mc.Operands.Count != 1) {
         // Assume (!!?!) that some other check will complain, e.g., "modifies o.f" where the type of o doesn't have a field f
         //this.HandleError(mc.Operands[0], Error.InvalidModifiesClause, "");
         //modifies[i] = null;
         continue;
       }
       TypeNode operandType = mc.Operands[0].Type;
       TypeNode unwrapped = this.typeSystem.Unwrap(operandType);
       #region modifies E.*
       if (mc is ModifiesObjectClause && !IsReferenceTypeButNotArray(operandType)) {
         this.HandleError(mc.Operands[0], Error.InvalidModifiesClause, ": 'E.*' is allowed only when E has a reference type, not '" + this.GetTypeName(operandType) + "'");
         modifies[i] = null;
         continue;
       }
       #endregion
       #region modifies E.**
       if (mc is ModifiesPeersClause && unwrapped.IsValueType) {
         this.HandleError(mc.Operands[0], Error.InvalidModifiesClause, ": 'E.**' is allowed only when E has a reference type, not '" + this.GetTypeName(operandType) + "'");
         modifies[i] = null;
         continue;
       }
       #endregion
       #region modifies E.0
       if (mc is ModifiesNothingClause && unwrapped is Reference || unwrapped.IsValueType) { // a Reference should be created only when the type of the thing is *not* a reference type
         this.HandleError(mc.Operands[0], Error.InvalidModifiesClause, ": 'E.0' is allowed only when E has a reference type, not '" + this.GetTypeName(operandType) + "'");
         modifies[i] = null;
         continue;
       }
       #endregion
       #region modifies E[*]
       if (mc is ModifiesArrayClause && (!(unwrapped is ArrayType))) {
         this.HandleError(mc.Operands[0], Error.InvalidModifiesClause, ": E[*] is allowed only when E has an array type, not " + this.GetTypeName(operandType));
         modifies[i] = null;
         continue;
       }
       #endregion
       #endregion
     }
   }
   SpecSharpCompilerOptions options = this.currentOptions as SpecSharpCompilerOptions;
   if (options != null && options.CheckContractAdmissibility) {
     AdmissibilityChecker checker = new AdmissibilityChecker(this);
     this.TransferStateTo(checker);
     Method method = contract.DeclaringMethod;
     if (method == contract.OriginalDeclaringMethod) {
       bool isPure = method.IsPure;
       if (method.IsPure || method.IsConfined || method.IsStateIndependent) {
         foreach (Requires r in contract.Requires)
           checker.CheckMethodSpecAdmissibility(r.Condition, method, isPure, false);
         foreach (Ensures e in contract.Ensures)
           checker.CheckMethodSpecAdmissibility(e.PostCondition, method, isPure, false);
       }
     }
   }
   return base.VisitMethodContract(contract);
 }
Ejemplo n.º 3
0
 public override Invariant VisitInvariant(Invariant inv) {
   if (inv == null) return null;
   SpecSharpCompilerOptions options = this.currentOptions as SpecSharpCompilerOptions;
   if (options != null && options.CheckContractAdmissibility) {
     AdmissibilityChecker checker = new AdmissibilityChecker(this);
     this.TransferStateTo(checker);
     checker.CheckInvariantAdmissibility(inv);
   }
   return base.VisitInvariant(inv);
 }