/// <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); }
private void TryMarkSuggestion(SyntaxNode containingmethod, StatementSyntax statementundertest) { Contract.Requires(statementundertest != null); var si = SematicModel.GetDeclaredSymbol(containingmethod) as ISymbol; Contract.Assert(si != null); var dci = si.GetDocumentationCommentId(); //if (dci.Equals(methodname)) foreach (var ann in Suggestions.Where(x => x.MethodName.Equals(dci) && x.Kind != ClousotSuggestion.Kind.ReadonlyField)) { /* the above conditional can lead to false positives * You could theoretically have another method called ...ObjectInvariantMethod * and have Contract.Invariants in it, and have the exact invariant that also generated this * error and we would errorneously delete your invariant too * but that seems a pretty extreme edge case. */ // this web of ifs could be refactored // I'm trying to avoid checking every statement against every suggestion //foreach(var precon in sugs[methodname]) //{ //if (ann.Annotation.Equals(statementundertest.GetText().ToString().Replace(ReviewBot.signature, ""))) //if (ann.Annotation.Equals(statementundertest.GetText().ToString())) if (statementundertest.GetText().ToString().Contains(ann.Annotation.Replace(Constants.String.Signature, ""))) //if (statementundertest.GetText().ToString().Contains(ann.Annotation)) { //sugs[methodname].Remove(precon); //if (ann.Kind == ClousotSuggestion.Kind.ObjectInvariant) { Debugger.Break(); } //RBLogger.Info("Marking bad: {0}", ann); //ann.isBad = true; BadSuggestions.Add(ann); return; } //} } var isObjectInvariant = containingmethod is MethodDeclarationSyntax && ObjectInvariantHelpers.isObjectInvariantMethod((MethodDeclarationSyntax)containingmethod, SematicModel); if (isObjectInvariant) { foreach (var ann in Suggestions.Where(x => x.Kind == ClousotSuggestion.Kind.ObjectInvariant)) { if (ann.Annotation.Equals(statementundertest.GetText().ToString().TrimEnd('\r', '\n'))) { //ann.isBad = true; BadSuggestions.Add(ann); } } //foreach (var precons in sugs.Values) //{ // foreach (var precon in precons) // { // if (precon.Annotation.Equals(statementundertest.GetText().ToString().TrimEnd('\r', '\n'))) // { // precon.isBad = true; // } // } //} } }