示例#1
0
        /// <summary>
        /// Apply the annotations, optionally remove errorenous annotations
        /// </summary>
        /// <param name="annotations">annotations to be applied</param>
        /// <param name="originalCompilation">compilation to annotate</param>
        /// <param name="project">originalCompilation's project</param>
        /// <param name="check_for_errors">if true, will remove annotations cause errors (according to Roslyn)</param>
        /// <returns>A modified version of originalCompilation with the annotations added</returns>
        private static Compilation ApplyAnnotations(IEnumerable <BaseAnnotation> annotations, Compilation originalCompilation, Project project, bool check_for_errors = true)
        {
            #region CodeContracts
            Contract.Requires(originalCompilation != null);
            Contract.Requires(annotations != null);
            Contract.Ensures(Contract.Result <Compilation>() != null);
            #endregion CodeContracts

            IEnumerable <BaseAnnotation> annotations2, annotations3;
            var newCompilation = originalCompilation;
            newCompilation = InterfaceAnnotationHelpers.CreateOrFindContractsClasses(annotations, project, newCompilation, out annotations2);
            newCompilation = ReadonlyHelpers.ReadonlyPass(annotations2, newCompilation);
            newCompilation = ObjectInvariantHelpers.ObjectInvariantPass(newCompilation, annotations2, out annotations3);
            var syntosugdict = Searcher.GetSyntaxNodeToAnnotationDict(newCompilation, annotations3);
            var syntosyndict = Replacer.PrecomputeReplacementNodes(syntosugdict, newCompilation);
            var comp2        = Replacer.RewriteCompilation(newCompilation, syntosyndict);
            var diagnostics  = comp2.GetDiagnostics().Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error);
            if (diagnostics.Any() && check_for_errors)
            {
                Output.WriteLine("Fix the errors introduced by bad contracts");

                Contract.Assert(annotations3.Count() == annotations.Count());
                var filteredAnnotations = HelperForDiagnostics.FilterBadSuggestions(comp2, annotations3);
                // unresolve interface annotations, we're reverting to the original compilation and forgetting everything
                filteredAnnotations = filteredAnnotations.Select(x => x is ResolvedInterfaceAnnotation ? (x as ResolvedInterfaceAnnotation).OriginalAnnotation : x);
                filteredAnnotations = filteredAnnotations.Select(x => x is ResolvedObjectInvariant ? (x as ResolvedObjectInvariant).OriginalAnnotation : x);
                comp2 = ApplyAnnotations(filteredAnnotations, originalCompilation, project, false);
            }
            return(comp2);
        }
示例#2
0
        public static int DoAnnotate(string[] args)
        {
            #region CodeContracts
            Contract.Requires(args != null);
            Contract.Requires(Contract.ForAll(0, args.Length, i => args[i] != null));
            Contract.Ensures(-1 <= Contract.Result <int>()); // we return 0 on success, -1 on failure
            #endregion CodeContracts

            // 1. parse the command line options
            Options options; String error;
            if (!Options.TryParseOptions(args, out options, out error))
            {
                Options.PrintUsage(error);
                Output.WriteError("Can't parse the options");
                return(-1);
            }

            // 2. Create a compilation using Roslyn
            Task <Compilation> compilationAsync;
            Compilation        compilation;
            MSBuildWorkspace   workspace;
            Project            project;
            if (!RoslynInterface.TryCreateCompilation(options, out compilationAsync, out workspace, out project))
            {
                Output.WriteError("Unable to create compilation");
                return(-1);
            }

            // 3. Read Clousot XML
            CCCheckOutput xml;
            if (!XmlDoc.TryReadXml(options.ClousotXML, out xml))
            {
                Output.WriteError("Unable to read XML");
                return(-1);
            }

            compilation = compilationAsync.Result;

            // 4. Check for diagnostics in the solution
            Output.WritePhase("Checking whether the original project has errors");
            var existingDiagnostics = compilation.GetDiagnostics();
            if (existingDiagnostics.Where(diagnostic => diagnostic.Severity == DiagnosticSeverity.Error).Any())
            {
                Output.WriteWarning("The original project has some errors");
                HelperForDiagnostics.PrintDiagnostics(existingDiagnostics);
            }

            // 5. Annotate
            Output.WritePhase("Reading the Contracts from Clousot");
            var annotations = Parser.GetAnnotationDictionary(xml);

            Output.WritePhase("Applying the annotations to the source code");
            var newcomp = ApplyAnnotations(annotations, compilation, project, true);

            // 6. Pretty print result
            Output.WritePhase("Cleaning up the code");
            newcomp = UsingHelpers.CleanImports(project, newcomp);

            // 7. Write result to disk
            Output.WritePhase("Writing result back to disk");
            newcomp = Writer.WriteChanges(compilation, newcomp, options.Output == OutputOption.inplace);

            //CommentHelpers.WriteCommentsFile(xml, compilation, newcomp, options.GitRoot);

            return(0);
        }