コード例 #1
0
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable string
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests</param>
        /// <param name="diagnostics">The Diagnostics to be formatted</param>
        /// <returns>The Diagnostics formatted as a string</returns>
        private static string FormatDiagnostics(DiagnosticAnalyzer?analyzer, params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (var i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine($"// {diagnostics[i]}");

                var analyzerType = analyzer?.GetType();
                if (analyzerType == null)
                {
                    continue;
                }
                var rules = analyzer !.SupportedDiagnostics;

                foreach (var rule in rules)
                {
                    if (rule == null || rule.Id != diagnostics[i].Id)
                    {
                        continue;
                    }
                    var location = diagnostics[i].Location;
                    if (location == Location.None)
                    {
                        builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
                    }
                    else
                    {
                        Assert.True(location.IsInSource,
                                    $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");

                        var fileIsCSharp     = diagnostics[i].Location.SourceTree?.FilePath.EndsWith(".cs") ?? false;
                        var resultMethodName = fileIsCSharp ? "GetCSharpResultAt" : "GetBasicResultAt";
                        var linePosition     = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                        builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
                                             resultMethodName,
                                             linePosition.Line + 1,
                                             linePosition.Character + 1,
                                             analyzerType.Name,
                                             rule.Id);
                    }

                    if (i != diagnostics.Length - 1)
                    {
                        builder.Append(',');
                    }

                    builder.AppendLine();
                    break;
                }
            }
            return(builder.ToString());
        }
コード例 #2
0
        public static void LogAnalyzerCrashCount(DiagnosticAnalyzer analyzer, Exception ex, LogAggregator logAggregator, ProjectId projectId)
        {
            if (logAggregator == null || analyzer == null || ex == null || ex is OperationCanceledException)
            {
                return;
            }

            // TODO: once we create description manager, pass that into here.
            bool telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(null, analyzer, projectId);
            var tuple = ValueTuple.Create(telemetry, analyzer.GetType(), ex.GetType());
            logAggregator.IncreaseCount(tuple);
        }
コード例 #3
0
        public void UpdateAnalyzerTypeCount(DiagnosticAnalyzer analyzer, AnalyzerTelemetryInfo analyzerTelemetryInfo)
        {
            var isTelemetryAllowed = DiagnosticAnalyzerLogger.AllowsTelemetry(analyzer, _analyzerService);

            ImmutableInterlocked.AddOrUpdate(
                ref _analyzerInfoMap,
                analyzer.GetType(),
                addValue: new AnalyzerInfo(analyzer, analyzerTelemetryInfo, isTelemetryAllowed),
                updateValueFactory: (k, ai) =>
            {
                ai.SetAnalyzerTypeCount(analyzerTelemetryInfo);
                return(ai);
            });
        }
コード例 #4
0
            public AnalyzerInfo(DiagnosticAnalyzer analyzer, AnalyzerActions analyzerActions, bool telemetry)
            {
                CLRType   = analyzer.GetType();
                Telemetry = telemetry;

                Counts[0] = analyzerActions.CodeBlockEndActionsCount;
                Counts[1] = analyzerActions.CodeBlockStartActionsCount;
                Counts[2] = analyzerActions.CompilationEndActionsCount;
                Counts[3] = analyzerActions.CompilationStartActionsCount;
                Counts[4] = analyzerActions.SemanticModelActionsCount;
                Counts[5] = analyzerActions.SymbolActionsCount;
                Counts[6] = analyzerActions.SyntaxNodeActionsCount;
                Counts[7] = analyzerActions.SyntaxTreeActionsCount;
            }
コード例 #5
0
            public AnalyzerInfo(DiagnosticAnalyzer analyzer, AnalyzerActions analyzerActions, bool telemetry)
            {
                CLRType = analyzer.GetType();
                Telemetry = telemetry;

                Counts[0] = analyzerActions.CodeBlockEndActionsCount;
                Counts[1] = analyzerActions.CodeBlockStartActionsCount;
                Counts[2] = analyzerActions.CompilationEndActionsCount;
                Counts[3] = analyzerActions.CompilationStartActionsCount;
                Counts[4] = analyzerActions.SemanticModelActionsCount;
                Counts[5] = analyzerActions.SymbolActionsCount;
                Counts[6] = analyzerActions.SyntaxNodeActionsCount;
                Counts[7] = analyzerActions.SyntaxTreeActionsCount;
            }
コード例 #6
0
            public StateSet(string language, DiagnosticAnalyzer analyzer, string errorSourceName)
            {
                _language        = language;
                _analyzer        = analyzer;
                _errorSourceName = errorSourceName;

                var(analyzerId, version) = _analyzer.GetAnalyzerIdAndVersion();
                _analyzerVersion         = version;
                _analyzerTypeData        = AnalyzerTypeData.ForType(_analyzer.GetType());
                Debug.Assert(_analyzerTypeData.StateName == $"{AnalyzerTypeData.UserDiagnosticsPrefixTableName}_{analyzerId}", "Expected persistence information for analyzer instance to be derived from its type alone.");

                _activeFileStates = new ConcurrentDictionary <DocumentId, ActiveFileState>(concurrencyLevel: 2, capacity: 10);
                _projectStates    = new ConcurrentDictionary <ProjectId, ProjectState>(concurrencyLevel: 2, capacity: 1);
            }
