コード例 #1
0
        static string contractRename(Method meth, ArrayList a, ArrayList b)
        {
            MethodContract mc = meth.Contract;

            File.AppendAllText("g:\\test3.txt", meth.HelpText + "\r\n");
            return "";
        }
コード例 #2
0
ファイル: Rewriter.cs プロジェクト: Yatajga/CodeContracts
 private CurrentState(TypeNode type, Dictionary<string, object> typeSuppressed, Method method)
 {
     this.Type = type;
     this.typeSuppressed = typeSuppressed;
     this.Method = method;
     this.methodSuppressed = null;
 }
コード例 #3
0
 public CollectOldExpressions(Module module, Method method, ContractNodes contractNodes, Dictionary<TypeNode, Local> closureLocals, 
     int localCounterStart, Class initialClosureClass)
     : this(module, method, contractNodes, closureLocals, localCounterStart)
 {
     this.topLevelClosureClass = initialClosureClass;
     this.currentClosureClass = initialClosureClass;
 }
コード例 #4
0
 static public void check(TypeSystem t, Method m){
   ModifiesChecker mChecker=new ModifiesChecker(t);
   ControlFlowGraph cfg=ControlFlowGraph.For(m);
   mChecker.Run(cfg,
     null // TBD
     );
 } 
コード例 #5
0
ファイル: RewriteUtils.cs プロジェクト: nbulp/CodeContracts
        internal static Block CreateTryFinallyBlock(Method method, Block tryBody, Block finallyBody)
        {
          Contract.Requires(method != null);
          Contract.Requires(tryBody != null);
          Contract.Requires(finallyBody != null);

            if (method.ExceptionHandlers == null) method.ExceptionHandlers = new ExceptionHandlerList();

            Block result = new Block(new StatementList());
            Block afterFinally = new Block(new StatementList());

            tryBody.Statements.Add(new Branch(null, afterFinally, false, true, true));
            finallyBody.Statements.Add(new EndFinally());

            result.Statements.Add(tryBody);
            result.Statements.Add(finallyBody);
            result.Statements.Add(afterFinally);

            ExceptionHandler fb = new ExceptionHandler();
            fb.TryStartBlock = tryBody;
            fb.BlockAfterTryEnd = finallyBody;
            fb.HandlerStartBlock = finallyBody;
            fb.BlockAfterHandlerEnd = afterFinally;
            fb.HandlerType = NodeType.Finally;
            method.ExceptionHandlers.Add(fb);

            return result;
        }
コード例 #6
0
ファイル: Checker.cs プロジェクト: nbulp/CodeContracts
 public CurrentState(AssemblyNode assembly) {
   this.Assembly = assembly;
   this.Type = null;
   this.Method = null;
   this.assemblySuppressed = null;
   this.typeSuppressed = null;
   this.methodSuppressed = null;
 }
コード例 #7
0
 public override Method VisitMethod(Method method)
 {
     if (method == null) return null;
     this.VisitAttributeList(method.Attributes);
     this.VisitAttributeList(method.ReturnAttributes);
     // don't visit further into the method.
     return method;
 }
コード例 #8
0
 public void CheckMethodSpecAdmissibility(Expression exp, Method method, bool reportWFonly, bool dontReport) {
   DeclaringMethod = method;
   ReportWFErrorOnly = reportWFonly; // true for Pure methods: we only want to enforce well-foundedness on them
   DontReportError = dontReport;     
   StateStack = new System.Collections.Stack();
   ResetCurrentState();
   this.VisitExpression(exp);
 }
