/// <summary> /// Given an analyzer and a document to apply it to, run the analyzer /// and gather an array of diagnostics found in it. The returned /// diagnostics are then ordered by location in the source document. /// </summary> /// <param name="analyzer"> /// The analyzer to run on the documents. /// </param> /// <param name="documents"> /// The Documents that the analyzer will be run on. /// </param> /// <param name="atmosphere"> /// The environment. /// </param> /// <returns> /// An array of <c>Diagnostic</c>s that surfaced in the source code, /// sorted by <c>Location</c>. /// </returns> public static IEnumerable <Diagnostic> GetSorted( DiagnosticAnalyzer analyzer, IEnumerable <Document> documents, Atmosphere atmosphere) { var analyzerArray = ImmutableArray.Create(analyzer); var treeSet = documents .Select(d => d.GetSyntaxTreeAsync().Result) .ToHashSet(); var options = new CSharpCompilationOptions( OutputKind.DynamicallyLinkedLibrary); var references = Enumerables.Of( Projects.NewReference <UnusedAttribute>()); var excludeIdSet = atmosphere.ExcludeIds.ToImmutableHashSet(); ImmutableArray <Diagnostic> DiagnosticArrayOf(Project p) { var compilation = p.WithCompilationOptions(options) .AddMetadataReferences(references) .GetCompilationAsync() .Result; if (compilation is null) { throw new CompilationException( $"{p.Language}: not supported"); } var rawDiagnostics = compilation.GetDiagnostics() .Where(d => !excludeIdSet.Contains(d.Id)) .ToImmutableArray(); if (rawDiagnostics.Length > 0) { var m = string.Join(',', rawDiagnostics); throw new CompilationException(m, rawDiagnostics); } var configText = atmosphere.ConfigText; var analyzerOptions = (configText is null) ? null : ConfigText.ToAnalyzerOptions(configText); return(compilation .WithAnalyzers(analyzerArray, analyzerOptions) .GetAnalyzerDiagnosticsAsync() .Result); } bool ValidLocation(Location location) { return(atmosphere.ForceLocationValid || location == Location.None || location.IsInMetadata || treeSet.Contains(location.SourceTree)); } return(documents.Select(d => d.Project) .SelectMany(p => DiagnosticArrayOf(p)) .Where(d => ValidLocation(d.Location)) .OrderBy(d => d.Location.SourceSpan.Start)); }
static IEnumerable <InvocableBaseNodePod> ToPods(SyntaxNode n) { var p = InvocableBaseNodePod.Of(n); return((p is null) ? Enumerable.Empty <InvocableBaseNodePod>() : Enumerables.Of(p)); }
private static void CheckLocal( SemanticModelAnalysisContext context, SemanticModel model) { IEnumerable <ILocalSymbol> FindLocalSymbols(SyntaxToken token) { var first = model.LookupSymbols( token.Span.Start, null, token.ValueText) .OfType <ILocalSymbol>() .FirstOrDefault(); return((!(first is null)) ? Enumerables.Of(first) : Enumerable.Empty <ILocalSymbol>()); } var all = LocalVariables.Symbols(model) .ToArray(); if (!all.Any()) { return; } foreach (var(token, symbol) in all) { var containingSymbol = symbol.ContainingSymbol; var reference = containingSymbol.DeclaringSyntaxReferences .FirstOrDefault(); if (reference is null) { continue; } var node = reference.GetSyntax(); if (node.DescendantNodes() .OfType <IdentifierNameSyntax>() .Any(n => FindLocalSymbols(n.Identifier) .Any(s => s.Equals(symbol)))) { continue; } var diagnostic = Diagnostic.Create( Rule, token.GetLocation(), R.TheLocalVariable, token, R.NeverUsed); context.ReportDiagnostic(diagnostic); } }