コード例 #7
0
        public void UpdateAnalyzerTypeCount(DiagnosticAnalyzer analyzer, ActionCounts analyzerActions, Project projectOpt)
        {
            var telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(_owner, analyzer, projectOpt?.Id);

            ImmutableInterlocked.AddOrUpdate(
                ref _analyzerInfoMap,
                analyzer.GetType(),
                addValue: new AnalyzerInfo(analyzer, analyzerActions, telemetry),
                updateValueFactory: (k, ai) =>
            {
                ai.SetAnalyzerTypeCount(analyzerActions);
                return(ai);
            });
        }
コード例 #8
0
ファイル: Tests.cs プロジェクト: forki/WpfAnalyzers
 public DescriptorInfo(DiagnosticAnalyzer analyzer)
 {
     this.DiagnosticAnalyzer = analyzer;
     this.DocFileName        = Path.Combine(DocumentsDirectory, this.DiagnosticDescriptor.Id + ".md");
     this.CodeFileName       = Directory.EnumerateFiles(
         SolutionDirectory,
         analyzer.GetType().Name + ".cs",
         SearchOption.AllDirectories)
                               .FirstOrDefault();
     this.CodeFileUri = this.CodeFileName != null
         ? @"https://github.com/DotNetAnalyzers/WpfAnalyzers/blob/master/" +
                        this.CodeFileName.Substring(SolutionDirectory.Length).Replace("\\", "/")
         : "missing";
 }
コード例 #9
0
        public void UpdateAnalyzerTypeCount(DiagnosticAnalyzer analyzer, ActionCounts analyzerActions, Project projectOpt)
        {
            var telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(_owner, analyzer, projectOpt?.Id);

            ImmutableInterlocked.AddOrUpdate(
                ref _analyzerInfoMap,
                analyzer.GetType(),
                addValue: new AnalyzerInfo(analyzer, analyzerActions, telemetry),
                updateValueFactory: (k, ai) =>
                {
                    ai.SetAnalyzerTypeCount(analyzerActions);
                    return ai;
                });
        }
コード例 #10
0
        public static void SetParameterValues(DiagnosticAnalyzer parameteredAnalyzer,
                                              AnalyzerOptions options)
        {
            if (ProcessedAnalyzers.ContainsKey(parameteredAnalyzer))
            {
                return;
            }

            var additionalFile = options.AdditionalFiles
                                 .FirstOrDefault(f => ConfigurationFilePathMatchesExpected(f.Path));

            if (additionalFile == null)
            {
                return;
            }

            var filePath   = additionalFile.Path;
            var xml        = XDocument.Load(filePath);
            var parameters = ParseParameters(xml);

            var propertyParameterPairs = parameteredAnalyzer.GetType()
                                         .GetProperties()
                                         .Select(p => new { Property = p, Descriptor = p.GetCustomAttributes <RuleParameterAttribute>().SingleOrDefault() })
                                         .Where(p => p.Descriptor != null);

            foreach (var propertyParameterPair in propertyParameterPairs)
            {
                var parameter = parameters
                                .FirstOrDefault(p => p.RuleId == parameteredAnalyzer.SupportedDiagnostics.Single().Id);

                if (parameter == null)
                {
                    return;
                }

                var parameterValue = parameter.ParameterValues
                                     .FirstOrDefault(pv => pv.ParameterKey == propertyParameterPair.Descriptor.Key);

                if (parameterValue == null)
                {
                    return;
                }

                var value          = parameterValue.ParameterValue;
                var convertedValue = ChangeParameterType(value, propertyParameterPair.Descriptor.Type);
                propertyParameterPair.Property.SetValue(parameteredAnalyzer, convertedValue);
            }

            ProcessedAnalyzers.AddOrUpdate(parameteredAnalyzer, 0, (a, b) => b);
        }