コード例 #9
0
        public DuplicatorForContractsAndClosures(Module module, Method sourceMethod, Method targetMethod,
            ContractNodes contractNodes, bool mapParameters)
            : base(module, targetMethod.DeclaringType)
        {
            this.sourceMethod = sourceMethod;
            this.targetMethod = targetMethod;

            this.RemoveNameForLocals = true;

            Duplicator dup = this;

            if (mapParameters)
            {
                if (sourceMethod.ThisParameter != null)
                {
                    if (targetMethod.ThisParameter != null)
                    {
                        dup.DuplicateFor[sourceMethod.ThisParameter.UniqueKey] = targetMethod.ThisParameter;
                    }
                    else
                    {
                        // target is a static wrapper. But duplicator cannot handle This -> Parameter conversion
                        // so we handle it explicitly here in this visitor.
                        replaceThisWithParameter = targetMethod.Parameters[0];
                    }
                }

                if (sourceMethod.Parameters != null && targetMethod.Parameters != null
                    && sourceMethod.Parameters.Count == targetMethod.Parameters.Count)
                {
                    for (int i = 0, n = sourceMethod.Parameters.Count; i < n; i++)
                    {
                        dup.DuplicateFor[sourceMethod.Parameters[i].UniqueKey] = targetMethod.Parameters[i];
                    }
                }
            }

            var originalType = HelperMethods.IsContractTypeForSomeOtherType(sourceMethod.DeclaringType, contractNodes);
            if (originalType != null)
            {
                var contractType = this.contractClass = sourceMethod.DeclaringType;
                while (contractType.Template != null)
                {
                    contractType = contractType.Template;
                }
                    
                while (originalType.Template != null)
                {
                    originalType = originalType.Template;
                }

                // forward ContractType<A,B> -> originalType<A',B'>
                this.contractClassToForward = contractType;
                this.targetTypeToForwardTo = originalType;

                //dup.DuplicateFor[contractType.UniqueKey] = originalType;
            }
        }
コード例 #10
0
ファイル: ZDuplicator.cs プロジェクト: ZingModelChecker/Zing
        public override Method VisitMethod(Method method)
        {
            if (method == null) return null;

            ZMethod result = (ZMethod)base.VisitMethod(method);

            result.ResetLocals();
            return result;
        }
コード例 #11
0
 public CurrentState(TypeNode type, CurrentState oldState)
 {
     this.Type = type;
     this.Method = null;
     this.typeSuppressed = null;
     this.methodSuppressed = null;
     this.Assembly = oldState.Assembly;
     this.assemblySuppressed = oldState.assemblySuppressed;
 }
コード例 #12
0
 /// <summary>
 /// Visits the ensures clauses to clean up Old expressions
 /// </summary>
 /// <param name="m"></param>
 public void CleanupEnsures(Method m)
 {
     if (m.Contract != null)
     {
         this.VisitEnsuresList(m.Contract.Ensures);
         this.VisitEnsuresList(m.Contract.AsyncEnsures);
         this.VisitEnsuresList(m.Contract.ModelEnsures);
     }
 }
コード例 #13
0
        /// <summary>
        /// actualReturn type is null if Task is not generic, otherwise ,the Task result type.
        /// </summary>
        public static bool Contains(Node node, ContractNodes contractNodes, Method currentMethod,
            TypeNode actualReturnType)
        {
            var v = new AsyncReturnValueQuery(contractNodes, currentMethod, actualReturnType);

            v.Visit(node);

            return v.foundReturnValueTaskResult;
        }
コード例 #14
0
        // Requires:
        //  statement.Expression is MethodCall
        //  statement.Expression.Callee is MemberBinding
        //  statement.Expression.Callee.BoundMember is Method
        //  statement.Expression.Callee.BoundMember == "Requires" or "Ensures"
        //
        //  inline  <==> replacementMethod == null
        //  replacementMethod != null
        //           ==> replacementMethod.ReturnType == methodToReplace.ReturnType
        //               && replacementMethod.Parameters.Count == 1
        //               && methodToReplace.Parameters.Count == 1
        //               && replacementMethod.Parameters[0].Type == methodToReplace.Parameters[0].Type
        //
        private static Statement RewriteContractCall(
            ExpressionStatement statement,
            Method /*!*/ methodToReplace,
            Method /*?*/ replacementMethod,
            Literal /*?*/ sourceTextToUseAsSecondArg)
        {
            Contract.Requires(statement != null);

            MethodCall call = statement.Expression as MethodCall;

            if (call == null || call.Callee == null)
            {
                return statement;
            }

            MemberBinding mb = call.Callee as MemberBinding;
            if (mb == null)
            {
                return statement;
            }

            Method m = mb.BoundMember as Method;
            if (m == null)
            {
                return statement;
            }

            if (m != methodToReplace)
            {
                return statement;
            }

            mb.BoundMember = replacementMethod;

            if (call.Operands.Count == 3)
            {
                // then the invariant was found in a reference assembly
                // it already has all of its arguments
                return statement;
            }

            if (call.Operands.Count == 1)
            {
                call.Operands.Add(Literal.Null);
            }

            Literal extraArg = sourceTextToUseAsSecondArg;
            if (extraArg == null)
            {
                extraArg = Literal.Null;
                //extraArg = new Literal("No other information available", SystemTypes.String);
            }

            call.Operands.Add(extraArg);

            return statement;
        }
