public static Diagnostic CreateDiagnostic( this SyntaxNodeOrToken nodeOrToken, DiagnosticDescriptor rule, params object[] args) { return nodeOrToken.GetLocation().CreateDiagnostic(rule, args); }
public static Diagnostic CreateDiagnostic( this ISymbol symbol, DiagnosticDescriptor rule, params object[] args) { return symbol.Locations.CreateDiagnostic(rule, args); }
public static Diagnostic CreateDiagnostic(DiagnosticDescriptor descriptor, params object[] args) { return Diagnostic.Create(descriptor, location: null, additionalLocations: null, messageArgs: args); }
public TestDiagnostic(DiagnosticDescriptor descriptor, string kind, DiagnosticSeverity severity, Location location, string message, params object[] arguments) { _descriptor = descriptor; _kind = kind; _severity = severity; _location = location; _message = message; _arguments = arguments; }
protected static DiagnosticResult GetGlobalResult(DiagnosticDescriptor rule, params string[] messageArguments) { return new DiagnosticResult { Id = rule.Id, Severity = rule.DefaultSeverity, Message = rule.MessageFormat.ToString() }; }
public static IEnumerable<Diagnostic> CreateDiagnostics( this IEnumerable<SyntaxNodeOrToken> nodesOrTokens, DiagnosticDescriptor rule, params object[] args) { foreach (var nodeOrToken in nodesOrTokens) { yield return nodeOrToken.CreateDiagnostic(rule, args); } }
public static IEnumerable<Diagnostic> CreateDiagnostics( this IEnumerable<ISymbol> symbols, DiagnosticDescriptor rule, params object[] args) { foreach (var symbol in symbols) { yield return symbol.CreateDiagnostic(rule, args); } }
public Diagnostic(Location location, DiagnosticDescriptor descriptor, params object[] messageArgs) { if(location == null) { throw new ArgumentNullException(nameof(location)); } if(descriptor == null) { throw new ArgumentNullException(nameof(descriptor)); } Location = location; Descriptor = descriptor; _messageArgs = messageArgs?? EmptyMessageArgs; }
protected AbstractCodeStyleDiagnosticAnalyzer( string descriptorId, LocalizableString title, LocalizableString message = null) { DescriptorId = descriptorId; _localizableTitle = title; _localizableMessage = message ?? title; _descriptor = CreateDescriptor(descriptorId, DiagnosticSeverity.Hidden); UnnecessaryWithSuggestionDescriptor = CreateDescriptor( descriptorId, DiagnosticSeverity.Hidden, DiagnosticCustomTags.Unnecessary); UnnecessaryWithoutSuggestionDescriptor = CreateDescriptor(descriptorId + "WithoutSuggestion", DiagnosticSeverity.Hidden, DiagnosticCustomTags.Unnecessary); SupportedDiagnostics = ImmutableArray.Create( _descriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor); }
private DiagnosticDescriptor GetClassificationIdDescriptor() { if (_classificationIdDescriptor == null) { var titleAndMessageFormat = GetTitleAndMessageFormatForClassificationIdDescriptor(); _classificationIdDescriptor = new DiagnosticDescriptor(IDEDiagnosticIds.RemoveUnnecessaryImportsDiagnosticId, titleAndMessageFormat, titleAndMessageFormat, DiagnosticCategory.Style, DiagnosticSeverity.Hidden, isEnabledByDefault: true, customTags: DiagnosticCustomTags.Unnecessary); } return _classificationIdDescriptor; }
public CSharpTypeStyleDiagnosticAnalyzerBase(string diagnosticId, LocalizableString title, LocalizableString message) { _diagnosticId = diagnosticId; _title = title; _message = message; _noneDiagnosticDescriptor = CreateDiagnosticDescriptor(DiagnosticSeverity.Hidden); _infoDiagnosticDescriptor = CreateDiagnosticDescriptor(DiagnosticSeverity.Info); _warningDiagnosticDescriptor = CreateDiagnosticDescriptor(DiagnosticSeverity.Warning); _errorDiagnosticDescriptor = CreateDiagnosticDescriptor(DiagnosticSeverity.Error); _severityToDescriptorMap = new Dictionary<DiagnosticSeverity, DiagnosticDescriptor> { {DiagnosticSeverity.Hidden, _noneDiagnosticDescriptor }, {DiagnosticSeverity.Info, _infoDiagnosticDescriptor }, {DiagnosticSeverity.Warning, _warningDiagnosticDescriptor }, {DiagnosticSeverity.Error, _errorDiagnosticDescriptor }, }; }
private void SymbolAction(SymbolAnalysisContext context, NamingStylePreferencesInfo preferences) { if (preferences.TryGetApplicableRule(context.Symbol, out var applicableRule)) { if (applicableRule.EnforcementLevel != DiagnosticSeverity.Hidden && !applicableRule.IsNameCompliant(context.Symbol.Name, out var failureReason)) { var descriptor = new DiagnosticDescriptor(IDEDiagnosticIds.NamingRuleId, s_localizableTitleNamingStyle, string.Format(FeaturesResources.Naming_rule_violation_0, failureReason), DiagnosticCategory.Style, applicableRule.EnforcementLevel, isEnabledByDefault: true); var builder = ImmutableDictionary.CreateBuilder<string, string>(); builder[nameof(NamingStyle)] = applicableRule.NamingStyle.CreateXElement().ToString(); builder["OptionName"] = nameof(SimplificationOptions.NamingPreferences); builder["OptionLanguage"] = context.Compilation.Language; context.ReportDiagnostic(Diagnostic.Create(descriptor, context.Symbol.Locations.First(), builder.ToImmutable())); } } }
protected AbstractCodeStyleDiagnosticAnalyzer( string descriptorId, LocalizableString title, LocalizableString message = null) { DescriptorId = descriptorId; _localizableTitle = title; _localizableMessage = message ?? title; HiddenDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Hidden); InfoDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Info); WarningDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Warning); ErrorDescriptor = CreateDescriptorWithSeverity(DiagnosticSeverity.Error); UnnecessaryWithSuggestionDescriptor = CreateDescriptorWithId( descriptorId, _localizableTitle, _localizableMessage, DiagnosticSeverity.Hidden, DiagnosticCustomTags.Unnecessary); UnnecessaryWithoutSuggestionDescriptor = CreateDescriptorWithId( descriptorId + "WithoutSuggestion", _localizableTitle, _localizableMessage, DiagnosticSeverity.Hidden, DiagnosticCustomTags.Unnecessary); SupportedDiagnostics = ImmutableArray.Create( HiddenDescriptor, UnnecessaryWithoutSuggestionDescriptor, UnnecessaryWithSuggestionDescriptor); }
public DisposeObjectsBeforeLosingScopeDiagnosticAnalyzer(DiagnosticDescriptor disposeObjectsBeforeLosingScopeRule, DiagnosticDescriptor useRecommendedDisposePatternRule) : base(ImmutableArray.Create(disposeObjectsBeforeLosingScopeRule, useRecommendedDisposePatternRule), GeneratedCodeAnalysisFlags.None) { _disposeObjectsBeforeLosingScopeRule = disposeObjectsBeforeLosingScopeRule; _useRecommendedDisposePatternRule = useRecommendedDisposePatternRule; }
public void TestGetEffectiveDiagnosticsGlobal() { var noneDiagDescriptor = new DiagnosticDescriptor("XX0001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Hidden, isEnabledByDefault: true); var infoDiagDescriptor = new DiagnosticDescriptor("XX0002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Info, isEnabledByDefault: true); var warningDiagDescriptor = new DiagnosticDescriptor("XX0003", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault: true); var errorDiagDescriptor = new DiagnosticDescriptor("XX0004", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Error, isEnabledByDefault: true); var noneDiag = Microsoft.CodeAnalysis.Diagnostic.Create(noneDiagDescriptor, Location.None); var infoDiag = Microsoft.CodeAnalysis.Diagnostic.Create(infoDiagDescriptor, Location.None); var warningDiag = Microsoft.CodeAnalysis.Diagnostic.Create(warningDiagDescriptor, Location.None); var errorDiag = Microsoft.CodeAnalysis.Diagnostic.Create(errorDiagDescriptor, Location.None); var diags = new[] { noneDiag, infoDiag, warningDiag, errorDiag }; var options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Default); var comp = CreateCompilationWithMscorlib45("", options: options); var effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(4, effectiveDiags.Length); options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Error); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(4, effectiveDiags.Length); Assert.Equal(1, effectiveDiags.Count(d => d.IsWarningAsError)); options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Warn); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(4, effectiveDiags.Length); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Error)); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Warning)); options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Info); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(4, effectiveDiags.Length); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Error)); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Info)); options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Hidden); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(4, effectiveDiags.Length); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Error)); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Hidden)); options = TestOptions.ReleaseDll.WithGeneralDiagnosticOption(ReportDiagnostic.Suppress); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(2, effectiveDiags.Length); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Error)); Assert.Equal(1, effectiveDiags.Count(d => d.Severity == DiagnosticSeverity.Hidden)); }
private static DiagnosticResult GetBasicResultAt(int line, int column, DiagnosticDescriptor descriptor, params object[] arguments) { return(new DiagnosticResult(descriptor) .WithLocation(line, column) .WithArguments(arguments)); }
#pragma warning disable RS1012 internal static bool IsAnalyzerSuppressed(this CompilationStartAnalysisContext context, DiagnosticDescriptor descriptor) { return(context.Compilation.IsAnalyzerSuppressed(descriptor)); }
public static void FadeOutBraces(this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, BlockSyntax block) { FadeOutToken(context, descriptor, block.OpenBraceToken); FadeOutToken(context, descriptor, block.CloseBraceToken); }
/// <summary> /// Analyzes a <see cref="InvocationExpressionSyntax"/> node to add a diagnostic to static method calls in <see cref="System.Diagnostics.Debug"/>. /// The diagnostic is added if the parameter count is lower than <paramref name="parameterIndex"/> or the string given at the index can be evaluated to null, string.Empty or just whitespaces. /// </summary> /// <param name="context">The current analysis context</param> /// <param name="methodName">The method name that should be detected</param> /// <param name="parameterIndex">The index, the string parameter that should be checked, is at</param> /// <param name="descriptor">The descriptor of the diagnostic that should be added</param> protected internal void HandleMethodCall(SyntaxNodeAnalysisContext context, string methodName, int parameterIndex, DiagnosticDescriptor descriptor) { var invocationExpressionSyntax = context.Node as InvocationExpressionSyntax; var memberAccessExpressionSyntax = invocationExpressionSyntax?.Expression as MemberAccessExpressionSyntax; var identifierNameSyntax = invocationExpressionSyntax?.Expression as IdentifierNameSyntax; var name = memberAccessExpressionSyntax?.Name?.Identifier.ValueText ?? identifierNameSyntax?.Identifier.ValueText; if (name == methodName) { IMethodSymbol symbolInfo = context.SemanticModel.GetSymbolInfo(invocationExpressionSyntax).Symbol as IMethodSymbol; if (symbolInfo != null) { var debugType = context.SemanticModel.Compilation.GetTypeByMetadataName(typeof(Debug).FullName); if (symbolInfo.ContainingType == debugType && symbolInfo.Name == methodName) { if ((invocationExpressionSyntax.ArgumentList?.Arguments.Count ?? 0) <= parameterIndex) { // Wrong overload was used, e.g. Debug.Assert(bool condition) context.ReportDiagnostic(Diagnostic.Create(descriptor, invocationExpressionSyntax.GetLocation())); } else { var messageParameter = invocationExpressionSyntax.ArgumentList?.Arguments[parameterIndex]; if (messageParameter?.Expression != null) { Optional <object> constantValue = context.SemanticModel.GetConstantValue(messageParameter.Expression); // Report a diagnostic if the message is constant and null or whitespace if (constantValue.HasValue && string.IsNullOrWhiteSpace(constantValue.Value as string)) { context.ReportDiagnostic(Diagnostic.Create(descriptor, invocationExpressionSyntax.GetLocation())); } } } } } } }
public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterOperationBlockStartAction(osContext => { var method = osContext.OwningSymbol as IMethodSymbol; if (method == null) { return; } osContext.RegisterOperationAction(opContext => { IOperation expression = ((IExpressionStatement)opContext.Operation).Expression; DiagnosticDescriptor rule = null; string targetMethodName = null; switch (expression.Kind) { case OperationKind.ObjectCreationExpression: IMethodSymbol ctor = ((IObjectCreationExpression)expression).Constructor; if (ctor != null) { rule = ObjectCreationRule; targetMethodName = ctor.ContainingType.Name; } break; case OperationKind.InvocationExpression: IInvocationExpression invocationExpression = ((IInvocationExpression)expression); IMethodSymbol targetMethod = invocationExpression.TargetMethod; if (targetMethod == null) { break; } if (IsStringCreatingMethod(targetMethod)) { rule = StringCreationRule; } else if (IsTryParseMethod(targetMethod)) { rule = TryParseRule; } else if (IsHResultOrErrorCodeReturningMethod(targetMethod)) { rule = HResultOrErrorCodeRule; } targetMethodName = targetMethod.Name; break; } if (rule != null) { Diagnostic diagnostic = Diagnostic.Create(rule, expression.Syntax.GetLocation(), method.Name, targetMethodName); opContext.ReportDiagnostic(diagnostic); } }, OperationKind.ExpressionStatement); }); }
protected abstract BaseDiagnosticItem CreateItem(DiagnosticDescriptor diagnostic, ReportDiagnostic effectiveSeverity, string language);
public static ReportDiagnostic GetEffectiveSeverity(this DiagnosticDescriptor descriptor, CompilationOptions options) { return(options == null ? descriptor.DefaultSeverity.MapSeverityToReport() : descriptor.GetEffectiveSeverity(options)); }
private string GetStatus(INamedTypeSymbol classSymbol, SyntaxNode root, SemanticModel model, DiagnosticDescriptor descriptor) { // Some analyzers use multiple descriptors. We analyze the first one and hope that // thats enough. var members = classSymbol.GetMembers().Where(x => x.Name.Contains("Descriptor")).ToArray(); foreach (var member in members) { ObjectCreationExpressionSyntax initializer; SyntaxNode node = root.FindNode(member.Locations.FirstOrDefault().SourceSpan); if (node != null) { initializer = (node as PropertyDeclarationSyntax)?.Initializer?.Value as ObjectCreationExpressionSyntax; if (initializer == null) { initializer = (node as VariableDeclaratorSyntax)?.Initializer?.Value as ObjectCreationExpressionSyntax; if (initializer == null) { continue; } } } else { continue; } var firstArgument = initializer.ArgumentList.Arguments[0]; string constantValue = (string)model.GetConstantValue(firstArgument.Expression).Value; if (constantValue != descriptor.Id) { continue; } // We use the fact that the only parameter that returns a boolean is the one we are interested in var enabledByDefaultParameter = from argument in initializer.ArgumentList.Arguments where Equals(model.GetTypeInfo(argument.Expression).Type, _booleanType) select argument.Expression; var parameter = enabledByDefaultParameter.FirstOrDefault(); string parameterString = parameter.ToString(); var analyzerConstantLength = "AnalyzerConstants.".Length; if (parameterString.Length < analyzerConstantLength) { return(parameterString); } return(parameter.ToString().Substring(analyzerConstantLength)); } return("Unknown"); }
public CSharpObjectCreationTracker(IAnalyzerConfiguration analyzerConfiguration, DiagnosticDescriptor rule) : base(analyzerConfiguration, rule) { }
public static (string source, List <Diagnostic> diagnostics) GetMarkedDiagnostics( string s, DiagnosticDescriptor descriptor, string filePath) { StringBuilder sb = StringBuilderCache.GetInstance(s.Length - OpenMarker.Length - CloseMarker.Length); List <Diagnostic> diagnostics = null; int lastPos = 0; int line = 0; int column = 0; int startLine = -1; int startColumn = -1; int length = s.Length; for (int i = 0; i < length; i++) { switch (s[i]) { case '\r': { if (i < length - 1 && s[i + 1] == '\n') { i++; } line++; column = 0; continue; } case '\n': { line++; column = 0; continue; } case '<': { if (i < length - 1 && IsOpenMarker(s, length, i)) { sb.Append(s, lastPos, i - lastPos); startLine = line; startColumn = column; i += 2; lastPos = i + 1; continue; } break; } case '>': { if (startColumn != -1 && IsCloseMarker(s, length, i)) { sb.Append(s, lastPos, i - lastPos); var lineSpan = new LinePositionSpan( new LinePosition(startLine, startColumn), new LinePosition(line, column)); TextSpan span = TextSpan.FromBounds(lastPos, i); Location location = Location.Create(filePath, span, lineSpan); Diagnostic diagnostic = Diagnostic.Create(descriptor, location); (diagnostics ?? (diagnostics = new List <Diagnostic>())).Add(diagnostic); i += 2; lastPos = i + 1; startLine = -1; startColumn = -1; continue; } break; } } column++; } sb.Append(s, lastPos, s.Length - lastPos); return(StringBuilderCache.GetStringAndFree(sb), diagnostics); }
public static void FadeOutBraces(this SyntaxNodeAnalysisContext context, DiagnosticDescriptor descriptor, AccessorListSyntax accessorList) { FadeOutToken(context, descriptor, accessorList.OpenBraceToken); FadeOutToken(context, descriptor, accessorList.CloseBraceToken); }
private TestDiagnostic(SerializationInfo info, StreamingContext context) { var id = info.GetString("id"); _kind = info.GetString("kind"); _message = info.GetString("message"); _location = (Location)info.GetValue("location", typeof(Location)); _severity = (DiagnosticSeverity)info.GetValue("severity", typeof(DiagnosticSeverity)); var defaultSeverity = (DiagnosticSeverity)info.GetValue("defaultSeverity", typeof(DiagnosticSeverity)); _arguments = (object[])info.GetValue("arguments", typeof(object[])); _descriptor = new DiagnosticDescriptor(id, string.Empty, _message, id, defaultSeverity, isEnabledByDefault: true); }
private static void Analyze(SyntaxNodeAnalysisContext context, DiagnosticDescriptor rule) { // empty callback serves only as baseline for performance tests }
internal async Task<IEnumerable<Diagnostic>> GetDiagnostic(SyntaxTree tree, DiagnosticDescriptor diagnosticDescriptor, CancellationToken cancellationToken) { try { // This can be called on a background thread. We are being asked whether a // lightbulb should be shown for the given document, but we only know about the // current state of the buffer. Compare the text to see if we should bail early. // Even if the text is the same, the buffer may change on the UI thread during this // method. If it does, we may give an incorrect response, but the diagnostics // engine will know that the document changed and not display the lightbulb anyway. if (Buffer.AsTextContainer().CurrentText != await tree.GetTextAsync(cancellationToken).ConfigureAwait(false)) { return SpecializedCollections.EmptyEnumerable<Diagnostic>(); } TrackingSession trackingSession; if (CanInvokeRename(out trackingSession, waitForResult: true, cancellationToken: cancellationToken)) { SnapshotSpan snapshotSpan = trackingSession.TrackingSpan.GetSpan(Buffer.CurrentSnapshot); var textSpan = snapshotSpan.Span.ToTextSpan(); var builder = ImmutableDictionary.CreateBuilder<string, string>(); builder.Add(RenameTrackingDiagnosticAnalyzer.RenameFromPropertyKey, trackingSession.OriginalName); builder.Add(RenameTrackingDiagnosticAnalyzer.RenameToPropertyKey, snapshotSpan.GetText()); var properties = builder.ToImmutable(); var diagnostic = Diagnostic.Create(diagnosticDescriptor, tree.GetLocation(textSpan), properties); return SpecializedCollections.SingletonEnumerable(diagnostic); } return SpecializedCollections.EmptyEnumerable<Diagnostic>(); } catch (Exception e) when (FatalError.ReportUnlessCanceled(e)) { throw ExceptionUtilities.Unreachable; } }
public CSharpMethodDeclarationTracker(IAnalyzerConfiguration analyzerConfiguration, DiagnosticDescriptor rule) : base(analyzerConfiguration, rule) { }
internal static bool AreAnalyzersSuppressed(this CompilationStartAnalysisContext context, DiagnosticDescriptor descriptor1, DiagnosticDescriptor descriptor2, DiagnosticDescriptor descriptor3) { return(context.Compilation.AreAnalyzersSuppressed(descriptor1, descriptor2, descriptor3)); }
private static DiagnosticResult GetBasicResultAt(int line, int column, DiagnosticDescriptor rule, params string[] arguments) #pragma warning disable RS0030 // Do not used banned APIs => VerifyVB.Diagnostic(rule) .WithLocation(line, column) #pragma warning restore RS0030 // Do not used banned APIs .WithArguments(arguments);
public override void Initialize(AnalysisContext analysisContext) { analysisContext.EnableConcurrentExecution(); analysisContext.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); analysisContext.RegisterCompilationStartAction( compilationStartContext => { Compilation compilation = compilationStartContext.Compilation; INamedTypeSymbol enumeratorType = compilation.GetTypeByMetadataName("System.Collections.IEnumerator"); INamedTypeSymbol dataSetType = compilation.GetTypeByMetadataName("System.Data.DataSet"); INamedTypeSymbol dataTableType = compilation.GetTypeByMetadataName("System.Data.DataTable"); INamedTypeSymbol dataRowType = compilation.GetTypeByMetadataName("System.Data.DataRow"); compilationStartContext.RegisterSymbolAction( symbolAnalysisContext => { var nestedType = (INamedTypeSymbol)symbolAnalysisContext.Symbol; INamedTypeSymbol containingType = nestedType.ContainingType; if (containingType == null) { return; } // Do not report diagnostic for compiler generated nested types for delegate declaration if (nestedType.TypeKind == TypeKind.Delegate) { return; } // The Framework Design Guidelines (see 4.9 Nested Types) say that it is okay // to expose nested types for advanced customization and subclassing scenarios, // so, following FxCop's implementation of this rule, we allow protected and // internal nested types. if (nestedType.DeclaredAccessibility != Accessibility.Public) { return; } // Even if the nested type is declared public, don't complain if it's within // a type that's not visible outside the assembly. if (!containingType.IsExternallyVisible()) { return; } // By the design guidelines, nested enumerators are exempt. if (nestedType.AllInterfaces.Contains(enumeratorType)) { return; } // FxCop allowed public nested enums to accommodate .NET types such as // Environment.SpecialFolders. if (nestedType.TypeKind == TypeKind.Enum) { return; } if (IsDataSetSpecialCase(containingType, nestedType, dataSetType, dataTableType, dataRowType)) { return; } DiagnosticDescriptor descriptor = containingType.TypeKind == TypeKind.Module ? VisualBasicModuleRule : DefaultRule; symbolAnalysisContext.ReportDiagnostic(nestedType.CreateDiagnostic(descriptor, nestedType.Name)); }, SymbolKind.NamedType); }); }
private static void TestDescriptorIsExceptionSafeCore(DiagnosticDescriptor descriptor) { var localizableTitle = descriptor.Title; var localizableMessage = descriptor.MessageFormat; var localizableDescription = descriptor.Description; // Verify exceptions from LocalizableResourceString don't go unhandled. var title = localizableTitle.ToString(); var message = localizableMessage.ToString(); var description = localizableDescription.ToString(); // Verify exceptions from LocalizableResourceString are raised if OnException is set. var exceptions = new List<Exception>(); var handler = new EventHandler<Exception>((sender, ex) => exceptions.Add(ex)); localizableTitle.OnException += handler; localizableMessage.OnException += handler; localizableDescription.OnException += handler; // Access and evaluate localizable fields. var unused1 = localizableTitle.ToString(); var unused2 = localizableMessage.ToString(); var unused3 = localizableDescription.ToString(); Assert.Equal(3, exceptions.Count); // Verify DiagnosticAnalyzer.SupportedDiagnostics is also exception safe. var analyzer = new MyAnalyzer(descriptor); var exceptionDiagnostics = new List<Diagnostic>(); Action<Exception, DiagnosticAnalyzer, Diagnostic> onAnalyzerException = (ex, a, diag) => exceptionDiagnostics.Add(diag); var analyzerExecutor = AnalyzerExecutor.CreateForSupportedDiagnostics(onAnalyzerException, AnalyzerManager.Instance); var descriptors = AnalyzerManager.Instance.GetSupportedDiagnosticDescriptors(analyzer, analyzerExecutor); Assert.Equal(1, descriptors.Length); Assert.Equal(descriptor.Id, descriptors[0].Id); // Access and evaluate localizable fields. unused1 = descriptors[0].Title.ToString(); unused2 = descriptors[0].MessageFormat.ToString(); unused3 = descriptors[0].Description.ToString(); // Verify logged analyzer exception diagnostics. Assert.Equal(3, exceptionDiagnostics.Count); Assert.True(exceptionDiagnostics.TrueForAll(AnalyzerExecutor.IsAnalyzerExceptionDiagnostic)); }
public void Execute(GeneratorExecutionContext context) { context.AddSource("MapperAttribute", SourceText.From(MappingAttributeText, Encoding.UTF8)); //Create a new compilation that contains the attribute var options = (context.Compilation as CSharpCompilation).SyntaxTrees[0].Options as CSharpParseOptions; var compilation = context.Compilation.AddSyntaxTrees(CSharpSyntaxTree.ParseText(SourceText.From(MappingAttributeText, Encoding.UTF8), options)); var allNodes = compilation.SyntaxTrees.SelectMany(s => s.GetRoot().DescendantNodes()); var allAttributes = allNodes.Where((d) => d.IsKind(SyntaxKind.Attribute)).OfType <AttributeSyntax>(); var attributes = allAttributes.Where(d => d.Name.ToString() == "Mapping" || d.Name.ToString() == "Mapper.Mapping").ToImmutableArray(); var allClasses = compilation.SyntaxTrees. SelectMany(x => x.GetRoot().DescendantNodes().OfType <ClassDeclarationSyntax>()); var sourceBuilder = new StringBuilder(@" //<auto-generated> namespace MapperGenerator { public static class Mapper {"); foreach (AttributeSyntax attr in attributes) { if (attr.ArgumentList is null) { throw new Exception("Can't be null here"); } #region Get Mapping Source Class Info //todo: add diagnostic when ArgumentList is null //get type of mapping target from constructor argument var mappedTypeArgSyntax = attr.ArgumentList.Arguments.First(); var mappedTypeArgSyntaxExpr = mappedTypeArgSyntax.Expression.NormalizeWhitespace().ToFullString(); var sourceClassName = GetContentInParentheses(mappedTypeArgSyntaxExpr); var sourceClassSyntax = allClasses.First(x => x.Identifier.ToString() == sourceClassName); var sourceClassModel = compilation.GetSemanticModel(sourceClassSyntax.SyntaxTree); var sourceClassNamedTypeSymbol = ModelExtensions.GetDeclaredSymbol(sourceClassModel, sourceClassSyntax); var sourceClassFullName = sourceClassNamedTypeSymbol.OriginalDefinition.ToString(); var sourceClassProperties = sourceClassSyntax.GetProperties(sourceClassModel); #endregion #region Get Mapping Target Class Info var targetClassSyntax = attr.SyntaxTree.GetRoot().DescendantNodes().OfType <ClassDeclarationSyntax>().Last(); var targetClassModel = compilation.GetSemanticModel(attr.SyntaxTree); var targetClassNamedTypeSymbol = ModelExtensions.GetDeclaredSymbol(targetClassModel, targetClassSyntax); var targetClassFullName = targetClassNamedTypeSymbol.OriginalDefinition.ToString(); var targetClassName = targetClassFullName.Split('.').Last(); var targetClassProperties = targetClassSyntax.GetProperties(targetClassModel); #endregion #region Create diagnostic erroes if any property of target doesn't match to source properties. //source class properties should match all of target class properties //should use same name and type of property var targetPropertiesMatchedResult = targetClassProperties.Select(target => new { TargetPropertyName = target.propertyName, TargetPropertySyntax = target.propertySyntax, IsMatched = sourceClassProperties.Any(source => source.propertyName == target.propertyName && source.propertyType == target.propertyType) }); if (targetPropertiesMatchedResult.Any(x => x.IsMatched == false)) { foreach (var target in targetPropertiesMatchedResult.Where(x => x.IsMatched == false)) { var diagnosticDescriptor = new DiagnosticDescriptor("MPERR001", "Property mapping error", $"{targetClassName}.{target.TargetPropertyName} couldn't match to {sourceClassName}, please check if the name and type of properties are the same.", "source generator", DiagnosticSeverity.Error, true); var diagnostic = Diagnostic.Create(diagnosticDescriptor, target.TargetPropertySyntax.GetLocation()); context.ReportDiagnostic(diagnostic); } break; } #endregion #region Build mapper method sourceBuilder.Append(@$ "
public static bool TryCreate(DiagnosticDescriptor descriptor, string[] messageArguments, ProjectId projectId, Workspace workspace, out DiagnosticData diagnosticData, CancellationToken cancellationToken = default(CancellationToken)) { diagnosticData = null; var project = workspace.CurrentSolution.GetProject(projectId); if (project == null) { return false; } var diagnostic = Diagnostic.Create(descriptor, Location.None, messageArguments); if (project.SupportsCompilation) { // Get diagnostic with effective severity. // Additionally, if the diagnostic was suppressed by a source suppression, effectiveDiagnostics will have a diagnostic with IsSuppressed = true. var compilation = project.GetCompilationAsync(cancellationToken).WaitAndGetResult(cancellationToken); var effectiveDiagnostics = CompilationWithAnalyzers.GetEffectiveDiagnostics(SpecializedCollections.SingletonEnumerable(diagnostic), compilation); if (effectiveDiagnostics == null || effectiveDiagnostics.IsEmpty()) { // Rule is disabled by compilation options. return false; } diagnostic = effectiveDiagnostics.Single(); } diagnosticData = diagnostic.ToDiagnosticData(project); return true; }
public void ChangeSeverity() { _rule = new DiagnosticDescriptor("test", "test", "test", "test", DiagnosticSeverity.Warning, true); }
private static DiagnosticResult GetAdditionalFileResultAt(int line, int column, string path, DiagnosticDescriptor descriptor, params object[] arguments) { return(new DiagnosticResult(descriptor) .WithLocation(path, line, column) .WithArguments(arguments)); }
private static ReportDiagnostic GetEffectiveSeverity(DiagnosticDescriptor descriptor, CompilationOptions options) { return options == null ? MapSeverityToReport(descriptor.DefaultSeverity) : descriptor.GetEffectiveSeverity(options); }
protected static DiagnosticResult GetResultAt(string path, int line, int column, DiagnosticDescriptor rule, params object[] messageArguments) { var location = new DiagnosticResultLocation(path, line, column); return new DiagnosticResult { Locations = new[] { location }, Id = rule.Id, Severity = rule.DefaultSeverity, Message = string.Format(rule.MessageFormat.ToString(), messageArguments) }; }
public CSharpElementAccessTracker(IAnalyzerConfiguration analyzerConfiguration, DiagnosticDescriptor rule) : base(analyzerConfiguration, rule) { }
private static ReportDiagnostic GetEffectiveSeverity(DiagnosticDescriptor descriptor, CompilationOptions options) { return(options == null ? MapSeverityToReport(descriptor.DefaultSeverity) : descriptor.GetEffectiveSeverity(options)); }
public void TestDiagnosticLocalization() { var resourceManager = GetTestResourceManagerInstance(); var arCulture = CultureInfo.CreateSpecificCulture("ar-SA"); var defaultCultureResourceSet = resourceManager.GetResourceSet(CustomResourceManager.DefaultCulture, false, false); var arResourceSet = resourceManager.GetResourceSet(arCulture, false, false); var nameOfResource1 = @"Resource1"; var nameOfResource2 = @"Resource2"; var nameOfResource3 = @"Resource3"; var fixedTitle = defaultCultureResourceSet.GetString(nameOfResource1); var fixedMessageFormat = defaultCultureResourceSet.GetString(nameOfResource2); var fixedDescription = defaultCultureResourceSet.GetString(nameOfResource3); var localizedTitle = arResourceSet.GetString(nameOfResource1); var localizedMessageFormat = arResourceSet.GetString(nameOfResource2); var localizedDescription = arResourceSet.GetString(nameOfResource3); // Test descriptor localization. // Test non-localizable title, description and message. var descriptor = new DiagnosticDescriptor( "Id", fixedTitle, fixedMessageFormat, "Category", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: fixedDescription); Assert.Equal(fixedTitle, descriptor.Title.ToString(arCulture)); Assert.Equal(fixedMessageFormat, descriptor.MessageFormat.ToString(arCulture)); Assert.Equal(fixedDescription, descriptor.Description.ToString(arCulture)); // Test localizable title, description and message. var localizableTitle = new LocalizableResourceString(nameOfResource1, resourceManager, typeof(CustomResourceManager)); var localizableMessageFormat = new LocalizableResourceString(nameOfResource2, resourceManager, typeof(CustomResourceManager)); var localizableDescription = new LocalizableResourceString(nameOfResource3, resourceManager, typeof(CustomResourceManager)); descriptor = new DiagnosticDescriptor( "Id", localizableTitle, localizableMessageFormat, "Category", DiagnosticSeverity.Warning, isEnabledByDefault: true, description: localizableDescription); if (EnsureEnglishUICulture.PreferredOrNull == null) { Assert.Equal<string>(fixedTitle, descriptor.Title.ToString()); Assert.Equal<string>(fixedMessageFormat, descriptor.MessageFormat.ToString()); Assert.Equal<string>(fixedDescription, descriptor.Description.ToString()); } Assert.Equal<string>(fixedTitle, descriptor.Title.ToString(CustomResourceManager.DefaultCulture)); Assert.Equal<string>(fixedMessageFormat, descriptor.MessageFormat.ToString(CustomResourceManager.DefaultCulture)); Assert.Equal<string>(fixedDescription, descriptor.Description.ToString(CustomResourceManager.DefaultCulture)); Assert.Equal(localizedTitle, descriptor.Title.ToString(arCulture)); Assert.Equal(localizedMessageFormat, descriptor.MessageFormat.ToString(arCulture)); Assert.Equal(localizedDescription, descriptor.Description.ToString(arCulture)); // Test diagnostic localization. var localizableDiagnostic = Diagnostic.Create(descriptor, Location.None); if (EnsureEnglishUICulture.PreferredOrNull == null) { // Test non-localized title, description and message. Assert.Equal(fixedTitle, localizableDiagnostic.Descriptor.Title.ToString()); Assert.Equal(fixedMessageFormat, localizableDiagnostic.GetMessage()); Assert.Equal(fixedDescription, localizableDiagnostic.Descriptor.Description.ToString()); } Assert.Equal(fixedTitle, localizableDiagnostic.Descriptor.Title.ToString(CustomResourceManager.DefaultCulture)); Assert.Equal(fixedMessageFormat, localizableDiagnostic.GetMessage(CustomResourceManager.DefaultCulture)); Assert.Equal(fixedDescription, localizableDiagnostic.Descriptor.Description.ToString(CustomResourceManager.DefaultCulture)); // Test localized title, description and message. Assert.Equal(localizedTitle, localizableDiagnostic.Descriptor.Title.ToString(arCulture)); Assert.Equal(localizedMessageFormat, localizableDiagnostic.GetMessage(arCulture)); Assert.Equal(localizedDescription, localizableDiagnostic.Descriptor.Description.ToString(arCulture)); // Test argument formatting for localized string var nameOfResourceWithArguments = @"ResourceWithArguments"; var argument = "formatted"; var localizableResource = new LocalizableResourceString(nameOfResourceWithArguments, resourceManager, typeof(CustomResourceManager), argument); // Verify without culture var defaultCultureLocalizedStringWithArguments = defaultCultureResourceSet.GetString(nameOfResourceWithArguments); var expected = string.Format(defaultCultureLocalizedStringWithArguments, argument); if (EnsureEnglishUICulture.PreferredOrNull == null) { Assert.Equal(expected, localizableResource.ToString()); } Assert.Equal(expected, localizableResource.ToString(CustomResourceManager.DefaultCulture)); // Verify with loc culture var arLocalizedStringWithArguments = arResourceSet.GetString(nameOfResourceWithArguments); expected = string.Format(arLocalizedStringWithArguments, argument); Assert.Equal(expected, localizableResource.ToString(arCulture)); }
internal static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) => new DiagnosticResult(descriptor);
public MyAnalyzer(DiagnosticDescriptor descriptor) { _descriptor = descriptor; }
private void Report(OperationBlockAnalysisContext context, ILocalSymbol local, DiagnosticDescriptor descriptor) { context.ReportDiagnostic(Diagnostic.Create(descriptor, local.Locations.FirstOrDefault())); }
/// <summary> /// Create a diagnostic for exception thrown by the given analyzer. /// </summary> /// <remarks> /// Keep this method in sync with "AnalyzerExecutor.CreateAnalyzerExceptionDiagnostic". /// </remarks> internal static Diagnostic CreateAnalyzerExceptionDiagnostic(DiagnosticAnalyzer analyzer, Exception e) { var analyzerName = analyzer.ToString(); // TODO: It is not ideal to create a new descriptor per analyzer exception diagnostic instance. // However, until we add a LongMessage field to the Diagnostic, we are forced to park the instance specific description onto the Descriptor's Description field. // This requires us to create a new DiagnosticDescriptor instance per diagnostic instance. var descriptor = new DiagnosticDescriptor(AnalyzerExceptionDiagnosticId, title: FeaturesResources.User_Diagnostic_Analyzer_Failure, messageFormat: FeaturesResources.Analyzer_0_threw_an_exception_of_type_1_with_message_2, description: string.Format(FeaturesResources.Analyzer_0_threw_the_following_exception_colon_1, analyzerName, e.CreateDiagnosticDescription()), category: AnalyzerExceptionDiagnosticCategory, defaultSeverity: DiagnosticSeverity.Warning, isEnabledByDefault: true, customTags: WellKnownDiagnosticTags.AnalyzerException); return Diagnostic.Create(descriptor, Location.None, analyzerName, e.GetType(), e.Message); }
static bool DescriptorHasTag(DiagnosticDescriptor desc, string tag) { return(desc.CustomTags.Any(c => CultureInfo.InvariantCulture.CompareInfo.Compare(c, tag) == 0)); }
protected static DiagnosticResult GetCSharpResultAt(int line, int column, DiagnosticDescriptor rule, params object[] messageArguments) { return GetResultAt(CSharpDefaultFilePath, line, column, rule, messageArguments); }
static bool IsConfigurable(DiagnosticDescriptor desc) { return(!DescriptorHasTag(desc, WellKnownDiagnosticTags.NotConfigurable)); }
private static void TestEffectiveSeverity( DiagnosticSeverity defaultSeverity, ReportDiagnostic expectedEffectiveSeverity, Dictionary<string, ReportDiagnostic> specificOptions = null, ReportDiagnostic generalOption = ReportDiagnostic.Default, bool isEnabledByDefault = true) { specificOptions = specificOptions ?? new Dictionary<string, ReportDiagnostic>(); var options = new CSharpCompilationOptions(OutputKind.ConsoleApplication, generalDiagnosticOption: generalOption, specificDiagnosticOptions: specificOptions); var descriptor = new DiagnosticDescriptor(id: "Test0001", title: "Test0001", messageFormat: "Test0001", category: "Test0001", defaultSeverity: defaultSeverity, isEnabledByDefault: isEnabledByDefault); var effectiveSeverity = descriptor.GetEffectiveSeverity(options); Assert.Equal(expectedEffectiveSeverity, effectiveSeverity); }
public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) { return(new DiagnosticResult(descriptor)); }
private void TestGetEffectiveDiagnostics() { var noneDiagDescriptor = new DiagnosticDescriptor("XX0001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Hidden, isEnabledByDefault: true); var infoDiagDescriptor = new DiagnosticDescriptor("XX0002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Info, isEnabledByDefault: true); var warningDiagDescriptor = new DiagnosticDescriptor("XX0003", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault: true); var errorDiagDescriptor = new DiagnosticDescriptor("XX0004", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Error, isEnabledByDefault: true); var noneDiag = CodeAnalysis.Diagnostic.Create(noneDiagDescriptor, Location.None); var infoDiag = CodeAnalysis.Diagnostic.Create(infoDiagDescriptor, Location.None); var warningDiag = CodeAnalysis.Diagnostic.Create(warningDiagDescriptor, Location.None); var errorDiag = CodeAnalysis.Diagnostic.Create(errorDiagDescriptor, Location.None); var diags = new[] { noneDiag, infoDiag, warningDiag, errorDiag }; // Escalate all diagnostics to error. var specificDiagOptions = new Dictionary<string, ReportDiagnostic>(); specificDiagOptions.Add(noneDiagDescriptor.Id, ReportDiagnostic.Error); specificDiagOptions.Add(infoDiagDescriptor.Id, ReportDiagnostic.Error); specificDiagOptions.Add(warningDiagDescriptor.Id, ReportDiagnostic.Error); var options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions); var comp = CreateCompilationWithMscorlib45("", options: options); var effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(diags.Length, effectiveDiags.Length); foreach (var effectiveDiag in effectiveDiags) { Assert.True(effectiveDiag.Severity == DiagnosticSeverity.Error); } // Suppress all diagnostics. specificDiagOptions = new Dictionary<string, ReportDiagnostic>(); specificDiagOptions.Add(noneDiagDescriptor.Id, ReportDiagnostic.Suppress); specificDiagOptions.Add(infoDiagDescriptor.Id, ReportDiagnostic.Suppress); specificDiagOptions.Add(warningDiagDescriptor.Id, ReportDiagnostic.Suppress); specificDiagOptions.Add(errorDiagDescriptor.Id, ReportDiagnostic.Suppress); options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(0, effectiveDiags.Length); // Shuffle diagnostic severity. specificDiagOptions = new Dictionary<string, ReportDiagnostic>(); specificDiagOptions.Add(noneDiagDescriptor.Id, ReportDiagnostic.Info); specificDiagOptions.Add(infoDiagDescriptor.Id, ReportDiagnostic.Hidden); specificDiagOptions.Add(warningDiagDescriptor.Id, ReportDiagnostic.Error); specificDiagOptions.Add(errorDiagDescriptor.Id, ReportDiagnostic.Warn); options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(diags.Length, effectiveDiags.Length); var diagIds = new HashSet<string>(diags.Select(d => d.Id)); foreach (var effectiveDiag in effectiveDiags) { Assert.True(diagIds.Remove(effectiveDiag.Id)); switch (effectiveDiag.Severity) { case DiagnosticSeverity.Hidden: Assert.Equal(infoDiagDescriptor.Id, effectiveDiag.Id); break; case DiagnosticSeverity.Info: Assert.Equal(noneDiagDescriptor.Id, effectiveDiag.Id); break; case DiagnosticSeverity.Warning: Assert.Equal(errorDiagDescriptor.Id, effectiveDiag.Id); break; case DiagnosticSeverity.Error: Assert.Equal(warningDiagDescriptor.Id, effectiveDiag.Id); break; default: throw ExceptionUtilities.Unreachable; } } Assert.Empty(diagIds); }
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/> public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) => CSharpAnalyzerVerifier <TAnalyzer, MSTestVerifier> .Diagnostic(descriptor);
private void TestDisabledDiagnostics() { var disabledDiagDescriptor = new DiagnosticDescriptor("XX001", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault: false); var enabledDiagDescriptor = new DiagnosticDescriptor("XX002", "DummyDescription", "DummyMessage", "DummyCategory", DiagnosticSeverity.Warning, isEnabledByDefault: true); var disabledDiag = CodeAnalysis.Diagnostic.Create(disabledDiagDescriptor, Location.None); var enabledDiag = CodeAnalysis.Diagnostic.Create(enabledDiagDescriptor, Location.None); var diags = new[] { disabledDiag, enabledDiag }; // Verify that only the enabled diag shows up after filtering. var options = TestOptions.ReleaseDll; var comp = CreateCompilationWithMscorlib45("", options: options); var effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(1, effectiveDiags.Length); Assert.Contains(enabledDiag, effectiveDiags); // If the disabled diag was enabled through options, then it should show up. var specificDiagOptions = new Dictionary<string, ReportDiagnostic>(); specificDiagOptions.Add(disabledDiagDescriptor.Id, ReportDiagnostic.Warn); specificDiagOptions.Add(enabledDiagDescriptor.Id, ReportDiagnostic.Suppress); options = TestOptions.ReleaseDll.WithSpecificDiagnosticOptions(specificDiagOptions); comp = CreateCompilationWithMscorlib45("", options: options); effectiveDiags = comp.GetEffectiveDiagnostics(diags).ToArray(); Assert.Equal(1, effectiveDiags.Length); Assert.Contains(disabledDiag, effectiveDiags); }
/// <inheritdoc cref="AnalyzerVerifier{TAnalyzer, TTest, TVerifier}.Diagnostic(DiagnosticDescriptor)"/> public static DiagnosticResult Diagnostic(DiagnosticDescriptor descriptor) => VisualBasicAnalyzerVerifier <TAnalyzer, MSTestVerifier> .Diagnostic(descriptor);
private static DiagnosticData CreateLiveDiagnostic(DiagnosticDescriptor descriptor, DiagnosticData diagnostic) { return new DiagnosticData( descriptor.Id, descriptor.Category, diagnostic.Message, descriptor.MessageFormat.ToString(DiagnosticData.USCultureInfo), diagnostic.Severity, descriptor.DefaultSeverity, descriptor.IsEnabledByDefault, diagnostic.WarningLevel, descriptor.CustomTags.ToImmutableArray(), diagnostic.Properties, diagnostic.Workspace, diagnostic.ProjectId, diagnostic.DataLocation, diagnostic.AdditionalLocations, descriptor.Title.ToString(CultureInfo.CurrentUICulture), descriptor.Description.ToString(CultureInfo.CurrentUICulture), descriptor.HelpLinkUri, isSuppressed: diagnostic.IsSuppressed); }
internal static void AnalyzeSyntaxTree(SyntaxTreeAnalysisContext context, FormatterState formatterState, DiagnosticDescriptor descriptor, OptionSet options) { var tree = context.Tree; var cancellationToken = context.CancellationToken; var oldText = tree.GetText(cancellationToken); var formattingChanges = Formatter.GetFormattedTextChanges(tree.GetRoot(cancellationToken), formatterState, options, cancellationToken); // formattingChanges could include changes that impact a larger section of the original document than // necessary. Before reporting diagnostics, process the changes to minimize the span of individual // diagnostics. foreach (var formattingChange in formattingChanges) { var change = formattingChange; if (change.NewText.Length > 0 && !change.Span.IsEmpty) { // Handle cases where the change is a substring removal from the beginning. In these cases, we want // the diagnostic span to cover the unwanted leading characters (which should be removed), and // nothing more. var offset = change.Span.Length - change.NewText.Length; if (offset >= 0) { if (oldText.GetSubText(new TextSpan(change.Span.Start + offset, change.NewText.Length)).ContentEquals(SourceText.From(change.NewText))) { change = new TextChange(new TextSpan(change.Span.Start, offset), ""); } else { // Handle cases where the change is a substring removal from the end. In these cases, we want // the diagnostic span to cover the unwanted trailing characters (which should be removed), and // nothing more. if (oldText.GetSubText(new TextSpan(change.Span.Start, change.NewText.Length)).ContentEquals(SourceText.From(change.NewText))) { change = new TextChange(new TextSpan(change.Span.Start + change.NewText.Length, offset), ""); } } } } if (change.NewText.Length == 0 && change.Span.IsEmpty) { // No actual change (allows for the formatter to report a NOP change without triggering a // diagnostic that can't be fixed). continue; } var location = Location.Create(tree, change.Span); context.ReportDiagnostic(Diagnostic.Create( descriptor, location, additionalLocations: null, properties: null)); } }
void Report(CompilationAnalysisContext context, IFieldSymbol field, DiagnosticDescriptor descriptor) { context.ReportDiagnostic(Diagnostic.Create(descriptor, field.Locations.FirstOrDefault())); }