コード例 #11
0
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable string.
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests.</param>
        /// <param name="diagnostics">The Diagnostics to be formatted.</param>
        /// <returns>The Diagnostics formatted as a string.</returns>
        static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (var i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine("// " + diagnostics[i]);

                var analyzerType = analyzer.GetType();
                var rules        = analyzer.SupportedDiagnostics;

                foreach (var rule in rules)
                {
                    if ((rule != null) && (rule.Id == diagnostics[i].Id))
                    {
                        var location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.AppendFormat(CultureInfo.InvariantCulture, "GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
                        }
                        else
                        {
                            Assert.That(location.IsInSource, Is.True, $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");

                            var resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) ? "GetCSharpResultAt" : "GetBasicResultAt";
                            var linePosition     = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.AppendFormat(
                                CultureInfo.InvariantCulture,
                                "{0}({1}, {2}, {3}.{4})",
                                resultMethodName,
                                linePosition.Line + 1,
                                linePosition.Character + 1,
                                analyzerType.Name,
                                rule.Id);
                        }

                        if (i != (diagnostics.Length - 1))
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }

            return(builder.ToString());
        }
コード例 #12
0
        /// <summary>
        ///     Helper method to format a Diagnostic into an easily readable string
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests</param>
        /// <param name="diagnostics">The Diagnostics to be formatted</param>
        /// <returns>The Diagnostics formatted as a string</returns>
        private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            StringBuilder builder = new StringBuilder();

            for (var i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine("// " + diagnostics[i]);

                Type analyzerType = analyzer.GetType();
                ImmutableArray <DiagnosticDescriptor> rules = analyzer.SupportedDiagnostics;

                foreach (DiagnosticDescriptor rule in rules)
                {
                    if (rule != null && rule.Id == diagnostics[i].Id)
                    {
                        Location location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
                        }
                        else
                        {
                            Assert.IsTrue(location.IsInSource,
                                          $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n");

                            string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs")
                                ? "GetCSharpResultAt"
                                : "GetBasicResultAt";
                            LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
                                                 resultMethodName,
                                                 linePosition.Line + 1,
                                                 linePosition.Character + 1,
                                                 analyzerType.Name,
                                                 rule.Id);
                        }

                        if (i != diagnostics.Length - 1)
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }
            return(builder.ToString());
        }
コード例 #13
0
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable string
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests</param>
        /// <param name="diagnostics">The Diagnostics to be formatted</param>
        /// <returns>The Diagnostics formatted as a string</returns>
        private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (int i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine("// " + diagnostics[i].ToString());

                System.Type analyzerType = analyzer.GetType();
                System.Collections.Immutable.ImmutableArray <DiagnosticDescriptor> rules = analyzer.SupportedDiagnostics;

                foreach (DiagnosticDescriptor rule in rules)
                {
                    if (rule != null && rule.Id == diagnostics[i].Id)
                    {
                        Location location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.AppendFormat(CultureInfo.InvariantCulture, "GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
                        }
                        else
                        {
                            Assert.True(location.IsInSource,
                                        "Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata:\r\n" + diagnostics[i]);

                            string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) ? "GetCSharpResultAt" : "GetBasicResultAt";
                            Microsoft.CodeAnalysis.Text.LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.AppendFormat(CultureInfo.InvariantCulture, "{0}({1}, {2}, {3}.{4})",
                                                 resultMethodName,
                                                 linePosition.Line + 1,
                                                 linePosition.Character + 1,
                                                 analyzerType.Name,
                                                 rule.Id);
                        }

                        if (i != diagnostics.Length - 1)
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }
            return(builder.ToString());
        }
コード例 #14
0
ファイル: AnalyzerHelper.cs プロジェクト: elemk0vv/roslyn-1
        public static bool IsCompilerAnalyzer(DiagnosticAnalyzer analyzer)
        {
            // TODO: find better way.
            var typeString = analyzer.GetType().ToString();
            if (typeString == CSharpCompilerAnalyzerTypeName)
            {
                return true;
            }

            if (typeString == VisualBasicCompilerAnalyzerTypeName)
            {
                return true;
            }

            return false;
        }
コード例 #15
0
        static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (var diagnosticIndex = 0; diagnosticIndex < diagnostics.Length; ++diagnosticIndex)
            {
                builder.AppendLine("// " + diagnostics[diagnosticIndex]);

                var analyzerType = analyzer.GetType();
                var descriptors  = analyzer.SupportedDiagnostics;

                foreach (var descriptor in descriptors
                         .Where(descriptor => descriptor?.Id == diagnostics[diagnosticIndex].Id))
                {
                    var location = diagnostics[diagnosticIndex].Location;
                    if (location == Location.None)
                    {
                        builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, descriptor.Id);
                    }
                    else
                    {
                        Assert.IsTrue(
                            location.IsInSource,
                            $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[diagnosticIndex]}\r\n");

                        var position = diagnostics[diagnosticIndex].Location.GetLineSpan().StartLinePosition;

                        builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
                                             "GetResultAt",
                                             position.Line + 1,
                                             position.Character + 1,
                                             analyzerType.Name,
                                             descriptor.Id);
                    }

                    if (diagnosticIndex != diagnostics.Length - 1)
                    {
                        builder.Append(',');
                    }

                    builder.AppendLine();
                    break;
                }
            }

            return(builder.ToString());
        }