コード例 #15
0
 private CurrentState(Method method, CurrentState oldState)
 {
     this.Assembly = oldState.Assembly;
     this.assemblySuppressed = oldState.assemblySuppressed;
     this.Type = oldState.Type;
     this.typeSuppressed = oldState.typeSuppressed;
     this.Method = method;
     this.methodSuppressed = null;
 }
コード例 #16
0
        public override Method VisitMethod(Method method)
        {
            Method re = base.VisitMethod(method);

            System.Compiler.TypeNode sigTmp = re.ReturnType;
            if(sigTmp.TypeCode!=TypeCode.Empty)
                signatureType = sigTmp;

            return re;
        }
コード例 #17
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="writer"></param>
        /// <param name="type">the current type being extended</param>
        /// <param name="extensionMethodTemplate">A reference to the extension method. For generic methods, this is a reference to the 
        /// non-specialized method, e.g. System.Linq.Enumerable.Select``2.
        /// </param>
        /// <param name="specialization">When the current type implements or inherits from a specialization of a generic type,
        /// this parameter has a TypeNode for the type used as apecialization of the generic type's first template param. 
        /// </param>
        private void AddExtensionMethod(XmlWriter writer, TypeNode type, Method extensionMethodTemplate, TypeNode specialization)
        {
            // If this is a specialization of a generic method, construct a Method object that describes the specialization
            Method extensionMethodTemplate2 = extensionMethodTemplate;
            if (extensionMethodTemplate2.IsGeneric && (specialization != null))
            {
                // the specialization type is the first of the method's template arguments
                TypeNodeList templateArgs = new TypeNodeList();
                templateArgs.Add(specialization);
                // add any additional template arguments
                for (int i = 1; i < extensionMethodTemplate.TemplateParameters.Count; i++)
                    templateArgs.Add(extensionMethodTemplate.TemplateParameters[i]);
                extensionMethodTemplate2 = extensionMethodTemplate.GetTemplateInstance(type, templateArgs);
            }
            TypeNode extensionMethodTemplateReturnType = extensionMethodTemplate2.ReturnType;
            ParameterList extensionMethodTemplateParameters = extensionMethodTemplate2.Parameters;

            ParameterList extensionMethodParameters = new ParameterList();
            for (int i = 1; i < extensionMethodTemplateParameters.Count; i++)
            {
                Parameter extensionMethodParameter = extensionMethodTemplateParameters[i];
                extensionMethodParameters.Add(extensionMethodParameter);
            }
            Method extensionMethod = new Method(extensionMethodTemplate.DeclaringType, new AttributeList(), extensionMethodTemplate.Name, extensionMethodParameters, extensionMethodTemplate.ReturnType, null);
            extensionMethod.Flags = extensionMethodTemplate.Flags & ~MethodFlags.Static;

            // for generic methods, set the template args and params so the template data is included in the id and the method data
            if (extensionMethodTemplate2.IsGeneric)
            {
                extensionMethod.IsGeneric = true;
                if (specialization != null)
                {
                    // set the template args for the specialized generic method
                    extensionMethod.TemplateArguments = extensionMethodTemplate2.TemplateArguments;
                }
                else
                {
                    // set the generic template params for the non-specialized generic method
                    extensionMethod.TemplateParameters = extensionMethodTemplate2.TemplateParameters;
                }
            }

            // Get the id
            string extensionMethodTemplateId = reflector.ApiNamer.GetMemberName(extensionMethodTemplate);

            // write the element node
            writer.WriteStartElement("element");
            writer.WriteAttributeString("api", extensionMethodTemplateId);
            writer.WriteAttributeString("source", "extension");
            isExtensionMethod = true;
            reflector.WriteMember(extensionMethod);
            isExtensionMethod = false;
            writer.WriteEndElement();
        }
コード例 #18
0
ファイル: CodeFlattener.cs プロジェクト: dbremner/specsharp
 private CodeFlattener(Method method, bool expandAllocations, bool constantFold) 
 {
   this.Method = method;
   this.expandAllocations = expandAllocations;
   this.performConstantFoldingOnBranchConditions = constantFold;
   this.new_stats = new StatementList();
   this.new_blocks = new StatementList();
   this.thisNode = CciHelper.GetThis(method);
   if (thisNode != null && thisNode.Type == null) {
     thisNode.Type = method.DeclaringType;
   }
 }
