public async System.Threading.Tasks.Task<IEnumerable<CodeAction>> GetRefactoringsAsync(Document document, TextSpan textSpan, CancellationToken cancellationToken) { if (textSpan.IsEmpty) { return null; } if (String.IsNullOrWhiteSpace(document.GetText().GetSubText(textSpan).ToString())) { return null; } var tree = (SyntaxTree)document.GetSyntaxTree(cancellationToken); var diagnostics = tree.GetDiagnostics(cancellationToken); if (diagnostics.Any(d => d.Severity == DiagnosticSeverity.Error || d.IsWarningAsError)) return null; var linespan = tree.GetLocation(textSpan).GetLineSpan(false); if (linespan.EndLinePosition.Line <= linespan.StartLinePosition.Line) return null; // single line var semanticModel = (SemanticModel)document.GetSemanticModel(cancellationToken); var sdiag = semanticModel.GetDiagnostics(cancellationToken); if (sdiag == null) return null; if (sdiag.Any(d => d.Severity == DiagnosticSeverity.Error || d.IsWarningAsError)) return null; var methodExtractor = new MethodExtractor(semanticModel, document, textSpan, this.options); var newDocument = methodExtractor.GetRefactoredDocument(cancellationToken); if (newDocument == null) return null; var action = new ClousotExtractMethodAction(newDocument); return new List<CodeAction>{ action }; }
public CodeRefactoring GetRefactoring(Microsoft.CodeAnalysis.Document document, TextSpan textSpan, CancellationToken cancellationToken) { var tree = (SyntaxTree)document.GetSyntaxTree(cancellationToken); var semanticModel = (SemanticModel)document.GetSemanticModel(cancellationToken); var methodExtractor = new MethodExtractor(semanticModel, document, textSpan, this.options); var newDocument = methodExtractor.GetRefactoredDocument(cancellationToken); if (newDocument == null) { return(null); } var action = new ClousotExtractMethodAction(newDocument); return(new CodeRefactoring(new[] { action })); }
public CodeActionEdit GetEdit(CancellationToken cancellationToken) { #region Parse the suggested fix var e = SyntaxFactory.ParseExpression(this.suggestion); if (e.ContainsDiagnostics) { this.description = String.Format("{0}: Parse error on '{1}'", this.description, this.suggestion); return(null); } #endregion #region Find the first node that corresponds to the span of the suggested fix var tree = (SyntaxTree)document.GetSyntaxTree(); var root = tree.GetRoot(); var oldEs = from node in root.DescendantNodes() where node.Span.Equals(this.span) select node; if (oldEs.Count() == 0) { this.description = String.Format("{0}: Couldn't find node with expected span", this.description); return(null); } var oldE = oldEs.First(); #endregion #region Create transform and return it SyntaxNode newRoot = null; // REVIEW: Is there a better way to know if the new expression can replace the old one? try { newRoot = root.ReplaceNode(oldE, e); } catch { this.description = String.Format("{0}: Parsed suggestion '{1}' doesn't agree with found node type", this.description, this.suggestion); return(null); } if (newRoot == null) { return(null); } return(new CodeActionEdit(this.document.WithSyntaxRoot(newRoot))); //return editFactory.CreateTreeTransformEdit(this.document.Project.Solution, tree, newRoot); #endregion }
public CodeActionEdit GetEdit(CancellationToken cancellationToken) { // create the new method var stmt = SyntaxFactory.ParseStatement(this.suggestion + "\r\n"); // need the newline or else the injected statement doesn't go on its own line! var newMethod = this.oldNode.InsertStatements(stmt, this.kind); // Nothing has changed, so there is nothing to suggest if (newMethod == this.oldNode) { return(null); } // update the document var syntaxTree = (SyntaxTree)document.GetSyntaxTree(cancellationToken); var newRoot = syntaxTree.GetRoot().ReplaceNode(this.oldNode, Formatter.Annotation.AddAnnotationTo(newMethod)); // return the update return(new CodeActionEdit(this.document.WithSyntaxRoot(newRoot))); }
public async Task<System.Collections.Generic.IEnumerable<Diagnostic>> GetSemanticDiagnosticsAsync(Document document, TextSpan span, CancellationToken cancellationToken) { var diagnostics = new List<Diagnostic>(); var model = await document.GetSemanticModelAsync(cancellationToken); var root = await document.GetSyntaxRootAsync(cancellationToken); CompilationUnitSyntax compilationUnitDeclaration = root as CompilationUnitSyntax; if (compilationUnitDeclaration == null) return diagnostics; IEnumerable<ClousotOutput> results = null; try { await Task.Run(() => results = this.connectionToClousot.AnalyzeMeAUnit(document, compilationUnitDeclaration, cancellationToken, options, null)); } catch (OperationCanceledException) { throw; // tell Roslyn } catch (Exception) { // whatever happened, it couldn't have been that important... // just swallow the exception and return nothing return null; } if (results == null) return null; foreach (var r in results) { var location = Location.Create(document.GetSyntaxTree(), r.Span); var d = Diagnostic.Create( id: "Clousot", kind: "Clousot", message: r.Message, severity: r.Kind, location: location ); diagnostics.Add(d); } return diagnostics; }
public IEnumerable <Tuple <string, TextSpan> > AnalyzeMeAUnit( Microsoft.CodeAnalysis.Document document, CompilationUnitSyntax compilationUnitDeclaration, CancellationToken cancellationToken) { var semanticModel = document.GetSemanticModel(cancellationToken); var semanticNode = semanticModel.GetDeclaredSymbol(compilationUnitDeclaration); this.sourceLocationProvider = new SourceLocationProvider(); string exceptionMessage = null; IAssemblyReference ar = null; try { // Constructs a full metadata model for the assembly the semantic model is from var transformer = new NodeVisitor(this.host, semanticModel, sourceLocationProvider); // Constructs the method bodies all of the methods in the compilation unit var tree = document.GetSyntaxTree(cancellationToken); var tree2 = transformer.Visit(compilationUnitDeclaration); ar = tree2 as IAssemblyReference; } catch (ConverterException e) { exceptionMessage = e.Message; } if (exceptionMessage != null) { yield return(Tuple.Create(exceptionMessage, compilationUnitDeclaration.GetFirstToken().Span)); yield break; } var unit = ar; this.host.RegisterUnit(unit.ResolvedUnit); this.cciProvider.MetaDataDecoder.RegisterSourceLocationProvider(unit, sourceLocationProvider); this.methodAnalyzer.AnalyzeAssembly(ar); foreach (var result in this.analysisResults) { yield return(result); } }