コード例 #16
0
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable string.
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests.</param>
        /// <param name="diagnostics">The Diagnostics to be formatted.</param>
        /// <returns>The Diagnostics formatted as a string.</returns>
        private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (int i = 0; i < diagnostics.Length; ++i)
            {
                builder.AppendLine("// " + diagnostics[i].ToString());

                var analyzerType = analyzer.GetType();
                var rules        = analyzer.SupportedDiagnostics;

                foreach (var rule in rules)
                {
                    if (rule != null && rule.Id == diagnostics[i].Id)
                    {
                        var location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.Append(FormattableString.Invariant($"GetGlobalResult({analyzerType.Name}.{rule.Id})"));
                        }
                        else
                        {
                            location.IsInSource.Should()
                            .BeTrue(FormattableString.Invariant(
                                        $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n"));

                            string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs", StringComparison.OrdinalIgnoreCase) ? "GetCSharpResultAt" : "GetBasicResultAt";
                            var    linePosition     = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.Append(
                                FormattableString.Invariant(
                                    $"{resultMethodName}({linePosition.Line + 1}, {linePosition.Character + 1}, {analyzerType.Name}.{rule.Id})"));
                        }

                        if (i != diagnostics.Length - 1)
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }

            return(builder.ToString());
        }
コード例 #17
0
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable string
        /// </summary>
        /// <param name="analyzer">The analyzer that this verifier tests</param>
        /// <param name="diagnostics">The Diagnostics to be formatted</param>
        /// <returns>The Diagnostics formatted as a string</returns>
        private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            StringBuilder builder = new StringBuilder();

            for (int i = 0; i < diagnostics.Length; ++i)
            {
                builder.Append("// ").AppendLine(diagnostics[i].ToString());

                System.Type analyzerType = analyzer.GetType();
                System.Collections.Immutable.ImmutableArray <DiagnosticDescriptor> rules = analyzer.SupportedDiagnostics;

                foreach (DiagnosticDescriptor rule in rules)
                {
                    if (rule != null && rule.Id == diagnostics[i].Id)
                    {
                        Location location = diagnostics[i].Location;
                        if (location == Location.None)
                        {
                            builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id);
                        }
                        else
                        {
                            Check.That(location.IsInSource).IsTrue();

                            string resultMethodName = diagnostics[i].Location.SourceTree.FilePath.EndsWith(".cs") ? "GetCSharpResultAt" : "GetBasicResultAt";
                            Microsoft.CodeAnalysis.Text.LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition;

                            builder.AppendFormat("{0}({1}, {2}, {3}.{4})",
                                                 resultMethodName,
                                                 linePosition.Line + 1,
                                                 linePosition.Character + 1,
                                                 analyzerType.Name,
                                                 rule.Id);
                        }

                        if (i != diagnostics.Length - 1)
                        {
                            builder.Append(',');
                        }

                        builder.AppendLine();
                        break;
                    }
                }
            }
            return(builder.ToString());
        }
コード例 #18
0
        public static bool IsCompilerAnalyzer(DiagnosticAnalyzer analyzer)
        {
            // TODO: find better way.
            var typeString = analyzer.GetType().ToString();

            if (typeString == CSharpCompilerAnalyzerTypeName)
            {
                return(true);
            }

            if (typeString == VisualBasicCompilerAnalyzerTypeName)
            {
                return(true);
            }

            return(false);
        }
コード例 #19
0
    /// <summary>
    ///     Helper method to format a Diagnostic into an easily readable string
    /// </summary>
    /// <param name="analyzer">The analyzer that this verifier tests</param>
    /// <param name="diagnostics">The Diagnostics to be formatted</param>
    /// <returns>The Diagnostics formatted as a string</returns>
    private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
    {
        StringBuilder builder = new();

        foreach (Diagnostic diagnostic in diagnostics)
        {
            builder = builder.Append("// ")
                      .AppendLine(diagnostic.ToString());

            Type analyzerType = analyzer.GetType();
            ImmutableArray <DiagnosticDescriptor> rules = analyzer.SupportedDiagnostics;

            DiagnosticDescriptor?rule = rules.FirstOrDefault(rule => rule.Id == diagnostic.Id);

            if (rule == null)
            {
                continue;
            }

            Location location = diagnostic.Location;

            if (location == Location.None)
            {
                builder = builder.Append(provider: CultureInfo.InvariantCulture, $"GetGlobalResult({analyzerType.Name}.{rule.Id})");
            }
            else
            {
                Assert.True(condition: location.IsInSource, $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostic}\r\n");

                string       resultMethodName = GetResultMethodName(diagnostic);
                LinePosition linePosition     = diagnostic.Location.GetLineSpan()
                                                .StartLinePosition;

                builder = builder.Append(provider: CultureInfo.InvariantCulture,
                                         $"{resultMethodName}({linePosition.Line + 1}, {linePosition.Character + 1}, {analyzerType.Name}.{rule.Id})");
            }

            builder = builder.Append(value: ',')
                      .AppendLine();
        }

        return(builder.ToString()
               .TrimEnd()
               .TrimEnd(',') + Environment.NewLine);
    }