コード例 #19
0
        public AbbreviationDuplicator(Method sourceMethod, Method targetMethod, ContractNodes contractNodes,
            Method abbreviation, Expression targetObject, ExpressionList actuals)
            : base(targetMethod.DeclaringType.DeclaringModule, sourceMethod, targetMethod, contractNodes, false)
        {
            this.targetObject = targetObject;
            this.abbreviation = abbreviation;
            this.actuals = actuals;

            this.localsInActuals = new TrivialHashtable();

            PopulateLocalsInActuals();
        }
コード例 #20
0
        public CollectOldExpressions(Module module, Method method, ContractNodes contractNodes, Dictionary<TypeNode, Local> closureLocals,
            int localCounterStart)
        {
            this.contractNodes = contractNodes;
            this.prestateValuesOfOldExpressions = new Block(new StatementList());
            this.closureLocals = closureLocals;

            this.stackOfMethods = new List<MethodCall>();
            this.stackOfBoundVariables = new List<Parameter>();

            this.module = module;
            this.currentMethod = method;
            this.counter = localCounterStart;
        }
コード例 #21
0
 public override void VisitMethod(Method method)
 {
     if (method == null) return;
     var savedCurrentMethod = this.CurrentMethod;
     this.CurrentMethod = method;
     try
     {
         base.VisitMethod(method);
     }
     finally
     {
         this.CurrentMethod = savedCurrentMethod;
     }
 }
コード例 #22
0
ファイル: Analyzer.cs プロジェクト: hesam/SketchSharp
        protected override void LanguageSpecificAnalysis(Method method)
        {
            if (!this.CodeIsWellFormed)
                return;
            if (Cci.Analyzer.Debug)
            {
                ControlFlowGraph cfg = GetCFG(method);
                if (cfg != null) cfg.Display(Console.Out);
            }
            if (method.Name.Name.StartsWith("Microsoft.Contracts"))
                return;
            // Weak Purity and Effects Analysis
            if (this.WeakPurityAnalysis && this.WeakPurityAnalyzer != null)
            {
                this.WeakPurityAnalyzer.VisitMethod(method); // computes points-to and effects
                // processes results from VisitMethod: issues errors and potentially prints out detailed info.
                this.WeakPurityAnalyzer.ProcessResultsMethod(method);

                // Admissibility Check 
                PointsToAndWriteEffects ptwe = this.WeakPurityAnalyzer.GetPurityAnalysisWithDefault(method);
                if (method.IsConfined || method.IsStateIndependent)
                {
                    Microsoft.SpecSharp.ReadEffectAdmissibilityChecker reac = new Microsoft.SpecSharp.ReadEffectAdmissibilityChecker(method, typeSystem.ErrorHandler);
                    reac.CheckReadEffectAdmissibility(ptwe.ComputeEffects(ptwe.ReadEffects));
                }

            }

            if (ReentrancyAnalysis)
            {
                if (this.ReentrancyAnalyzer != null)
                {
                    this.ReentrancyAnalyzer.VisitMethod(method);
                }
            }

            if (ObjectExposureAnalysis)
            {
                if (this.ObjectExposureAnalyzer != null)
                {
                    this.ObjectExposureAnalyzer.VisitMethod(method);
                }
            }
        }
コード例 #23
0
        public override Method VisitMethod(Method method)
        {
            if (method == null) return null;

            if (visitedMethods.ContainsKey(method))
                return method;

            base.VisitMethod(method);

            method.SetDelayedContract((m, dummy) =>
            {
                // cleanup contracts for clousot
                this.CleanupRequires(method);
                this.CleanupEnsures(method);
                // this.CleanupBody(method.Body);
            });

            return method;
        }
コード例 #24
0
ファイル: RewriteUtils.cs プロジェクト: nbulp/CodeContracts
        internal static bool Implements(Method concreteMethod, Method abstractMethod)
        {
          Contract.Requires(concreteMethod != null);

            MethodList ml = concreteMethod.ImplicitlyImplementedInterfaceMethods;
            for (int i = 0, n = ml == null ? 0 : ml.Count; i < n; i++)
            {
                Method ifaceMethod = ml[i];
                if (ifaceMethod == null) continue;
                if (ifaceMethod == abstractMethod) return true;
            }
            ml = concreteMethod.ImplementedInterfaceMethods;
            for (int i = 0, n = ml == null ? 0 : ml.Count; i < n; i++)
            {
                Method ifaceMethod = ml[i];
                if (ifaceMethod == null) continue;
                if (ifaceMethod == abstractMethod) return true;
            }
            return false;
        }
