public static void LogAnalyzerCrashCount(DiagnosticAnalyzer analyzer, Exception ex, LogAggregator logAggregator) { 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); var tuple = ValueTuple.Create(telemetry, analyzer.GetType(), ex.GetType()); logAggregator.IncreaseCount(tuple); }
/// <summary> /// Check the method body of the Initialize method of an analyzer and if that's empty, /// then the analyzer hasn't been implemented yet. /// </summary> private static bool HasImplementation(DiagnosticAnalyzer analyzer) { System.Reflection.MethodInfo method = analyzer.GetType().GetMethod("Initialize"); if (method != null) { System.Reflection.MethodBody body = method.GetMethodBody(); int? ilInstructionCount = body?.GetILAsByteArray()?.Count(); // An empty method has two IL instructions - nop and ret. return ilInstructionCount != 2; } return true; }
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; }
public void UpdateAnalyzerTypeCount(DiagnosticAnalyzer analyzer, AnalyzerActions analyzerActions) { var telemetry = DiagnosticAnalyzerLogger.AllowsTelemetry(_owner, analyzer); ImmutableInterlocked.AddOrUpdate( ref _analyzerInfoMap, analyzer.GetType(), addValue: new AnalyzerInfo(analyzer, analyzerActions, telemetry), updateValueFactory: (k, ai) => { ai.SetAnalyzerTypeCount(analyzerActions); return ai; }); }
/// <summary> /// 診断結果を文字列に整えます。 /// </summary> private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics) { if (diagnostics.Length == 0) { return " NONE.\r\n"; } var builder = new StringBuilder(); for (var i = 0; i < diagnostics.Length; ++i) { builder.AppendLine("// " + diagnostics[i].ToString()); var analyzerTypeName = analyzer.GetType().Name; foreach (var rule in analyzer.SupportedDiagnostics) { if (rule != null && rule.Id == diagnostics[i].Id) { var location = diagnostics[i].Location; if (location == Location.None) { builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerTypeName, rule.Id); } else { Assert.IsTrue(location.IsInSource, $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostics[i]}\r\n"); var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition; builder.AppendFormat("{0}({1}, {2}, {3}.{4})", "GetCSharpResultAt", linePosition.Line + 1, linePosition.Character + 1, analyzerTypeName, rule.Id); } if (i != diagnostics.Length - 1) { builder.Append(','); } builder.AppendLine(); break; } } } return builder.ToString(); }
public static bool IsCompilerAnalyzer(this DiagnosticAnalyzer analyzer) { // TODO: find better way. var typeString = analyzer.GetType().ToString(); if (typeString == CSharpCompilerAnalyzerTypeName) { return(true); } if (typeString == VisualBasicCompilerAnalyzerTypeName) { return(true); } return(false); }
internal static Diagnostic GetAnalyzerDiagnostic(DiagnosticAnalyzer analyzer, Exception e) { return(Diagnostic.Create(GetDiagnosticDescriptor(analyzer.GetType().ToString(), e.Message), Location.None)); }
/// <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(); }
/// <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("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("{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(); }
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); }
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 ruleFields = analyzerType .GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) .Where(f => f.IsStatic && f.FieldType == typeof(DiagnosticDescriptor)); foreach (var field in ruleFields) { var rule = field.GetValue(null) as DiagnosticDescriptor; if (rule != null && rule.Id == diagnostics[i].Id) { var location = diagnostics[i].Location; if (location == Location.None) { builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, field.Name); } else { Assert.True(location.IsInSource, string.Format("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") ? "GetCSharpResultAt" : "GetBasicResultAt"; var linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition; builder.AppendFormat("{0}({1}, {2}, {3}.{4})", resultMethodName, linePosition.Line + 1, linePosition.Character + 1, field.DeclaringType.Name, field.Name); } if (i != diagnostics.Length - 1) { builder.Append(','); } builder.AppendLine(); break; } } } return builder.ToString(); }
public static string GetAnalyzerAssemblyName(this DiagnosticAnalyzer analyzer) => analyzer.GetType().Assembly.GetName().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 + "_" + providerType.AssemblyQualifiedName, GetProviderVersion(location)); }
/// <summary> /// Helper method to format a Diagnostic into an easily reasible string /// </summary> /// <param name="analyzer">The analyzer that this Verifer 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.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, rule.Id); } else { Assert.IsTrue(location.IsInSource, string.Format("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") ? "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(); }
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()); Type analyzerType = analyzer.GetType(); IEnumerable<FieldInfo> ruleFields = analyzerType .GetFields(BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy) .Where(f => f.IsStatic && f.FieldType == typeof(DiagnosticDescriptor)); foreach (FieldInfo field in ruleFields) { var rule = field.GetValue(null) as DiagnosticDescriptor; if (rule != null && rule.Id == diagnostics[i].Id) { Location location = diagnostics[i].Location; if (location == Location.None) { builder.AppendFormat("GetGlobalResult({0}.{1})", analyzerType.Name, field.Name); } else { Assert.False(location.IsInMetadata, "Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata:\r\n" + diagnostics[i]); string resultMethodName = GetResultMethodName(diagnostics[i]); Microsoft.CodeAnalysis.Text.LinePosition linePosition = diagnostics[i].Location.GetLineSpan().StartLinePosition; builder.AppendFormat("{0}({1}, {2}, {3}.{4})", resultMethodName, linePosition.Line + 1, linePosition.Character + 1, field.DeclaringType.Name, field.Name); } if (i != diagnostics.Length - 1) { builder.Append(','); } builder.AppendLine(); break; } } } return builder.ToString(); }
public static string GetAnalyzerAssemblyName(this DiagnosticAnalyzer analyzer) { var typeInfo = analyzer.GetType().GetTypeInfo(); return(typeInfo.Assembly.GetName().Name); }
private void SetParameterValues(DiagnosticAnalyzer parameteredAnalyzer) { 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 value = parameters .Single(p => p.RuleId == parameteredAnalyzer.SupportedDiagnostics.Single().Id).ParameterValues .Single(pv => pv.ParameterKey == propertyParameterPair.Descriptor.Key) .ParameterValue; object convertedValue = value; switch (propertyParameterPair.Descriptor.Type) { case PropertyType.String: break; case PropertyType.Integer: convertedValue = int.Parse(value, NumberStyles.None, CultureInfo.InvariantCulture); break; default: throw new NotSupportedException(); } propertyParameterPair.Property.SetValue(parameteredAnalyzer, convertedValue); } }
/// <summary> /// Check the method body of the Initialize method of an analyzer and if that's empty, /// then the analyzer hasn't been implemented yet. /// </summary> private static bool HasImplementation(DiagnosticAnalyzer analyzer) { MethodInfo method = analyzer.GetType().GetTypeInfo().GetMethod("Initialize"); if (method != null) { MethodBody body = method.GetMethodBody(); int? ilInstructionCount = body?.GetILAsByteArray()?.Count(); return ilInstructionCount != 2; } return true; }
private static string FormatDiagnostics(DiagnosticAnalyzer analyzer, params Diagnostic[] diagnostics) { return string.Join(",", diagnostics.Select(diagnostic => { var builder = new StringBuilder(); builder.AppendLine($"// {diagnostic}"); var analyzerType = analyzer.GetType(); foreach (var rule in analyzer.SupportedDiagnostics.Where(d => d?.Id == diagnostic.Id)) { if (diagnostic.Location == Location.None) { builder.Append($"GetGlobalResult({analyzerType.Name}.{rule.Id})"); } else { Assert.IsTrue(diagnostic.Location.IsInSource, $"Test base does not currently handle diagnostics in metadata locations. Diagnostic in metadata: {diagnostic}{NewLine}"); var resultMethodName = diagnostic.Location.SourceTree.FilePath.EndsWith(".cs") ? "CSharp" : "Basic"; var linePosition = diagnostic.Location.GetLineSpan().StartLinePosition; builder.Append($"Get{resultMethodName}ResultAt({linePosition.Line + 1}, {linePosition.Character + 1}, {analyzerType.Name}.{rule.Id})"); } builder.AppendLine(); break; } return builder.ToString(); })); }