public static Dictionary <TextSpan, BaseMethodDeclarationSyntax> GetMethodSpans(CompilationUnitSyntax compilationUnit) { var msf = new MethodSpanFinder(); msf.Visit(compilationUnit); return(msf.span2Method); }
public static Dictionary <TextSpan, BaseMethodDeclarationSyntax> GetMethodSpans(SyntaxNode syntaxNode) { var msf = new MethodSpanFinder(); msf.Visit(syntaxNode); return(msf.span2Method); }
/// <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); } }