private static bool IsTestMethod(MethodDeclarationSyntax method) { var methodAttributes = new[] { "Test", "TestMethod", "Fact" }; var attributes = method.AttributeLists.FirstOrDefault()?.Attributes; if (attributes == null) { return false; } return attributes.Value.Any(x => methodAttributes.Contains(x.Name.ToString())); }
private void AnalyzeSymbol(SyntaxNodeAnalysisContext context) { var argumentList = (GenericNameSyntax) context.Node; var identifier = "Unnamed variable"; var ancestorNodes = new[] { SyntaxKind.LocalDeclarationStatement, SyntaxKind.FieldDeclaration, SyntaxKind.Parameter, SyntaxKind.PropertyDeclaration }; var parentNode = context.Node.AncestorsAndSelf().FirstOrDefault(x => ancestorNodes.Contains(x.Kind())); // We're having a return type if (context.Node.Parent is MethodDeclarationSyntax) { identifier = "Return statement"; } if (parentNode != null) { switch (parentNode.Kind()) { case SyntaxKind.LocalDeclarationStatement: { identifier = ((LocalDeclarationStatementSyntax) parentNode).Declaration?.Variables.FirstOrDefault()?.Identifier.Text; break; } case SyntaxKind.FieldDeclaration: { identifier = ((FieldDeclarationSyntax) parentNode).Declaration?.Variables.FirstOrDefault()?.Identifier.Text; break; } case SyntaxKind.Parameter: { identifier = ((ParameterSyntax) parentNode).Identifier.Text; break; } case SyntaxKind.TypeParameter: { identifier = ((TypeParameterSyntax) parentNode).Identifier.Text; break; } case SyntaxKind.PropertyDeclaration: { identifier = ((PropertyDeclarationSyntax) parentNode).Identifier.Text; break; } } } Handle(identifier, context.Node.GetLocation(), argumentList, context); }
public override void Initialize(AnalysisContext analysisContext) { analysisContext.RegisterCompilationStartAction( compilationStartAnalysisContext => { Compilation compilation = compilationStartAnalysisContext.Compilation; INamedTypeSymbol[] nativeResourceTypes = new[] { WellKnownTypes.IntPtr(compilation), WellKnownTypes.UIntPtr(compilation), WellKnownTypes.HandleRef(compilation) }; compilationStartAnalysisContext.RegisterOperationAction( operationAnalysisContext => { var assignment = (IAssignmentExpression)operationAnalysisContext.Operation; IReferenceExpression target = assignment.Target; if (target == null) { // This can happen if the left-hand side is an undefined symbol. return; } if (target.Kind != OperationKind.FieldReferenceExpression) { return; } var fieldReference = (IFieldReferenceExpression)target; var field = fieldReference.Member as IFieldSymbol; if (field == null || field.Kind != SymbolKind.Field || field.IsStatic) { return; } if (!nativeResourceTypes.Contains(field.Type)) { return; } INamedTypeSymbol containingType = field.ContainingType; if (containingType == null || containingType.IsValueType) { return; } if (!containingType.AllInterfaces.Contains(WellKnownTypes.IDisposable(compilation))) { return; } if (containingType.HasFinalizer()) { return; } if (assignment.Value == null || assignment.Value.Kind != OperationKind.InvocationExpression) { return; } var invocation = (IInvocationExpression)assignment.Value; if (invocation == null) { return; } IMethodSymbol method = invocation.TargetMethod; // TODO: What about COM? if (method.GetDllImportData() == null) { return; } operationAnalysisContext.ReportDiagnostic(containingType.CreateDiagnostic(Rule)); }, OperationKind.AssignmentExpression); }); }