コード例 #20
0
        private static string GetTestCaseFileName(DiagnosticAnalyzer analyzer)
        {
            var typeName = analyzer.GetType().Name;

            return(typeName switch
            {
                "ConfiguringLoggers" => "ConfiguringLoggers_AspNetCore",
                "CookieShouldBeHttpOnly" => "CookieShouldBeHttpOnly_Nancy",
                "CookieShouldBeSecure" => "CookiesShouldBeSecure_Nancy",
                "DoNotHardcodeCredentials" => "DoNotHardcodeCredentials_DefaultValues",
#if NETFRAMEWORK
                "ExecutingSqlQueries" => "ExecutingSqlQueries_Net46",
                "UsingCookies" => "UsingCookies_Net46",
#else
                "ExecutingSqlQueries" => "ExecutingSqlQueries_NetCore",
                "UsingCookies" => "UsingCookies_NetCore",
#endif
                _ => typeName
            });
コード例 #21
0
        private static void VerifyDiagnosticResults(IOrderedEnumerable <Diagnostic> actualResults,
                                                    DiagnosticAnalyzer analyzer,
                                                    params DiagnosticResult[] expectedResults)
        {
            var analyzerName       = analyzer.GetType().Name;
            var actualResultsArray = actualResults.ToArray();

            VerifyCorrectNumberOfDiagnostics(analyzerName, actualResultsArray, expectedResults);

            for (var i = 0; i < expectedResults.Length; i++)
            {
                var actual        = actualResultsArray[i];
                var expected      = expectedResults[i];
                var diagnosticNum = i + 1;

                VerifyLocationOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
                VerifyCategoryOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
                VerifyIdOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
                VerifyTitleOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
                VerifyDescriptionOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
                VerifyMessageOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
                VerifySeverityOfDiagnostic(analyzerName, diagnosticNum, expected, actual);
            }
        }
コード例 #22
0
ファイル: CodeVerifier.cs プロジェクト: joebone/Roslynator
 internal void VerifySupportedDiagnostics(DiagnosticAnalyzer analyzer, Diagnostic diagnostic)
 {
     if (analyzer.SupportedDiagnostics.IndexOf(diagnostic.Descriptor, DiagnosticDescriptorComparer.Id) == -1)
     {
         Assert.True(false, $"Diagnostic \"{diagnostic.Id}\" is not supported by '{analyzer.GetType().Name}'.");
     }
 }
            /// <summary>
            /// Get the unique state name for the given {type, provider} tuple.
            /// Note that this name is used by the underlying persistence stream of the corresponding <see cref="DiagnosticState"/> to Read/Write diagnostic data into the stream.
            /// If any two distinct {type, provider} tuples have the same diagnostic state name, we will end up sharing the persistence stream between them, leading to duplicate/missing/incorrect diagnostic data.
            /// </summary>
            private static ValueTuple<string, VersionStamp> GetUniqueDiagnosticStateNameAndVersion(StateType type, ProviderId providerId, DiagnosticAnalyzer provider)
            {
                Contract.ThrowIfNull(provider);

                // Get the unique ID for given diagnostic analyzer.
                // note that we also put version stamp so that we can detect changed provider
                var providerType = provider.GetType();
                var location = providerType.Assembly.Location;

                return ValueTuple.Create(UserDiagnosticsPrefixTableName + "_" + type.ToString() + "_" + providerType.AssemblyQualifiedName, GetProviderVersion(location));
            }
コード例 #24
0
        private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, List <Diagnostic> diagnostics, Action <Project, DiagnosticAnalyzer, CancellationToken> forceAnalyzeAllDocuments)
        {
            Contract.ThrowIfFalse(_project.SupportsCompilation);

            using (var pooledObject = SharedPools.Default <List <Diagnostic> >().GetPooledObject())
            {
                var localDiagnostics = pooledObject.Object;
                var compilation      = await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);

                DiagnosticAnalyzer clonedAnalyzer = null;

                try
                {
                    // Get all the analyzer actions, including the per-compilation actions.
                    var analyzerExecutor = GetAnalyzerExecutor(compilation, localDiagnostics.Add);
                    var analyzerActions  = await this.GetAnalyzerActionsAsync(analyzer, analyzerExecutor).ConfigureAwait(false);

                    var hasDependentCompilationEndAction = await AnalyzerManager.Instance.GetAnalyzerHasDependentCompilationEndAsync(analyzer, analyzerExecutor).ConfigureAwait(false);

                    if (hasDependentCompilationEndAction && forceAnalyzeAllDocuments != null)
                    {
                        // Analyzer registered a compilation end action and at least one other analyzer action during its compilation start action.
                        // We need to ensure that we have force analyzed all documents in this project for this analyzer before executing the end actions.
                        // Doing so on the original analyzer instance might cause duplicate callbacks into the analyzer.
                        // So we create a new instance of this analyzer and compute compilation diagnostics on that instance.

                        try
                        {
                            clonedAnalyzer = Activator.CreateInstance(analyzer.GetType()) as DiagnosticAnalyzer;
                        }
                        catch
                        {
                            // Unable to created a new analyzer instance, bail out on reporting diagnostics.
                            return;
                        }

                        // Report analyzer exception diagnostics on original analyzer, not the temporary cloned one.
                        analyzerExecutor = GetAnalyzerExecutorForClone(compilation, localDiagnostics.Add, analyzerForExceptionDiagnostics: analyzer);

                        analyzerActions = await this.GetAnalyzerActionsAsync(clonedAnalyzer, analyzerExecutor).ConfigureAwait(false);

                        forceAnalyzeAllDocuments(_project, clonedAnalyzer, _cancellationToken);
                    }

                    // Compilation actions.
                    analyzerExecutor.ExecuteCompilationActions(analyzerActions.CompilationActions);

                    // CompilationEnd actions.
                    analyzerExecutor.ExecuteCompilationActions(analyzerActions.CompilationEndActions);

                    var filteredDiagnostics = CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation);
                    diagnostics.AddRange(filteredDiagnostics);
                }
                finally
                {
                    if (clonedAnalyzer != null)
                    {
                        AnalyzerManager.Instance.ClearAnalyzerState(ImmutableArray.Create(clonedAnalyzer));
                    }
                }
            }
        }
