public static Document OpenDocument(EditorWorkspace workspace, DocumentId documentId) { if (!workspace.IsDocumentOpen(documentId)) { workspace.OpenDocument(documentId); Debug.Assert(workspace.IsDocumentOpen(documentId), "Could not open document."); } return(workspace.CurrentSolution.GetDocument(documentId)); }
// TODO: refactor this code to share with DoTheWork private string DoTheWorkToInferInvariants() { // We should move this in the UI var selectionStart = this.wpfTextView.Selection.Start.Position.Position; var selectionEnd = this.wpfTextView.Selection.End.Position.Position; if (selectionStart == selectionEnd) { Trace.WriteLine(string.Format("Selection: {0}", selectionStart)); var container = wpfTextView.TextBuffer.AsTextContainer(); //var text = wpfTextView.TextBuffer.CurrentSnapshot.AsText(); EditorWorkspace workspace; EditorWorkspace.TryGetWorkspace(container, out workspace); //var workspaceDiscovery = Helper.GetMefService<IWorkspaceDiscoveryService>(); //var workspace = workspaceDiscovery.GetWorkspace(container); if (workspace != null) { Document doc; DocumentId docId; if (workspace.TryGetDocumentId(container, out docId)) { doc = Helper.OpenDocument(workspace, docId); var syntax = doc.GetSyntaxTree(); var source = syntax.GetText().ToString(); // Generate the new text var newText = GenerateAdornedSource(doc, selectionStart); var newSolution = doc.Project.Solution.WithDocumentText(doc.Id, new StringText(newText)); //var newSolution = doc.Project.Solution.UpdateDocument(doc.Id, new StringText(newText)); var locDocument = newSolution.GetDocument(doc.Id); var newTree = (CompilationUnitSyntax)locDocument.GetSyntaxTree().GetRoot(); if (!newTree.ContainsDiagnostics) { try { Trace.WriteLine(string.Format("Annotated tree for the state:\n{0}", newText)); var clousotConnection = new RoslynToCCICodeModel.ClousotGlue(); var run = clousotConnection.AnalyzeMeAUnit(locDocument, newTree, new System.Threading.CancellationToken(), this.options, new string[] { "-warnscores:false", "-sortwarns:false", "-suggest:!!", "-invariantsuggestmode:true" }, true // we want to filter all the messages but the answer of Clousot ); foreach (var r in run) { Trace.WriteLine(string.Format("{0}: {1}", r.Message, r.outcome)); if (r.IsInvariantAtSuggestion) { return(PrettyFormat(r.Message)); } } } catch (Exception e) { Trace.WriteLine(string.Format("Some exception was thrown inside Clousot...\nDetails:\n{0}", e.ToString())); } } else { Trace.WriteLine("Compilation error from Roslyn"); } } } } else { Trace.WriteLine(string.Format("start/end do not match {0} {1}", selectionStart, selectionEnd)); } return(null); }
private IEnumerable <SearchResult> DoTheWorkToSearchTheCallers(string query) { // We should move this in the UI var selectionStart = this.wpfTextView.Selection.Start.Position.Position; var selectionEnd = this.wpfTextView.Selection.End.Position.Position; var results = new List <SearchResult>(); if (selectionStart == selectionEnd) { Trace.WriteLine(string.Format("Selection: {0}", selectionStart)); var container = wpfTextView.TextBuffer.AsTextContainer(); EditorWorkspace workspace; EditorWorkspace.TryGetWorkspace(container, out workspace); if (workspace != null) { Document doc; DocumentId docId; if (workspace.TryGetDocumentId(container, out docId)) { doc = Helper.OpenDocument(workspace, docId); var span = new Microsoft.CodeAnalysis.Text.TextSpan(selectionStart, 0); var syntaxNode = doc.GetSyntaxTree().GetRoot() as SyntaxNode; if (syntaxNode != null) { var methodFinder = EnclosingMethodFinder.GetMethodSpans(syntaxNode); BaseMethodDeclarationSyntax method; if (methodFinder.TryGetValueContainingSpan(span, out method)) { // Add the precondition var preAsStr = string.Format(CLOUSOT_QUERY_PRECONDITION, query); var pre = SyntaxFactory.ParseStatement(preAsStr + Environment.NewLine + Environment.NewLine); // F: adding two newlines as Roslyn for some reason pretty print the text in a different way, and loses one line at the end of the file var newMethod = method.InsertStatements(pre, ContractKind.Precondition); var newRoot = ((SyntaxNode)doc.GetSyntaxTree().GetRoot()).ReplaceNode(method, newMethod); // Create the new Roslyn environment var newSolution = doc.Project.Solution.WithDocumentText(doc.Id, new StringText(newRoot.GetText().ToString())); //var newSolution = doc.Project.Solution.UpdateDocument(doc.Id, new StringText(newRoot.GetText())); var locDocument = newSolution.GetDocument(doc.Id); var newTree = (CompilationUnitSyntax)locDocument.GetSyntaxTree().GetRoot(); try { Trace.WriteLine(string.Format("Annotated tree for the state:\n{0}", newRoot.GetText())); var run = new RoslynToCCICodeModel.ClousotGlue().AnalyzeMeAUnit(locDocument, newTree, new System.Threading.CancellationToken(), this.options, new string[] { "-warnscores:false", "-sortwarns:false", "-suggest:!!", "-show", "validations" }, false ); foreach (var r in run) { Trace.WriteLine(string.Format("{0}: {1}", r.Message, r.outcome)); if (r.outcome.HasValue && // it is not a suggestion r.startPoint != null && r.Message.Contains("Contract.Requires") && r.Message.Contains(query)) // we should do better than chekcing the string. This is very weak { BaseMethodDeclarationSyntax caller; if (methodFinder.TryGetValueContainingSpan(r.Span, out caller)) { var pair = r.startPoint; results.Add(new SearchResult(pair.Item1, pair.Item2, caller, r.outcome.Value)); } else { Trace.WriteLine("Failed to find the containing method"); } } } } catch (Exception e) { Trace.WriteLine(string.Format("Some exception was thrown inside Clousot...\nDetails:\n{0}", e.ToString())); } } } } } } return(results.Distinct()); }
private ProofOutcome?DoTheWork(string query, IEnumerable <CodeAssumption> assumptions) { // We should move this in the UI var selectionStart = this.wpfTextView.Selection.Start.Position.Position; var selectionEnd = this.wpfTextView.Selection.End.Position.Position; if (selectionStart == selectionEnd) { Trace.WriteLine(string.Format("Selection: {0}", selectionStart)); var container = wpfTextView.TextBuffer.AsTextContainer(); //var text = wpfTextView.TextBuffer.CurrentSnapshot.AsText(); EditorWorkspace workspace; EditorWorkspace.TryGetWorkspace(container, out workspace); //var workspaceDiscovery = Helper.GetMefService<IWorkspaceDiscoveryService>(); //var workspace = workspaceDiscovery.GetWorkspace(container); if (workspace != null) { Document doc; DocumentId docId; if (workspace.TryGetDocumentId(container, out docId)) { doc = Helper.OpenDocument(workspace, docId); var syntax = doc.GetSyntaxTree(); var source = syntax.GetText().ToString(); var newText = GenerateInstrumentedSourceText(query, assumptions, selectionStart, source); var newSolution = doc.Project.Solution.WithDocumentText(doc.Id, new StringText(newText)); //var newSolution = doc.Project.Solution.UpdateDocument(doc.Id, new StringText(newText)); var locDocument = newSolution.GetDocument(doc.Id); var newTree = (Microsoft.CodeAnalysis.CSharp.Syntax.CompilationUnitSyntax)locDocument.GetSyntaxTree().GetRoot(); var adornedSource = GenerateAdornedSource(doc, selectionStart); if (!newTree.ContainsDiagnostics) { try { var clousotConnection = new RoslynToCCICodeModel.ClousotGlue(); var run = clousotConnection.AnalyzeMeAUnit(locDocument, newTree, new System.Threading.CancellationToken(), this.options, new string[] { "-warnscores:false", "-sortwarns:false", "-show:validations", "-show:unreached" }, true // we want to filter all the messages but the answer of Clousot ); foreach (var r in run) { Trace.WriteLine(string.Format("{0}: {1}", r.Message, r.outcome)); // if we have a non-null, then this is the outcome // We can have outcome == null for e.g., suggestions. // In this case we simply ignore them if (r.outcome.HasValue) { return(r.outcome); } } } catch (Exception e) { Trace.WriteLine(string.Format("Some exception was thrown inside Clousot...\nDetails:\n{0}", e.ToString())); } } else { Trace.WriteLine("Compilation error from Roslyn"); } } } } else { Trace.WriteLine(string.Format("start/end do not match {0} {1}", selectionStart, selectionEnd)); } return(null); }