コード例 #25
0
ファイル: Reflection.cs プロジェクト: hnlshzx/DotNetOpenAuth
        public static Method[] GetImplementedMethods(Method method) {
            List < Method > list = new List < Method >();

            // Explicit implementations
            MethodList explicitImplementations = method.ImplementedInterfaceMethods;
            if (explicitImplementations != null) {
                for (int i = 0; i < explicitImplementations.Count; i++) {
                    Method explicitImplementation = explicitImplementations[i];
                    list.Add(explicitImplementation);
                }
            }

            // Implicit implementations
            MethodList implicitImplementations = method.ImplicitlyImplementedInterfaceMethods;
            if (implicitImplementations != null) {
                for (int i = 0; i < implicitImplementations.Count; i++) {
                    Method implicitImplementation = implicitImplementations[i];
                    list.Add(implicitImplementation);
                }
            }

            return (list.ToArray());
        }
コード例 #26
0
ファイル: Specializer.cs プロジェクト: julianhaslinger/SHFB
        public override Method VisitMethod(Method method)
        {
            if (method == null) return null;
            Method savedCurrentMethod = this.CurrentMethod;
            TypeNode savedCurrentType = this.CurrentType;
            this.CurrentMethod = method;
            this.CurrentType = method.DeclaringType;
            method.ThisParameter = (This)this.VisitThis(method.ThisParameter);
            method.Attributes = this.VisitAttributeList(method.Attributes);
            method.ReturnAttributes = this.VisitAttributeList(method.ReturnAttributes);
            method.SecurityAttributes = this.VisitSecurityAttributeList(method.SecurityAttributes);
            method.ReturnType = this.VisitTypeReference(method.ReturnType);
            method.ImplementedTypes = this.VisitTypeReferenceList(method.ImplementedTypes);
            method.Parameters = this.VisitParameterList(method.Parameters);

            if(TargetPlatform.UseGenerics && this.args != method.TemplateArguments)
            {
                method.TemplateArguments = this.VisitTypeReferenceList(method.TemplateArguments);
                method.TemplateParameters = this.VisitTypeParameterList(method.TemplateParameters);
            }

            method.ImplementedInterfaceMethods = this.VisitMethodList(method.ImplementedInterfaceMethods);
            this.CurrentMethod = savedCurrentMethod;
            this.CurrentType = savedCurrentType;
            return method;
        }