コード例 #25
0
        public static void VerifyNoDiagnostic(
            IEnumerable <string> sources,
            DiagnosticDescriptor descriptor,
            DiagnosticAnalyzer analyzer,
            string language)
        {
            Assert.True(analyzer.Supports(descriptor),
                        $"Diagnostic \"{descriptor.Id}\" is not supported by analyzer \"{analyzer.GetType().Name}\".");

            IEnumerable <Document> documents = WorkspaceFactory.CreateDocuments(sources, language);

            VerifyNoCompilerError(documents);

            Diagnostic[] diagnostics = DiagnosticUtility.GetSortedDiagnostics(documents, analyzer);

            Assert.True(diagnostics.Length == 0 || diagnostics.All(f => !string.Equals(f.Id, descriptor.Id, StringComparison.Ordinal)),
                        $"No diagnostic expected{diagnostics.Where(f => string.Equals(f.Id, descriptor.Id, StringComparison.Ordinal)).ToDebugString()}");
        }
コード例 #26
0
        /// <summary>
        /// The caller is free to provide his own <see cref="FormatDiagnosticsCallback"/>,
        /// however, most likely, the default formatter is sufficient for eighty to ninety
        /// percent of what you want to do.
        /// </summary>
        /// <param name="language"></param>
        /// <param name="analyzer"></param>
        /// <param name="diagnostics"></param>
        /// <returns></returns>
        internal static string DefaultDiagnosticFormatter(string language
                                                          , DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics)
        {
            string FormatDiagnostic(Diagnostic diagnostic)
            {
                var sb = new StringBuilder();

                sb.AppendLine($"// {diagnostic}");

                var analyzerType = analyzer.GetType();
                var rules        = analyzer.SupportedDiagnostics;

                // TODO: TBD: is this just a fancy way of selecting the "single" rule corresponding to the Diagnostic Id?
                foreach (var rule in from r in rules
                         where r != null && r.Id == diagnostic.Id
                         select r)
                {
                    var location = diagnostic.Location;

                    string message;

                    if (location == Location.None)
                    {
                        message = $"Global '{language}' result '{analyzerType.FullName}.{rule.Id}'";
                    }
                    else
                    {
                        // Positively assert when Location IsInMetadata, as contrasted with !IsInSource.
                        if (location.IsInMetadata)
                        {
                            throw new BadFormatterLocationException(
                                      "Verifiers do not currently handle diagnostics"
                                      + $" in metadata locations, diagnostic in metadata: {diagnostic}"
                                      , BadLocation, diagnostic);
                        }

                        //try
                        //{
                        //    Assert.True(location.IsInSource);
                        //}
                        //catch (TrueException)
                        //{
                        //    OutputHelper.WriteLine(
                        //        "Test base does not currently handle diagnostics in metadata locations."
                        //        + $"Diagnostic in metadata: {diagnostic}");
                        //    throw;
                        //}

                        var linePosition = diagnostic.Location.GetLineSpan().StartLinePosition;

                        message = $"'{language}' result at "
                                  + $"line {linePosition.Line + 1} "
                                  + $"column {linePosition.Character + 1}"
                                  + $", rule '{analyzerType.FullName}.{rule.Id}')";
                    }

                    // TODO: TBD: we'll have to watch this, but I suspect we are formatting only a SINGLE rule/diagnostic pair here...
                    sb.AppendLine(message);
                }

                return($"{sb}");
            }

            return(Join(",\r\n", diagnostics.Select(FormatDiagnostic)));
        }
