public void CheckContractIsOther(string contract, ContractKind kind)
        {
            var root = Syntax.ParseExpression(contract);
              var req = new CodeContractCollector(kind, Categories.SemanticCategories);

              req.Visit(root);

              Assert.IsTrue(req.Labels.Count == 1, "Expected a single contract clause for contract {0}", contract);
              Assert.IsFalse(
            req.Labels[0].Labels.Any(),
            string.Format("Contract '{0}' miscategorized. Label(s): {1}",
              contract,
              string.Join(",", req.Labels[0].Labels)));
        }
        public void CheckContract(string contract, ContractKind kind, Category expected)
        {
            var root = Syntax.ParseExpression(contract);
              var collector = new CodeContractCollector(kind, Categories.SemanticCategories);

              collector.Visit(root);

              Assert.AreEqual(1, collector.Labels.Count, "Expected a single top-level contract clause");

              var labels = collector.Labels[0].Labels.ToList();

              Assert.IsTrue(labels.Count > 0, string.Format("Contract {0} not labeled", contract));
              Assert.AreEqual(1, labels.Count, "Expected a single label for the contract");
              Assert.AreEqual(expected.Name, labels[0], string.Format("Contract {0} miscategorized", contract));
        }
        public void Combined_bounds_check_test()
        {
            // This test fails because the categorization is considering each top-level clause separately
              var root = Syntax.ParseExpression("Contract.Requires(idx >= 0 && idx < array.Length);");
              var req = new CodeContractCollector(ContractKind.Requires, Categories.SemanticCategories);

              req.Visit(root);

              Assert.AreEqual(2, req.Labels.Count(), "Expected categorization for both clauses");

              Assert.AreEqual(1, req.Labels[0].Labels.Count(), "Expected first clause to have a single label");
              Assert.AreEqual(1, req.Labels[1].Labels.Count(), "Expected second clause to have a single label");

              Assert.AreEqual(Categories.BoundsCheck.Name, req.Labels[0].Labels.First());
              Assert.AreEqual(Categories.BoundsCheck.Name, req.Labels[1].Labels.First());
        }
        public static void Main(string[] args)
        {
            if (args.Length != 2)
              {
            ShowHelpMessage();
            return;
              }

              var targetDirectory = args[0];
              var outputDirectory = args[1];

              // Create project records for each of the subdirectories in the target directory.
              var projects = Directory.GetDirectories(targetDirectory);
              var subjects = new List<SubjectProgram>();
              foreach (var path in projects)
              {
            var project = Path.GetFileName(path);
            Log.Info("Added project " + project);
            subjects.Add(new SubjectProgram() { Name = project, Path = path });
              }

              var categories = Categories.SemanticCategories;

              // Delete the old category log files
              foreach (var cat in categories)
              {
             var path = Path.Combine(outputDirectory, CategoryLogName(cat));
             if (File.Exists(path))
             {
               File.Delete(path);
             }
              }

              // Aggregate statistic counters
              var agg = new Dictionary<string, int>();
              var reqCnt = 0;
              var ensCnt = 0;
              var invCnt = 0;

              using (var csvStatsByProject = new StreamWriter(Path.Combine(outputDirectory, SummaryFileName)))
              {
            // Write the header.
            csvStatsByProject.WriteLine(string.Join(",", new[] { " " }.Concat(categories.Select(x => x.Name))));

            using (var uncategorizedContractListing = new StreamWriter(Path.Combine(outputDirectory, UncategorizedContractFileName)))
            {
              foreach (var subject in subjects)
              {
            Log.InfoFormat("Computing counts for project {0}.", subject.Name);

            var req = new CodeContractCollector(ContractKind.Requires, categories);
            var ens = new CodeContractCollector(ContractKind.Ensures, categories);
            var obj = new CodeContractCollector(ContractKind.Invariant, categories);
            var all = new CodeContractCollector(
                      ContractKind.Invariant | ContractKind.Ensures | ContractKind.Requires,
                      categories);

            ProcessDirectory(subject.Path, path =>
            {
              try
              {
                if (path.EndsWith(".cs")) VisitFile(path, new[] { req, ens, obj, all });
                else return;
              }
              catch (Exception ex)
              {
                Log.Warn("Error processing file " + path, ex);
              }
            });

            using (var csv = File.CreateText(Path.Combine(outputDirectory, subject.Name + ".stats")))
            {
              var projRow = new List<string>();
              projRow.Add(subject.Name);

              foreach (var cat in categories)
              {
                csv.Write(cat.Name + ",");
                csv.Write(req.Labels.Count(t => t.Labels.Contains(cat.Name)) + ",");
                csv.Write(ens.Labels.Count(t => t.Labels.Contains(cat.Name)) + ",");
                csv.Write(obj.Labels.Count(t => t.Labels.Contains(cat.Name)));

                csv.WriteLine();

                if (!agg.ContainsKey(cat.Name)) agg.Add(cat.Name, 0);
                agg[cat.Name] = agg[cat.Name] + ens.Labels.Count(t => t.Labels.Contains(cat.Name));

                projRow.Add(all.Labels.Count(t => t.Labels.Contains(cat.Name)).ToString());

                // Dump all the contracts for the category
                using (var log = File.AppendText(Path.Combine(outputDirectory, CategoryLogName(cat))))
                {
                  foreach(var clause in all.Labels.Where(t => t.Labels.Contains(cat.Name)))
                  {
                     log.WriteLine(clause.ContractText);
                  }
                }
              }

              csv.Write("Other" + ",");
              csv.Write(req.Labels.Count(t => t.Labels.Count == 0) + ",");
              csv.Write(ens.Labels.Count(t => t.Labels.Count == 0) + ",");
              csv.Write(obj.Labels.Count(t => t.Labels.Count == 0));
              csv.WriteLine();

              reqCnt += req.Labels.Count;
              ensCnt += ens.Labels.Count;
              invCnt += obj.Labels.Count;

              projRow.Add(all.Labels.Count(t => t.Labels.Count == 0).ToString());

              if (!agg.ContainsKey("Other")) agg.Add("Other", 0);
              agg["Other"] = agg["Other"] + ens.Labels.Count(t => t.Labels.Count == 0);

              csvStatsByProject.WriteLine(string.Join(",", projRow));
            }

            // Print uncatagorized contracts
            foreach (var u in all.Labels.Where(c => c.Labels.Count == 0))
            {
              uncategorizedContractListing.WriteLine(u.ContractText);
              Log.DebugFormat("[Project {0}] No category for contract: {1}", subject.Name, u.ContractText);
            }
              }
            }
              }

              // Dump out aggregate counts
              foreach (var category in agg)
              {
            Console.WriteLine(category.Key + ": " + category.Value);
              }
        }