コード例 #27
0
        public override void VisitMethod(Method method)
        {
            if (method == null) return;
            
            // closures used from methods are visited from the method from which they are referenced
            if (HelperMethods.IsCompilerGenerated(method)) return;

            var savedState = this.currentState;
            try
            {
                this.currentState = savedState.Derive(method);
                if (this.contractNodes.IsObjectInvariantMethod(method))
                {
                    return;
                }

                // Check Abbreviators

                if (ContractNodes.IsAbbreviatorMethod(method))
                {
                    if (method.IsVirtual)
                    {
                        this.HandleError(
                            new Error(1064,
                                "Contract abbreviator method '" + method.FullName +
                                "' cannot be virtual or implement an interface method.'",
                                HelperMethods.SourceContextOfMethod(method)));
                    }

                    if (!HelperMethods.IsVoidType(method.ReturnType))
                    {
                        this.HandleError(
                            new Error(1060,
                                "Contract abbreviator method '" + method.FullName + "' must have void return type.'",
                                HelperMethods.SourceContextOfMethod(method)));
                    }

                    if (method.Contract != null)
                    {
#if false
            if (IsNonTrivial(method.Contract.ContractInitializer))
            {
              this.HandleError(new Error(1061, "Contract abbreviator validator method '" + method.FullName + "' may not use closures.'",
                HelperMethods.SourceContextOfMethod(method)));
            }
#endif
                        if (method.Contract.HasLegacyValidations)
                        {
                            this.HandleError(
                                new Error(1062,
                                    "Contract abbreviator '" + method.FullName +
                                    "' cannot contain if-then-throw contracts or validator calls. Only regular contracts and abbreviator calls are allowed.",
                                    HelperMethods.SourceContextOfMethod(method)));
                        }

                        if (method.Contract.EnsuresCount + method.Contract.RequiresCount == 0)
                        {
                            this.HandleError(
                                new Warning(1063, "No contracts recognized in contract abbreviator '" + method.FullName + "'.",
                                    HelperMethods.SourceContextOfMethod(method)));
                        }
                    }
                    else
                    {
                        // no contracts
                        this.HandleError(
                            new Warning(1063, "No contracts recognized in contract abbreviator '" + method.FullName + "'.",
                                HelperMethods.SourceContextOfMethod(method)));
                    }

                    // abbreviator code must be completely visible to all callers as it is effectively inlined there.
                    this.visibilityChecker.CheckRequires(method.Contract);
                    this.visibilityChecker.CheckAbbreviatorEnsures(method.Contract);

                    return; // no further checks as we check the rest in use-site methods.
                }

                // Check Contracts contents and visibility

                this.CheckMethodContract(method.Contract);

                // Check purity

                this.purityChecker.Check(method);

                // Check Method Body

                this.methodBodyChecker.Check(method);

                SourceContext sourceContext = HelperMethods.SourceContextOfMethod(method);
                
                Method firstRootMethod = null;

                var methodDeclaringType = method.DeclaringType;

                Contract.Assume(methodDeclaringType != null);
                
                TypeNode classForWhichThisIsContractMethod = HelperMethods.IsContractTypeForSomeOtherType(methodDeclaringType, this.contractNodes);

                foreach (var rootMethod in RootMethodsForRequires(method))
                {
                    Contract.Assume(rootMethod != null);

                    if (classForWhichThisIsContractMethod != null)
                    {
                        if (method.Contract == null) continue;

                        if (rootMethod.DeclaringType != classForWhichThisIsContractMethod)
                        {
                            this.HandleError(
                                new Warning(1076,
                                    string.Format(
                                        "Contract class {2} cannot define contract for method {0} as its original definition is not in type {1}. Define the contract on type {3} instead.",
                                        rootMethod.FullName, classForWhichThisIsContractMethod, methodDeclaringType.FullName,
                                        rootMethod.DeclaringType), 
                                    sourceContext));

                            continue;
                        }

                        if (!rootMethod.IsAbstract)
                        {
                            this.HandleError(
                                new Error(1077,
                                    string.Format(
                                        "Contract class {1} cannot define contract for non-abstract method {0}. Define the contract on {0} instead.",
                                        rootMethod.FullName, methodDeclaringType.FullName), 
                                    sourceContext));

                            continue;
                        }

                        // contract class methods can only override/implement the methods of their original type
                        continue;
                    }

                    if (!allowPreconditionsInOverrides)
                    {
                        // Overrides cannot add preconditions unless this is "the" contract method for an abstract method

                        if (method.Contract != null && method.Contract.Requires != null)
                        {
                            foreach (RequiresPlain req in method.Contract.Requires)
                            {
                                if (req == null) continue;

                                if (!this.explicitUserValidations || !req.IsFromValidation)
                                {
                                    SourceContext sc = req.SourceContext;
                                    if (rootMethod.DeclaringType is Interface)
                                    {
                                        this.HandleError(
                                            new Warning(1033,
                                                string.Format( "Method '{0}' implements interface method '{1}', thus cannot add Requires.", method.FullName, rootMethod.FullName), 
                                                sc));
                                    }
                                    else
                                    {
                                        this.HandleError(
                                            new Warning(1032,
                                                string.Format("Method '{0}' overrides '{1}', thus cannot add Requires.", method.FullName, rootMethod.FullName), 
                                                sc));
                                    }

                                    return; // only one error per method
                                }
                            }
                        }

                        // Multiple root methods with contracts

                        // check that none of them have contracts
                        if (firstRootMethod == null)
                        {
                            firstRootMethod = rootMethod;
                        }
                        else
                        {
                            bool someContracts = HasPlainRequires(GetMethodWithContractFor(rootMethod)) ||
                                                 HasPlainRequires(GetMethodWithContractFor(firstRootMethod));
                            if (someContracts)
                            {
                                // found 2 that are in conflict and at least one of them has contracts
                                this.HandleError(new Warning(1035,
                                    String.Format(
                                        "Method '{0}' cannot implement/override two methods '{1}' and '{2}', where one has Requires.",
                                        method.FullName, firstRootMethod.FullName, rootMethod.FullName), sourceContext));

                                return; // only one error per method
                            }
                        }
                    }

                    // if (classForWhichThisIsContractMethod != null) continue; // skip rest of checks in this iteration

                    // Check that validations are present if necessary

                    if (this.explicitUserValidations && !HasValidations(method.Contract))
                    {
                        var rootMethodContract = GetMethodWithContractFor(rootMethod).Contract;
                        if (rootMethodContract != null)
                        {
                            for (int i = 0; i < rootMethodContract.RequiresCount; i++)
                            {
                                var req = (RequiresPlain) rootMethodContract.Requires[i];
                                if (req == null) continue;

                                if (!req.IsWithException) continue;
                                
                                var operation = (rootMethod.DeclaringType is Interface) ? "implements" : "overrides";
                                
                                if (req.SourceConditionText != null && req.ExceptionType.Name != null)
                                {
                                    this.HandleError(new Warning(1055,
                                        String.Format(
                                            "Method '{0}' should contain custom argument validation for 'Requires<{3}>({2})' as it {4} '{1}' which suggests it does. If you don't want to use custom argument validation in this assembly, change the assembly mode to 'Standard Contract Requires'.",
                                            method.FullName,
                                            rootMethod.FullName,
                                            req.SourceConditionText,
                                            req.ExceptionType.Name.Name,
                                            operation),
                                        sourceContext));
                                }
                                else
                                {
                                    this.HandleError(new Warning(1055,
                                        String.Format(
                                            "Method '{0}' should contain custom argument validation as it {2} '{1}' which suggests it does. If you don't want to use custom argument validation in this assembly, change the assembly mode to 'Standard Contract Requires'.",
                                            method.FullName,
                                            rootMethod.FullName,
                                            operation),
                                        sourceContext));

                                    return; // avoid dups
                                }
                            }
                        }
                    }
                }

                // Check that OOB types have no legacy requires (can't inherit them anyway, so should be Requires<E>)

                if (classForWhichThisIsContractMethod != null)
                {
                    if (HasValidations(method.Contract))
                    {
                        this.HandleError(new Error(1078,
                            string.Format(
                                "Method '{0}' annotating type '{1}' should use Requires<E> instead of custom validation.",
                                method.FullName,
                                classForWhichThisIsContractMethod.FullName),
                            sourceContext));
                    }

                    // skip rest of checks
                    return;
                }

                // Explicit parameter validations should not use Requires<E>

                if (this.explicitUserValidations && method.Contract != null)
                {
                    for (int i = 0; i < method.Contract.RequiresCount; i++)
                    {
                        var req = (RequiresPlain) method.Contract.Requires[i];
                        if (req == null) continue;

                        if (req.IsFromValidation) continue;
                        
                        if (!req.IsWithException) continue;
                        
                        // found Requires<E>
                        this.HandleError(new Error(1058,
                            String.Format(
                                "Method '{0}' should not have Requires<E> contract when assembly mode is set to 'Custom Parameter Validation'. Either change it to a legacy if-then-throw validation or change the assembly mode to 'Standard Contract Requires'.",
                                method.FullName), req.SourceContext));
                        
                        return; // avoid duplicate errors.
                    }
                }

                // non-user validation assembly

                if (!this.explicitUserValidations && HasValidations(method.Contract))
                {
                    if (firstRootMethod != null)
                    {
                        this.HandleError(new Warning(1056,
                            String.Format(
                                "Method '{0}' has custom parameter validation but assembly mode is not set to support this. It will be ignored (but base method contract may be inherited).",
                                method.FullName), sourceContext));
                    }
                    else
                    {
                        this.HandleError(new Warning(1057,
                            String.Format(
                                "Method '{0}' has custom parameter validation but assembly mode is not set to support this. It will be treated as Requires<E>.",
                                method.FullName), sourceContext));
                    }
                }

                // Check Validators

                if (ContractNodes.IsValidatorMethod(method))
                {
                    if (method.IsVirtual)
                    {
                        this.HandleError(new Error(1059,
                            "Contract argument validator method '" + method.FullName +
                            "' cannot be virtual or implement an interface method.'",
                            HelperMethods.SourceContextOfMethod(method)));
                    }

                    if (!HelperMethods.IsVoidType(method.ReturnType))
                    {
                        this.HandleError(new Error(1050,
                            "Contract argument validator method '" + method.FullName + "' must have void return type.'",
                            HelperMethods.SourceContextOfMethod(method)));
                    }

                    if (method.Contract != null)
                    {
#if false
            if (IsNonTrivial(method.Contract.ContractInitializer))
            {
              this.HandleError(new Error(1051, "Contract argument validator method '" + method.FullName + "' may not use closures.'",
                HelperMethods.SourceContextOfMethod(method)));
            }
#endif
                        if (!method.Contract.HasLegacyValidations)
                        {
                            this.HandleError(new Warning(1053,
                                "No validation code recognized in contract argument validator '" + method.FullName +
                                "'.",
                                HelperMethods.SourceContextOfMethod(method)));
                        }

                        if (HasNonValidationContract(method.Contract))
                        {
                            this.HandleError(new Error(1054,
                                "Contract argument validator '" + method.FullName +
                                "' cannot contain ordinary contracts. Only if-then-throw or validator calls are allowed.",
                                HelperMethods.SourceContextOfMethod(method)));
                        }
                    }
                    else
                    {
                        // no validations
                        this.HandleError(new Warning(1053,
                            "No validation code recognized in contract argument validator '" + method.FullName + "'.",
                            HelperMethods.SourceContextOfMethod(method)));
                    }
                }
            }
            finally
            {
                this.currentState = savedState;
            }
        }
