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) { 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 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) { 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)); } } }
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) { 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 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)); } }
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) { 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)); } } }
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; } }
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 (!(GetSymbolForDiagnostic(diagnostic, context) is IMethodSymbol symbol)) { return; } if (symbol.IsHarmonyMethod()) { context.ReportSuppression(Suppression.Create(suppressionDescriptor, diagnostic)); } } }
private static void AnalyzeProperties(PropertyDeclarationSyntax declarationSyntax, Diagnostic diagnostic, SuppressionAnalysisContext context, SyntaxNode root) { var symbol = GetSymbol(diagnostic.Location.SourceTree, declarationSyntax.Type, context); if (!symbol.Extends(typeof(UnityEngine.Object))) { return; } //check for valid assignments if (IsAssignedTo(declarationSyntax.Identifier.Text, MethodBodies(root))) { context.ReportSuppression(Suppression.Create(Rule, 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 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)); } }
private static void AnalyzeFields(VariableDeclaratorSyntax declarator, Diagnostic diagnostic, SuppressionAnalysisContext context, SyntaxNode root) { var declarationSyntax = declarator.FirstAncestorOrSelf <FieldDeclarationSyntax>(); //suppress for fields that are not private and not static => statics cannot be set in editor and are not shown in the inspector and cannot be set there if (!declarationSyntax.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.PrivateKeyword) || modifier.IsKind(SyntaxKind.StaticKeyword)) && !declarationSyntax.AttributeLists.Any(attributeList => attributeList.Attributes.Any(attribute => attribute.Name.ToString() == nameof(UnityEngine.HideInInspector)))) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); return; } //check for serializefield attribute => variable could be set in editor if (declarationSyntax.AttributeLists.Any(attributeList => attributeList.Attributes.Any(attribute => attribute.Name.ToString() == nameof(UnityEngine.SerializeField)))) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); return; } var symbol = GetSymbol(diagnostic.Location.SourceTree, declarationSyntax.Declaration.Type, context); if (!symbol.Extends(typeof(UnityEngine.Object))) { return; } var methodBodies = MethodBodies(root) .ToList(); //check for valid assignments if (IsAssignedTo(declarator.Identifier.Text, methodBodies)) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); return; } //check for existence of this variable in any assigned property foreach (string variable in AssignedProperties(root, methodBodies)) { if (variable == declarator.Identifier.Text) { context.ReportSuppression(Suppression.Create(Rule, 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)); } }
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 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)); } } }
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; } if (ShouldBeSuppressed(node)) { context.ReportSuppression(Suppression.Create(SuppressionDescriptors[diagnostic.Id], 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; } // Was the offending variable assigned or verified to be not null inside an Assert.Multiple? // NUnit doesn't throw on failures and therefore the compiler is correct. if (ShouldBeSuppressed(node, out SyntaxNode? suppressionCause) && !IsInsideAssertMultiple(suppressionCause)) { context.ReportSuppression(Suppression.Create(SuppressionDescriptors[diagnostic.Id], diagnostic)); } } }
private void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var node = context.GetSuppressibleNode <SyntaxNode>(diagnostic, n => n is ParameterSyntax || n is MethodDeclarationSyntax); if (node is ParameterSyntax) { node = node .Ancestors() .OfType <MethodDeclarationSyntax>() .FirstOrDefault(); } if (node == null) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(node) is IMethodSymbol methodSymbol)) { return; } var scriptInfo = new ScriptInfo(methodSymbol.ContainingType); if (!scriptInfo.IsMessage(methodSymbol)) { return; } foreach (var suppression in SupportedSuppressions) { if (suppression.SuppressedDiagnosticId == diagnostic.Id) { context.ReportSuppression(Suppression.Create(suppression, diagnostic)); } } }
private static void SuppressMarkMethodsAsStaticDiagnosticIfNeeded(SuppressionAnalysisContext context, Diagnostic diagnostic) { SemanticModel model = context.GetSemanticModel(diagnostic.Location.SourceTree); ISymbol diagnosedSymbol = model.GetDeclaredSymbol(diagnostic.Location.SourceTree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan), context.CancellationToken); if (diagnosedSymbol.Kind != SymbolKind.Method) { return; } if (FindContainingEntryPointTypeAndManagedType(diagnosedSymbol.ContainingType) is (INamedTypeSymbol entryPointMarshallerType, INamedTypeSymbol managedType)) { bool isLinearCollectionMarshaller = ManualTypeMarshallingHelper.IsLinearCollectionEntryPoint(entryPointMarshallerType); (MarshallerShape _, StatefulMarshallerShapeHelper.MarshallerMethods methods) = StatefulMarshallerShapeHelper.GetShapeForType(diagnosedSymbol.ContainingType, managedType, isLinearCollectionMarshaller, context.Compilation); if (methods.IsShapeMethod((IMethodSymbol)diagnosedSymbol)) { // If we are a method of the shape on the stateful marshaller shape, then we need to be our current shape. // So, suppress the diagnostic to make this method static, as that would break the shape. context.ReportSuppression(Suppression.Create(MarkMethodsAsStaticSuppression, diagnostic)); } } }
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); if (!(node is MethodDeclarationSyntax method)) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(method) is IMethodSymbol methodSymbol)) { return; } if (IsSuppressable(methodSymbol)) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); } }
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); if (!(node is MethodDeclarationSyntax method)) { return; } var model = context.GetSemanticModel(diagnostic.Location.SourceTree); if (!(model.GetDeclaredSymbol(method) is IMethodSymbol methodSymbol)) { return; } var typeSymbol = methodSymbol.ContainingType; if (!typeSymbol.Extends(typeof(UnityEngine.MonoBehaviour))) { return; } var references = root .DescendantNodes() .OfType <InvocationExpressionSyntax>() .Where(e => IsMatchingArgument(e, methodSymbol.Name)) .Where(e => IsMatchingIdentifier(e.Expression)); if (references.Any()) { context.ReportSuppression(Suppression.Create(Rule, diagnostic)); } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { foreach (var diagnostic in context.ReportedDiagnostics) { var root = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken); if (root.FindNode(diagnostic.Location.SourceSpan) is { } node&& node.TryFirstAncestorOrSelf(out IdentifierNameSyntax? identifierName) && context.GetSemanticModel(identifierName.SyntaxTree) is { } semanticModel) { if (semanticModel.TryGetSymbol(identifierName, context.CancellationToken, out var symbol) && FieldOrProperty.TryCreate(symbol, out var fieldOrProperty) && fieldOrProperty.Type == KnownSymbols.DependencyPropertyKey) { context.ReportSuppression(Suppression.Create(Descriptor, diagnostic)); } if (identifierName.Parent is MethodDeclarationSyntax method && ClrMethod.IsAttachedSet(method, semanticModel, context.CancellationToken, out _, out _)) { context.ReportSuppression(Suppression.Create(Descriptor, diagnostic)); } } } }
public override void ReportSuppressions(SuppressionAnalysisContext context) { try { // Get expose attribute instance and check Catel.Fody assembly var exposeAttributeType = context.Compilation.GetTypeByMetadataName("Catel.Fody.ExposeAttribute"); if (exposeAttributeType is null) { return; } var supresssionDescriptor = SupportedSuppressions.FirstOrDefault(); foreach (var diagnostic in context.ReportedDiagnostics) { if (context.CancellationToken.IsCancellationRequested) { return; } var diagnosticSourceSyntaxTree = diagnostic.Location.SourceTree; if (diagnosticSourceSyntaxTree is null || !diagnostic.Location.IsInSource) { continue; } var rootSyntax = diagnosticSourceSyntaxTree.GetRoot(context.CancellationToken); var targetSyntax = rootSyntax.FindNode(diagnostic.Location.SourceSpan, false, true); // Look is class weaved by Fody var containerClassSyntax = targetSyntax.FirstAncestor <ClassDeclarationSyntax>(); if (containerClassSyntax is null) { continue; } if (context.CancellationToken.IsCancellationRequested) { return; } var rootSemantic = context.GetSemanticModel(diagnosticSourceSyntaxTree); var containerClassSymbol = (rootSemantic.GetDeclaredSymbol(containerClassSyntax, context.CancellationToken) as ITypeSymbol); if (containerClassSymbol is null) { // Wrong class declaration continue; } if (context.CancellationToken.IsCancellationRequested) { return; } if (!containerClassSymbol.InheritsFrom(CatelBaseClassLookupName)) { continue; } var targetSymbol = rootSemantic.GetDeclaredSymbol(targetSyntax, context.CancellationToken); if (context.CancellationToken.IsCancellationRequested) { return; } var accessModifierNode = targetSyntax.ChildTokens().FirstOrDefault(x => x.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrivateKeyword)); // Check agains "None" kine empty token if (!accessModifierNode.IsKind(Microsoft.CodeAnalysis.CSharp.SyntaxKind.PrivateKeyword)) { // Skip non-private continue; } if (!(targetSymbol is IMethodSymbol method) || !method.Name.StartsWith("On") || !method.Name.EndsWith("Changed")) { continue; } var propertyName = method.Name.ReplaceFirst("On", string.Empty).ReplaceLast("Changed", string.Empty); // Search for property // Step 1: Search by property name through class properties // Step 2: Try to check Expose attributes: // - arguments passed to ctor // - named arguments // This call is more expensive than queries on syntax tree if (containerClassSymbol.TryFindProperty(propertyName, out var weavedPropertySymbol)) { context.ReportSuppression(Suppression.Create(supresssionDescriptor, diagnostic)); return; } var exposedMarkedDeclarations = from descendantNode in containerClassSyntax.DescendantNodes(x => x is ClassDeclarationSyntax || x is PropertyDeclarationSyntax || x is AttributeListSyntax) where descendantNode is AttributeSyntax && string.Equals(descendantNode.GetIdentifier(), CatelFodyAttributeLookupName) select descendantNode.FirstAncestor <PropertyDeclarationSyntax>(); if (IsAnyExposedPropertyDeclarationMatch(exposedMarkedDeclarations, exposeAttributeType, propertyName, rootSemantic, context.CancellationToken)) { context.ReportSuppression(Suppression.Create(supresssionDescriptor, diagnostic)); } } } catch (Exception ex) { throw ex; } }
private static void AnalyzeDiagnostic(Diagnostic diagnostic, SuppressionAnalysisContext context) { var node = diagnostic.Location.SourceTree.GetRoot(context.CancellationToken).FindNode(diagnostic.Location.SourceSpan); if (node == null) { return; } if (!node.IsKind(SyntaxKind.ConditionalExpression)) { return; } var cond = (ConditionalExpressionSyntax)node; switch (cond.Condition.Kind()) { case SyntaxKind.EqualsExpression: case SyntaxKind.NotEqualsExpression: break; default: return; } var binary = (BinaryExpressionSyntax)cond.Condition; if (!binary.Right.IsKind(SyntaxKind.NullLiteralExpression)) { return; } var model = context.GetSemanticModel(node.SyntaxTree); if (model == null) { return; } var type = model.GetTypeInfo(binary.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)); } }