コード例 #27
0
        /// <summary>
        /// Helper method to format a Diagnostic into an easily readable
        /// string.
        /// </summary>
        /// <param name="analyzer">
        /// The analyzer that this verifier tests.
        /// </param>
        /// <param name="atmosphere">
        /// The compilation environment.
        /// </param>
        /// <param name="diagnostics">
        /// The Diagnostics to be formatted.
        /// </param>
        /// <returns>
        /// The Diagnostics formatted as a string.
        /// </returns>
        private static string FormatDiagnostics(
            DiagnosticAnalyzer analyzer,
            Atmosphere atmosphere,
            params Diagnostic[] diagnostics)
        {
            var builder = new StringBuilder();

            for (var i = 0; i < diagnostics.Length; ++i)
            {
                builder.Append("// ")
                .AppendLine(diagnostics[i].ToString());

                var analyzerType = analyzer.GetType();
                var rule         = analyzer.SupportedDiagnostics
                                   .FirstOrDefault(r => !(r is null) &&
                                                   r.Id == diagnostics[i].Id);
                if (rule is null)
                {
                    continue;
                }
                var location = diagnostics[i].Location;
                if (location == Location.None)
                {
                    builder.AppendFormat(
                        CultureInfo.CurrentCulture,
                        "GetGlobalResult({0}.{1})",
                        analyzerType.Name,
                        rule.Id);
                }
                else if (atmosphere.ForceLocationValid)
                {
                    var linePosition = diagnostics[i].Location
                                       .GetLineSpan()
                                       .StartLinePosition;
                    builder.AppendFormat(
                        CultureInfo.CurrentCulture,
                        "GetExternalResult({0}, {1}, {2}.{3})",
                        linePosition.Line + 1,
                        linePosition.Character + 1,
                        analyzerType.Name,
                        rule.Id);
                }
                else
                {
                    AssertFailIfFalse(
                        location.IsInSource,
                        () => "Test base does not currently handle "
                        + "diagnostics in metadata locations. "
                        + "Diagnostic in metadata: "
                        + $"{diagnostics[i]}{NewLine}");

                    var sourceTree = diagnostics[i].Location
                                     .SourceTree;
                    if (sourceTree is null)
                    {
                        throw new NullReferenceException();
                    }
                    var filePath = sourceTree.FilePath;

                    AssertFailIfFalse(
                        filePath.EndsWith(".cs", StringComparison.Ordinal),
                        () => "The file path does not end '.cs': "
                        + $"{filePath}");

                    var resultMethodName = "GetCSharpResultAt";
                    var linePosition     = diagnostics[i].Location
                                           .GetLineSpan()
                                           .StartLinePosition;

                    builder.AppendFormat(
                        CultureInfo.CurrentCulture,
                        "{0}({1}, {2}, {3}.{4})",
                        resultMethodName,
                        linePosition.Line + 1,
                        linePosition.Character + 1,
                        analyzerType.Name,
                        rule.Id);
                }

                if (i != diagnostics.Length - 1)
                {
                    builder.Append(',');
                }
                builder.AppendLine();
            }
            return(builder.ToString());
        }
コード例 #28
0
 public AnalyzerInfo(DiagnosticAnalyzer analyzer, AnalyzerTelemetryInfo analyzerTelemetryInfo, bool telemetry)
 {
     CLRType = analyzer.GetType();
     Telemetry = telemetry;
     SetAnalyzerTypeCount(analyzerTelemetryInfo);
 }
コード例 #29
0
        private async Task GetCompilationDiagnosticsAsync(DiagnosticAnalyzer analyzer, List<Diagnostic> diagnostics, Action<Project, DiagnosticAnalyzer, CancellationToken> forceAnalyzeAllDocuments)
        {
            Contract.ThrowIfFalse(_project.SupportsCompilation);

            using (var pooledObject = SharedPools.Default<List<Diagnostic>>().GetPooledObject())
            {
                var localDiagnostics = pooledObject.Object;
                var compilation = await _project.GetCompilationAsync(_cancellationToken).ConfigureAwait(false);
                DiagnosticAnalyzer clonedAnalyzer = null;

                try
                {
                    // Get all the analyzer actions, including the per-compilation actions.
                    var analyzerExecutor = GetAnalyzerExecutor(compilation, localDiagnostics.Add);
                    var analyzerActions = await this.GetAnalyzerActionsAsync(analyzer, analyzerExecutor).ConfigureAwait(false);
                    var hasDependentCompilationEndAction = await AnalyzerManager.Instance.GetAnalyzerHasDependentCompilationEndAsync(analyzer, analyzerExecutor).ConfigureAwait(false);

                    if (hasDependentCompilationEndAction && forceAnalyzeAllDocuments != null)
                    {
                        // Analyzer registered a compilation end action and at least one other analyzer action during its compilation start action.
                        // We need to ensure that we have force analyzed all documents in this project for this analyzer before executing the end actions.
                        // Doing so on the original analyzer instance might cause duplicate callbacks into the analyzer.
                        // So we create a new instance of this analyzer and compute compilation diagnostics on that instance.

                        try
                        {
                            clonedAnalyzer = Activator.CreateInstance(analyzer.GetType()) as DiagnosticAnalyzer;
                        }
                        catch
                        {
                            // Unable to created a new analyzer instance, bail out on reporting diagnostics.
                            return;
                        }

                        // Report analyzer exception diagnostics on original analyzer, not the temporary cloned one.
                        analyzerExecutor = GetAnalyzerExecutorForClone(compilation, localDiagnostics.Add, analyzerForExceptionDiagnostics: analyzer);

                        analyzerActions = await this.GetAnalyzerActionsAsync(clonedAnalyzer, analyzerExecutor).ConfigureAwait(false);
                        forceAnalyzeAllDocuments(_project, clonedAnalyzer, _cancellationToken);
                    }

                    // Compilation actions.
                    analyzerExecutor.ExecuteCompilationActions(analyzerActions.CompilationActions);

                    // CompilationEnd actions.
                    analyzerExecutor.ExecuteCompilationActions(analyzerActions.CompilationEndActions);

                    var filteredDiagnostics = CompilationWithAnalyzers.GetEffectiveDiagnostics(localDiagnostics, compilation);
                    diagnostics.AddRange(filteredDiagnostics);
                }
                finally
                {
                    if (clonedAnalyzer != null)
                    {
                        AnalyzerManager.Instance.ClearAnalyzerState(ImmutableArray.Create(clonedAnalyzer));
                    }
                }
            }
        }
