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 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); } }
public IEnumerable <Tuple <string, TextSpan> > AnalyzeMeAMethod( Microsoft.CodeAnalysis.Document document, MethodDeclarationSyntax methodDeclaration, CancellationToken cancellationToken) { var semanticModel = document.GetSemanticModel(cancellationToken); var semanticNode = semanticModel.GetDeclaredSymbol(methodDeclaration); Microsoft.Cci.IMethodReference cciMethod = null; this.sourceLocationProvider = new SourceLocationProvider(); string exceptionMessage = 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 body for just this one method cciMethod = transformer.Visit(methodDeclaration) as Microsoft.Cci.IMethodReference; } catch (ConverterException e) { exceptionMessage = e.Message; } if (exceptionMessage != null) { yield return(Tuple.Create(exceptionMessage, methodDeclaration.Span)); yield break; } var unit = TypeHelper.GetDefiningUnitReference(cciMethod.ContainingType); this.host.RegisterUnit(unit.ResolvedUnit); this.cciProvider.MetaDataDecoder.RegisterSourceLocationProvider(unit, sourceLocationProvider); this.methodAnalyzer.Analyze(MethodReferenceAdaptor.AdaptorOf(cciMethod)); foreach (var result in this.analysisResults) { yield return(result); } }
/// <summary> /// Checks the <paramref name="compilationUnitDeclaration"/> for syntax and semantic /// errors and returns an empty enumerable if any are found. /// </summary> public IEnumerable <ClousotOutput> AnalyzeMeAUnit( Microsoft.CodeAnalysis.Document document, CompilationUnitSyntax compilationUnitDeclaration, CancellationToken cancellationToken, ClousotOptions options, string[] extraOptions, bool showOnlyAnswersToAskClousot = false ) { if (options == null) { options = new ClousotOptions(); } // Don't do anything if there are syntactic errors. if (compilationUnitDeclaration.ContainsDiagnostics) { yield break; } var semanticModel = document.GetSemanticModel(cancellationToken); // Don't do anything if there are semantic errors. var diagnostics = semanticModel.GetDiagnostics(cancellationToken); if (diagnostics.Any(d => d.Info.Severity == DiagnosticSeverity.Error || d.Info.IsWarningAsError)) { yield break; } this.host = new ClousotGlueHost((document.Project).MetadataReferences); 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; } catch (OperationCanceledException) { // just return nothing yield break; } if (exceptionMessage != null) { yield return(new ClousotOutput(null, exceptionMessage, compilationUnitDeclaration.GetFirstToken().Span, null, (ICodeAction)null, ClousotOutput.ExtraInfo.None)); yield break; } var spanToMethodMap = MethodSpanFinder.GetMethodSpans(compilationUnitDeclaration); lock (this) { // Clousot is single-threaded var cciProvider = Microsoft.Cci.Analysis.CciILCodeProvider.CreateCodeProvider(host); var unit = ar; this.host.RegisterUnit(unit.ResolvedUnit); cciProvider.MetaDataDecoder.RegisterSourceLocationProvider(unit, sourceLocationProvider); var metadataDecoder = cciProvider.MetaDataDecoder; var contractDecoder = cciProvider.ContractDecoder; var defaultargs = new string[] { "-nonnull", "-bounds", "-arithmetic", "-sortwarns:-", //"-arrays", "-cache", //"-suggest=methodensures", "-suggest=propertyensures", "-suggest=objectinvariants", //"-infer=requires", //"-infer=objectinvariants", //"-clearcache", //"-prefrompost" }; var codefixesargs = new string[] { "-nonnull", "-bounds", "-arithmetic", "-suggest=codefixes", "-cache", "-libpaths:\"c:\\program files (x86)\\Microsoft\\Contracts\\Contracts\\.NetFramework\\v4.0\"", //"-suggest=methodensures", "-suggest=objectinvariants", "-infer=objectinvariants", "-suggest=assumes", "-premode=backwards", }; var args = codefixesargs; if (extraOptions != null) { args = args.Concat(extraOptions).ToArray(); } var w = (options == null || String.IsNullOrWhiteSpace(options.WarningLevel)) ? "low" : options.WarningLevel; var warninglevel = String.Format("-warninglevel={0}", w); var x = new string[] { warninglevel, }; args = args.Concat(x).ToArray(); if (options != null) { var otherOptions = options.OtherOptions; if (!String.IsNullOrWhiteSpace(otherOptions)) { var otherOpts = otherOptions.Split(' '); args = args.Concat(otherOpts).ToArray(); } } this.analysisResults = new List <ClousotOutput>(); var output = new RoslynOutput(showOnlyAnswersToAskClousot, this.analysisResults, document, spanToMethodMap, null); var methodAnalyzer = Clousot.GetIndividualMethodAnalyzer(metadataDecoder, contractDecoder, args, output, new[] { this.cacheFactory }); foreach (var path in methodAnalyzer.Options.libPaths) { host.AddLibPath(path); } methodAnalyzer.AnalyzeAssembly(ar); } foreach (var result in this.analysisResults) { yield return(result); } }