コード例 #28
0
 private static bool ImplementsAnyInterfaces(Method rootMethod)
 {
     Contract.Requires(rootMethod != null);
     
     if (rootMethod.ImplementedInterfaceMethods != null && rootMethod.ImplementedInterfaceMethods.Count > 0)
         return true;
     
     if (rootMethod.ImplicitlyImplementedInterfaceMethods != null &&
         rootMethod.ImplicitlyImplementedInterfaceMethods.Count > 0) return true;
     
     return false;
 }
コード例 #29
0
        private IEnumerable<Method> RootMethodsForRequires(Method method)
        {
            Contract.Ensures(Contract.Result<IEnumerable<Method>>() != null);

            Method rootMethod = OverriddenRootMethod(method);
            if (rootMethod != null && !ImplementsAnyInterfaces(rootMethod)) yield return rootMethod;

            if (method.ImplementedInterfaceMethods != null)
            {
                for (int i = 0; i < method.ImplementedInterfaceMethods.Count; i++)
                {
                    var intfMethod = method.ImplementedInterfaceMethods[i];
                    if (intfMethod != null) yield return intfMethod;
                }
            }

            if (method.ShallowImplicitlyImplementedInterfaceMethods != null)
            {
                for (int i = 0; i < method.ShallowImplicitlyImplementedInterfaceMethods.Count; i++)
                {
                    var intfMethod = method.ShallowImplicitlyImplementedInterfaceMethods[i];
                    
                    if (intfMethod != null) yield return intfMethod;
                }
            }
        }