コード例 #30
0
 public AnalyzerInfo(DiagnosticAnalyzer analyzer, AnalyzerTelemetryInfo analyzerTelemetryInfo, bool telemetry)
 {
     CLRType   = analyzer.GetType();
     Telemetry = telemetry;
     SetAnalyzerTypeCount(analyzerTelemetryInfo);
 }
コード例 #31
0
        public static void VerifyDiagnostic(
            IEnumerable <string> sources,
            DiagnosticAnalyzer analyzer,
            string language,
            params Diagnostic[] expectedDiagnostics)
        {
            foreach (Diagnostic diagnostic in expectedDiagnostics)
            {
                Assert.True(analyzer.Supports(diagnostic.Descriptor),
                            $"Diagnostic \"{diagnostic.Descriptor.Id}\" is not supported by analyzer \"{analyzer.GetType().Name}\".");
            }

            Diagnostic[] diagnostics = DiagnosticUtility.GetSortedDiagnostics(sources, analyzer, language);

            if (diagnostics.Length > 0 &&
                analyzer.SupportedDiagnostics.Length > 1)
            {
                diagnostics = diagnostics
                              .Where(diagnostic => expectedDiagnostics.Any(expectedDiagnostic => DiagnosticComparer.Id.Equals(diagnostic, expectedDiagnostic)))
                              .ToArray();
            }

            VerifyDiagnostics(diagnostics, expectedDiagnostics);
        }
コード例 #32
0
            private static string CreateStub(DiagnosticAnalyzer analyzer, DiagnosticDescriptor descriptor)
            {
                var builder = new StringBuilder();

                builder.Append($"|{(builder.Length == 0 ? " Code     " : "          ")}| ");
                builder.Append($"[{analyzer.GetType().Name}]({CodeFile.Find(analyzer.GetType()).Uri})");

                var text = builder.ToString();
                var stub = $@"# {descriptor.Id}

## {EscapeTags(descriptor.Title)}

| Topic    | Value
| :--      | :--
| Id       | {descriptor.Id}
| Severity | {descriptor.DefaultSeverity}
| Enabled  | {(descriptor.IsEnabledByDefault ? "True" : "False")}
| Category | {descriptor.Category}
| Code     | [<TYPENAME>](<URL>)

## Description

{EscapeTags(descriptor.Description)}

## Motivation

ADD MOTIVATION HERE

## How to fix violations

ADD HOW TO FIX VIOLATIONS HERE

<!-- start generated config severity -->
## Configure severity

### Via ruleset file

Configure the severity per project, for more info see [MSDN](https://msdn.microsoft.com/en-us/library/dd264949.aspx).

### Via .editorconfig file

```ini
# {descriptor.Id}: {descriptor.Title.ToString(CultureInfo.InvariantCulture)}
dotnet_diagnostic.{descriptor.Id}.severity = chosenSeverity
```

where `chosenSeverity` can be one of `none`, `silent`, `suggestion`, `warning`, or `error`.

### Via #pragma directive

```csharp
#pragma warning disable {descriptor.Id} // {descriptor.Title.ToString(CultureInfo.InvariantCulture)}
Code violating the rule here
#pragma warning restore {descriptor.Id} // {descriptor.Title.ToString(CultureInfo.InvariantCulture)}
```

Or put this at the top of the file to disable all instances.

```csharp
#pragma warning disable {descriptor.Id} // {descriptor.Title.ToString(CultureInfo.InvariantCulture)}
```

### Via attribute `[SuppressMessage]`

```csharp
[System.Diagnostics.CodeAnalysis.SuppressMessage(""{descriptor.Category}"",
    ""{descriptor.Id}:{descriptor.Title.ToString(CultureInfo.InvariantCulture)}"",
    Justification = ""Reason..."")]
```
<!-- end generated config severity -->
";

                return(Replace(stub, "| Code     | [<TYPENAME>](<URL>)", text));
            }
コード例 #33
0
        public void AnalyzersBenchmark(DiagnosticAnalyzer analyzer)
        {
            var id           = analyzer.SupportedDiagnostics.Single().Id;
            var expectedName = id + (id.Contains("_") ? "_" : string.Empty) + "Benchmarks";
            var fileName     = Path.Combine(Program.BenchmarksDirectory, expectedName + ".cs");
            var code         = new StringBuilder().AppendLine($"namespace {this.GetType().Namespace}")
                               .AppendLine("{")
                               .AppendLine($"    public class {expectedName}")
                               .AppendLine("    {")
                               .AppendLine($"        private static readonly Gu.Roslyn.Asserts.Benchmark Benchmark = Gu.Roslyn.Asserts.Benchmark.Create(Code.AnalyzersProject, new {analyzer.GetType().FullName}());")
                               .AppendLine()
                               .AppendLine("        [BenchmarkDotNet.Attributes.Benchmark]")
                               .AppendLine("        public void RunOnIDisposableAnalyzers()")
                               .AppendLine("        {")
                               .AppendLine("            Benchmark.Run();")
                               .AppendLine("        }")
                               .AppendLine("    }")
                               .AppendLine("}")
                               .ToString();

            if (!File.Exists(fileName) ||
                File.ReadAllText(fileName) != code)
            {
                File.WriteAllText(fileName, code);
                Assert.Fail();
            }
        }