Пример #1
0
        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);
        }
Пример #2
0
        /// <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();
        }
Пример #6
0
        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);
        }
Пример #7
0
 internal static Diagnostic GetAnalyzerDiagnostic(DiagnosticAnalyzer analyzer, Exception e)
 {
     return(Diagnostic.Create(GetDiagnosticDescriptor(analyzer.GetType().ToString(), e.Message), Location.None));
 }
Пример #8
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();
        }
        /// <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();
        }
Пример #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);
        }
        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();
        }
Пример #12
0
 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));
                }
Пример #14
0
        /// <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();
        }
Пример #16
0
        public static string GetAnalyzerAssemblyName(this DiagnosticAnalyzer analyzer)
        {
            var typeInfo = analyzer.GetType().GetTypeInfo();

            return(typeInfo.Assembly.GetName().Name);
        }
Пример #17
0
        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);
            }
        }
Пример #18
0
        /// <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;
        }
Пример #19
0
		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();
			}));
		}