private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var node = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan); if (node == null) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(node) is IFieldSymbol fieldSymbol)) { return; } if (!fieldSymbol.GetAttributes().Any(a => a.AttributeClass.Matches(typeof(UnityEngine.SerializeField)) || a.AttributeClass.Matches(typeof(UnityEngine.SerializeReference)))) { return; } foreach (var descriptor in SupportedSuppressions.Where(d => d.SuppressedDiagnosticId == diagnostic.Id)) { context.ReportSuppression(Suppression.Create(descriptor, diagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (Diagnostic diagnostic in context.ReportedDiagnostics) { context.ReportSuppression(Suppression.Create(SupportedSuppressions[0], diagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { AnalyzeDiagnostic(diagnostic, context); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { var node = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan); if (node == null) { continue; } if (!(node is ParameterSyntax parameter)) { continue; } // cheapest checks first if (!(parameter.Type is NameSyntax)) { return; } if (context.GetSemanticModel(node.SyntaxTree).GetTypeInfo(parameter.Type).Type.IsCancellationToken()) { context.ReportSuppression(SuppressionDescriptors.CancellationTokenParameterUnused, diagnostic); } } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { SyntaxNode?node = diagnostic.Location.SourceTree?.GetRoot(context.CancellationToken) .FindNode(diagnostic.Location.SourceSpan); if (node is null) { continue; } string fieldName = node.ToString(); var classDeclaration = node.Ancestors().OfType <ClassDeclarationSyntax>().First(); var methods = classDeclaration.Members.OfType <MethodDeclarationSyntax>().ToArray(); foreach (var method in methods) { var allAttributes = method.AttributeLists.SelectMany(list => list.Attributes.Select(a => a.Name.ToString())) .ToImmutableHashSet(); if (allAttributes.Contains("SetUp") || allAttributes.Contains("OneTimeSetUp")) { // Find (OneTime)SetUps method and check for assignment to this field. if (FieldIsAssignedIn(method, fieldName)) { context.ReportSuppression(Suppression.Create(NullableFieldInitializedInSetUp, diagnostic)); } } } } }
private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var root = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken); // We can be called in the context of a method argument or a regular expression if (!(root .FindNode(diagnostic.Location.SourceSpan) .DescendantNodesAndSelf() .OfType <ConditionalExpressionSyntax>() .FirstOrDefault() is ConditionalExpressionSyntax expressionSyntax)) { return; } // We can be tricked by extra parentheses for the condition, so go to the first concrete binary expression if (!(expressionSyntax .Condition .DescendantNodesAndSelf() .OfType <BinaryExpressionSyntax>() .FirstOrDefault() is BinaryExpressionSyntax binaryExpression)) { return; } AnalyzeBinaryExpression(diagnostic, context, binaryExpression); }
public override void ReportSuppressions(SuppressionAnalysisContext context) { var implAttr = context.Compilation.GetTypeByMetadataName(MeansImplicitAssignmentAttribute); foreach (var reportedDiagnostic in context.ReportedDiagnostics) { if (reportedDiagnostic.Id != Diagnostics.MeansImplicitAssignment.SuppressedDiagnosticId) { continue; } var node = reportedDiagnostic.Location.SourceTree?.GetRoot(context.CancellationToken).FindNode(reportedDiagnostic.Location.SourceSpan); if (node == null) { continue; } var symbol = context.GetSemanticModel(reportedDiagnostic.Location.SourceTree).GetDeclaredSymbol(node); if (symbol == null || !symbol.GetAttributes().Any(a => a.AttributeClass?.GetAttributes().Any(attr => SymbolEqualityComparer.Default.Equals(attr.AttributeClass, implAttr)) == true)) { continue; } context.ReportSuppression(Suppression.Create( Diagnostics.MeansImplicitAssignment, reportedDiagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { if (context.Compilation.GetOrCreateTypeByMetadataName(WellKnownTypeNames.XunitFactAttribute) is not { } factAttribute) { return; } var knownTestAttributes = new ConcurrentDictionary <INamedTypeSymbol, bool>(); foreach (var diagnostic in context.ReportedDiagnostics) { // The diagnostic is reported on the test method if (diagnostic.Location.SourceTree is not { } tree) { continue; } var root = tree.GetRoot(context.CancellationToken); var node = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); var semanticModel = context.GetSemanticModel(tree); var declaredSymbol = semanticModel.GetDeclaredSymbol(node, context.CancellationToken); if (declaredSymbol is IMethodSymbol method && method.IsXUnitTestMethod(knownTestAttributes, factAttribute)) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); } } }
private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var fieldDeclarationSyntax = context.GetSuppressibleNode <VariableDeclaratorSyntax>(diagnostic); if (fieldDeclarationSyntax == null) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(fieldDeclarationSyntax) is IFieldSymbol fieldSymbol)) { return; } if (!IsSuppressable(fieldSymbol)) { return; } foreach (var descriptor in SupportedSuppressions.Where(d => d.SuppressedDiagnosticId == diagnostic.Id)) { context.ReportSuppression(Suppression.Create(descriptor, diagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { var suppressAll = IsMarkedWithAttribute(context.Compilation.Assembly, "SmartAnalyzers.CSharpExtensions.Annotations.InitRequiredForNotNullAttribute"); foreach (var diagnostic in context.ReportedDiagnostics) { if (suppressAll) { context.ReportSuppression(Suppression.Create(SuppressionDescriptor, diagnostic)); continue; } var root = diagnostic.Location.SourceTree.GetRoot().FindNode(diagnostic.Location.SourceSpan); if (root is MemberDeclarationSyntax memberDeclaration) { if (HasAttributeWithInitGuarantee(memberDeclaration.AttributeLists)) { context.ReportSuppression(Suppression.Create(SuppressionDescriptor, diagnostic)); } else { var typeDeclaration = SyntaxHelper.FindNearestContainer <TypeDeclarationSyntax>(memberDeclaration); if (typeDeclaration != null && HasAttributeWithInitGuarantee(typeDeclaration.AttributeLists)) { context.ReportSuppression(Suppression.Create(SuppressionDescriptor, diagnostic)); } } } } }
private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var node = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan); if (node == null) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(node) is IFieldSymbol fieldSymbol)) { return; } if (!IsSuppressable(fieldSymbol)) { return; } foreach (var descriptor in SupportedSuppressions.Where(d => d.SuppressedDiagnosticId == diagnostic.Id)) { context.ReportSuppression(Suppression.Create(descriptor, diagnostic)); } }
private ISymbol GetSymbolForDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var syntaxTree = diagnostic.Location.SourceTree; var nodeWithWarning = syntaxTree.GetRoot().FindNode(diagnostic.Location.SourceSpan); var semanticModel = context.GetSemanticModel(syntaxTree); return(semanticModel.GetDeclaredSymbol(nodeWithWarning)); }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { if (diagnostic.GetMessage(CultureInfo.InvariantCulture) is { } message&& IsOut(message)) { context.ReportSuppression(Suppression.Create(Descriptor, diagnostic)); }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (Diagnostic diagnostic in context.ReportedDiagnostics) { if (diagnostic.GetMessage().Contains("TestStruct.X")) // Filtering on the message is gross and terrible. Don't actually do this in a real suppressor. { context.ReportSuppression(Suppression.Create(SupportedSuppressions[0], diagnostic)); } } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { if (diagnostic.Id == MarkMethodsAsStaticSuppression.SuppressedDiagnosticId) { SuppressMarkMethodsAsStaticDiagnosticIfNeeded(context, diagnostic); } } }
private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var binaryExpression = context.GetSuppressibleNode <BinaryExpressionSyntax>(diagnostic); if (binaryExpression == null) { return; } AnalyzeBinaryExpression(diagnostic, context, binaryExpression); }
private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var model = context.GetSemanticModel(diagnostic.Location.SourceTree); var methodDeclarationSyntax = context.GetSuppressibleNode <MethodDeclarationSyntax>(diagnostic); // Reuse the same detection logic regarding decorated methods with *InitializeOnLoadMethodAttribute if (InitializeOnLoadMethodAnalyzer.MethodMatches(methodDeclarationSyntax, model, out _, out _)) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); } }
private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { try { var node = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan); if (node is PropertyDeclarationSyntax prop) { if (!ContainsMustInitialize(prop, context, prop.Identifier.ValueText)) { return; } } else if ((node.Parent.Parent) is FieldDeclarationSyntax f) { if (!ContainsMustInitialize(f, context, (node as VariableDeclaratorSyntax).Identifier.Text)) { return; } } else if (node is ConstructorDeclarationSyntax) { var regex = new Regex(@"(\S*)\s*'(.*)'"); var match = regex.Match(diagnostic.GetMessage()); var type = match.Groups[1].Value; var name = match.Groups[2].Value; if (type == "field") { var fieldDecl = node.Parent.DescendantNodes().OfType <FieldDeclarationSyntax>().First(n => n.Declaration.Variables.Any(v => v.Identifier.ValueText == name)); if (!ContainsMustInitialize(fieldDecl, context, name)) { return; } } else { var propDecl = node.Parent.DescendantNodes().OfType <PropertyDeclarationSyntax>().First(p => p.Identifier.ValueText == name); if (!ContainsMustInitialize(propDecl, context, name)) { return; } } } context.ReportSuppression(Suppression.Create(MustInitializeRule, diagnostic)); } catch (Exception ex) { Logger.LogError(ex); throw; } }
public static T?GetSuppressibleNode <T>(this SuppressionAnalysisContext context, Diagnostic diagnostic, Func <T, bool> predicate) where T : SyntaxNode { var location = diagnostic.Location; var sourceTree = location.SourceTree; var root = sourceTree.GetRoot(context.CancellationToken); return(root? .FindNode(location.SourceSpan) .DescendantNodesAndSelf() .OfType <T>() .FirstOrDefault(predicate)); }
private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var sourceTree = diagnostic.Location.SourceTree; var root = sourceTree.GetRoot(context.CancellationToken); var node = root.FindNode(diagnostic.Location.SourceSpan); var model = context.GetSemanticModel(diagnostic.Location.SourceTree); // Reuse the same detection logic regarding decorated methods with *InitializeOnLoadMethodAttribute if (InitializeOnLoadMethodAnalyzer.MethodMatches(node, model, out _, out _)) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { if (!(diagnostic.Location.SourceTree is { } tree)) { continue; } var root = tree.GetRoot(context.CancellationToken); var node = root.FindNode(diagnostic.Location.SourceSpan, getInnermostNodeForTie: true); var semanticModel = context.GetSemanticModel(tree); var operation = semanticModel.GetOperation(node, context.CancellationToken); if (operation is IPropertyReferenceOperation { Property: { Name: nameof(Type.FullName) }, Instance: ITypeOfOperation {
public override void ReportSuppressions(SuppressionAnalysisContext context) { try { foreach (var diagnostic in context.ReportedDiagnostics) { AnalyzeDiagnostic(diagnostic, context); } } catch (Exception ex) { Logger.LogError(ex); throw; } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { if (!(GetSymbolForDiagnostic(diagnostic, context) is IMethodSymbol symbol)) { return; } if (symbol.IsHarmonyMethod()) { context.ReportSuppression(Suppression.Create(suppressionDescriptor, diagnostic)); } } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { if (!(GetSymbolForDiagnostic(diagnostic, context) is IFieldSymbol symbol)) { return; } if (symbol.GetAttributes().Any(x => IsRightAttribute(x))) { context.ReportSuppression(Suppression.Create(GetSuppressionDescriptor(), diagnostic)); } bool IsRightAttribute(AttributeData attribute) => GetSuppressorAttributeName().Contains(attribute.AttributeClass.Name); } }
private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var sourceTree = diagnostic.Location.SourceTree; var root = sourceTree.GetRoot(context.CancellationToken); var methodDeclarationSyntax = context.GetSuppressibleNode <MethodDeclarationSyntax>(diagnostic); if (methodDeclarationSyntax == null) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(methodDeclarationSyntax) is IMethodSymbol methodSymbol)) { return; } var typeSymbol = methodSymbol.ContainingType; if (!typeSymbol.Extends(typeof(UnityEngine.MonoBehaviour))) { return; } while (typeSymbol.ContainingType != null && typeSymbol.ContainingType.Extends(typeof(UnityEngine.MonoBehaviour))) { typeSymbol = typeSymbol.ContainingType; } var references = new List <InvocationExpressionSyntax>(); foreach (var typeNode in typeSymbol.Locations.Select(location => root.FindNode(location.SourceSpan))) { references.AddRange(typeNode.DescendantNodes() .OfType <InvocationExpressionSyntax>() .Where(e => MethodInvocationAnalyzer.InvocationMatches(e, out string argument) && argument == methodSymbol.Name)); } if (references.Any()) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); } }
private static void AnalyzeBinaryExpression(Diagnostic diagnostic, SuppressionAnalysisContext context, BinaryExpressionSyntax binaryExpression) { switch (binaryExpression.Kind()) { case SyntaxKind.EqualsExpression: case SyntaxKind.NotEqualsExpression: break; default: return; } if (!binaryExpression.Right.IsKind(SyntaxKind.NullLiteralExpression)) { return; } var model = context.GetSemanticModel(binaryExpression.SyntaxTree); if (model == null) { return; } var type = model.GetTypeInfo(binaryExpression.Left); if (type.Type == null) { return; } if (!type.Type.Extends(typeof(UnityEngine.Object))) { return; } if (diagnostic.Id == NullCoalescingRule.SuppressedDiagnosticId) { context.ReportSuppression(Suppression.Create(NullCoalescingRule, diagnostic)); } else if (diagnostic.Id == NullPropagationRule.SuppressedDiagnosticId) { context.ReportSuppression(Suppression.Create(NullPropagationRule, diagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { var root = diagnostic.Location.SourceTree.GetRoot(); var node = root?.FindNode(diagnostic.Location.SourceSpan); var classDeclaration = node?.FirstAncestorOrSelf <ClassDeclarationSyntax>(); if (classDeclaration is null) { continue; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); var symbol = model?.GetDeclaredSymbol(classDeclaration); if (symbol is null) { continue; } var scriptInfo = new ScriptInfo(symbol); if (!scriptInfo.HasMessages) { continue; } var propertyDeclaration = node.FirstAncestorOrSelf <PropertyDeclarationSyntax>(); //handle properties before fields to minimize double checking of potential backing fields if (!(propertyDeclaration is null)) { AnalyzeProperties(propertyDeclaration, diagnostic, context, root); continue; } var fieldDeclaration = context.GetSuppressibleNode <VariableDeclaratorSyntax>(diagnostic); if (fieldDeclaration != null) { AnalyzeFields(fieldDeclaration, diagnostic, context, root); } //TODO handle nullable warnings for constructors => diagnostic location is now on constructor //TODO handle other Unity objects that cannot be initialized => e.g. Unity's new Input system } }
public IList <Diagnostic> Analyze(SyntaxNode elementNode, SuppressionAnalysisContext context, SyntaxTree sourceTree) { var parentNode = elementNode; while (true) { parentNode = parentNode.Parent; if (parentNode == null) { throw new NotSupportedException("No supported node for analyzing found in tree. Aborted"); } if (!_actions.TryGetValue(parentNode.Kind(), out var action)) { continue; } var declaration = parentNode; if (_cachedDiagnostics.TryGetValue(declaration, out var cachedDiagnostics)) { return(cachedDiagnostics); } var semanticModel = context.GetSemanticModel(sourceTree); IList <Diagnostic> detectedDiagnostics = new List <Diagnostic>(); var syntaxNodeAnalysisContext = new SyntaxNodeAnalysisContext( declaration, null, semanticModel, null !, diagnostic => detectedDiagnostics.Add(diagnostic), _ => true, context.CancellationToken ); action(syntaxNodeAnalysisContext); _cachedDiagnostics.Add(declaration, detectedDiagnostics); return(detectedDiagnostics); } }
private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var location = diagnostic.Location; var sourceTree = location.SourceTree; var root = sourceTree.GetRoot(context.CancellationToken); var node = root.FindNode(location.SourceSpan); var model = context.GetSemanticModel(location.SourceTree); var symbols = new List <ISymbol>(); switch (node) { case MethodDeclarationSyntax method: symbols.Add(model.GetDeclaredSymbol(method)); break; case VariableDeclaratorSyntax vdec: symbols.Add(model.GetDeclaredSymbol(vdec)); break; case FieldDeclarationSyntax fdec: symbols.AddRange(fdec.Declaration.Variables.Select(v => model.GetDeclaredSymbol(v))); break; } var reportableSymbols = symbols .Where(IsReportable) .ToList(); if (!reportableSymbols.Any()) { return; } if (reportableSymbols.FirstOrDefault() is IMethodSymbol) { context.ReportSuppression(Suppression.Create(ContextMenuRule, diagnostic)); } else { foreach (var descriptor in SupportedSuppressions.Where(d => d.SuppressedDiagnosticId == diagnostic.Id)) { context.ReportSuppression(Suppression.Create(descriptor, diagnostic)); } } }
private void AnalyzeBinaryExpression(Diagnostic diagnostic, SuppressionAnalysisContext context, BinaryExpressionSyntax binaryExpression) { switch (binaryExpression.Kind()) { case SyntaxKind.EqualsExpression: case SyntaxKind.NotEqualsExpression: if (!binaryExpression.Right.IsKind(SyntaxKind.NullLiteralExpression)) { return; } break; case SyntaxKind.CoalesceExpression: break; default: return; } var model = context.GetSemanticModel(binaryExpression.SyntaxTree); if (model == null) { return; } var type = model.GetTypeInfo(binaryExpression.Left); if (type.Type == null) { return; } if (!type.Type.Extends(typeof(UnityEngine.Object))) { return; } var rule = SupportedSuppressions.FirstOrDefault(r => r.SuppressedDiagnosticId == diagnostic.Id); if (rule != null) { context.ReportSuppression(Suppression.Create(rule, diagnostic)); } }