Example #5
0
        public static void Main(string[] args)
        {
            if (args.Length != 2)
            {
                ShowHelpMessage();
                return;
            }

            var targetDirectory = args[0];
            var outputDirectory = args[1];

            // Create project records for each of the subdirectories in the target directory.
            var projects = Directory.GetDirectories(targetDirectory);
            var subjects = new List <SubjectProgram>();

            foreach (var path in projects)
            {
                var project = Path.GetFileName(path);
                Log.Info("Added project " + project);
                subjects.Add(new SubjectProgram()
                {
                    Name = project, Path = path
                });
            }

            var categories = Categories.SemanticCategories;

            // Delete the old category log files
            foreach (var cat in categories)
            {
                var path = Path.Combine(outputDirectory, CategoryLogName(cat));
                if (File.Exists(path))
                {
                    File.Delete(path);
                }
            }

            // Aggregate statistic counters
            var agg    = new Dictionary <string, int>();
            var reqCnt = 0;
            var ensCnt = 0;
            var invCnt = 0;

            using (var csvStatsByProject = new StreamWriter(Path.Combine(outputDirectory, SummaryFileName)))
            {
                // Write the header.
                csvStatsByProject.WriteLine(string.Join(",", new[] { " " }.Concat(categories.Select(x => x.Name))));

                using (var uncategorizedContractListing = new StreamWriter(Path.Combine(outputDirectory, UncategorizedContractFileName)))
                {
                    foreach (var subject in subjects)
                    {
                        Log.InfoFormat("Computing counts for project {0}.", subject.Name);

                        var req = new CodeContractCollector(ContractKind.Requires, categories);
                        var ens = new CodeContractCollector(ContractKind.Ensures, categories);
                        var obj = new CodeContractCollector(ContractKind.Invariant, categories);
                        var all = new CodeContractCollector(
                            ContractKind.Invariant | ContractKind.Ensures | ContractKind.Requires,
                            categories);

                        ProcessDirectory(subject.Path, path =>
                        {
                            try
                            {
                                if (path.EndsWith(".cs"))
                                {
                                    VisitFile(path, new[] { req, ens, obj, all });
                                }
                                else
                                {
                                    return;
                                }
                            }
                            catch (Exception ex)
                            {
                                Log.Warn("Error processing file " + path, ex);
                            }
                        });

                        using (var csv = File.CreateText(Path.Combine(outputDirectory, subject.Name + ".stats")))
                        {
                            var projRow = new List <string>();
                            projRow.Add(subject.Name);

                            foreach (var cat in categories)
                            {
                                csv.Write(cat.Name + ",");
                                csv.Write(req.Labels.Count(t => t.Labels.Contains(cat.Name)) + ",");
                                csv.Write(ens.Labels.Count(t => t.Labels.Contains(cat.Name)) + ",");
                                csv.Write(obj.Labels.Count(t => t.Labels.Contains(cat.Name)));

                                csv.WriteLine();

                                if (!agg.ContainsKey(cat.Name))
                                {
                                    agg.Add(cat.Name, 0);
                                }
                                agg[cat.Name] = agg[cat.Name] + ens.Labels.Count(t => t.Labels.Contains(cat.Name));

                                projRow.Add(all.Labels.Count(t => t.Labels.Contains(cat.Name)).ToString());

                                // Dump all the contracts for the category
                                using (var log = File.AppendText(Path.Combine(outputDirectory, CategoryLogName(cat))))
                                {
                                    foreach (var clause in all.Labels.Where(t => t.Labels.Contains(cat.Name)))
                                    {
                                        log.WriteLine(clause.ContractText);
                                    }
                                }
                            }

                            csv.Write("Other" + ",");
                            csv.Write(req.Labels.Count(t => t.Labels.Count == 0) + ",");
                            csv.Write(ens.Labels.Count(t => t.Labels.Count == 0) + ",");
                            csv.Write(obj.Labels.Count(t => t.Labels.Count == 0));
                            csv.WriteLine();

                            reqCnt += req.Labels.Count;
                            ensCnt += ens.Labels.Count;
                            invCnt += obj.Labels.Count;

                            projRow.Add(all.Labels.Count(t => t.Labels.Count == 0).ToString());

                            if (!agg.ContainsKey("Other"))
                            {
                                agg.Add("Other", 0);
                            }
                            agg["Other"] = agg["Other"] + ens.Labels.Count(t => t.Labels.Count == 0);

                            csvStatsByProject.WriteLine(string.Join(",", projRow));
                        }

                        // Print uncatagorized contracts
                        foreach (var u in all.Labels.Where(c => c.Labels.Count == 0))
                        {
                            uncategorizedContractListing.WriteLine(u.ContractText);
                            Log.DebugFormat("[Project {0}] No category for contract: {1}", subject.Name, u.ContractText);
                        }
                    }
                }
            }

            // Dump out aggregate counts
            foreach (var category in agg)
            {
                Console.WriteLine(category.Key + ": " + category.Value);
            }
        }
        public void Top_level_enumerable_clauses_tests()
        {
            var root = Syntax.ParseExpression("Contract.Requires(Contract.ForAll(xs, x => x >= 0 && x < array.Length));");
              var req = new CodeContractCollector(ContractKind.Requires, Categories.SemanticCategories);

              req.Visit(root);

              Assert.AreEqual(2, req.Labels.Count(), "Expected categorization for both top-level clauses");

              Assert.AreEqual(1, req.Labels[0].Labels.Count(), "Expected first clause to have a single label");
              Assert.AreEqual(1, req.Labels[1].Labels.Count(), "Expected second clause to have a single label");
        }
        public void Top_level_cojunct_and_enumerable_clauses_tests()
        {
            var root = Syntax.ParseExpression("Contract.Requires(y != null && Contract.ForAll(xs, x => x >= 0 && x < array.Length));");
              var req = new CodeContractCollector(ContractKind.Requires, Categories.SemanticCategories);

              req.Visit(root);

              Assert.AreEqual(3, req.Labels.Count(), "Expected categorization for both top-level clauses");
        }
        public void Top_level_clause_tests()
        {
            var root = Syntax.ParseExpression("Contract.Requires(x > 5 && y > 1);");
              var req = new CodeContractCollector(ContractKind.Requires, Categories.SemanticCategories);

              req.Visit(root);

              Assert.AreEqual(2, req.Labels.Count(), "Expected categorization for both clauses");

              Assert.AreEqual(1, req.Labels[0].Labels.Count(), "Expected first clause to have a single label");
              Assert.AreEqual(1, req.Labels[1].Labels.Count(), "Expected second clause to have a single label");
        }
        public void Three_clause_tests()
        {
            var root = Syntax.ParseExpression("Contract.Requires(x != null && (y != null && (z != null)));");
              var req = new CodeContractCollector(ContractKind.Requires, Categories.SemanticCategories);

              req.Visit(root);

              Assert.AreEqual(3, req.Labels.Count(), "Expected categorization for all three clauses");
        }
        public void Invalid_contract_tests()
        {
            var root = Syntax.ParseExpression("Contract.Requires(false);");
              var req = new CodeContractCollector(ContractKind.Requires, Categories.SemanticCategories);

              req.Visit(root);

              Assert.AreEqual(0, req.Labels.Count, "Invalid requires contract should be skipped");
        }