コード例 #30
0
        private static Method GetMethodWithContractFor(Method method)
        {
            Contract.Ensures(Contract.Result<Method>() != null || method == null);

            if (method == null) return null;

            // get rid of specialization
            while (method.Template != null) method = method.Template;

            var declType = method.DeclaringType;
            
            if (declType == null) return method;
            
            if (!declType.IsAbstract) return method; // only abstract types and interfaces can have OOB

            // get rid of instantiations
            while (declType.Template != null)
            {
                declType = declType.Template;
            }

            var al = declType.Attributes;
            // if (al != null)
            {
                for (int i = 0; i < al.Count; i++)
                {
                    var attr = al[i];
                    if (attr == null) continue;

                    if (attr.Type == null) continue;
                    
                    if (attr.Type.Name == null) continue;
                    
                    if (attr.Type.Name.Name != "ContractClassAttribute") continue;

                    if (attr.Expressions == null) return method;
                    
                    Literal lit = attr.Expressions[0] as Literal;
                    
                    if (lit == null) return method; // not found
                    TypeNode t = lit.Value as TypeNode;
                    
                    if (t == null) return method; // not found
                    if (t.Template != null)
                    {
                        t = t.Template;
                    }

                    return HelperMethods.FindMatchingMethod(t, method);
                }
            }

            return method; // not found
        }