protected override void AnalyzeNode(SyntaxNodeAnalysisContext context) { var semanticModel = context.SemanticModel; var cancellationToken = context.CancellationToken; if (context.Node is InvocationExpressionSyntax invocationExpression && semanticModel.GetSymbolInfo(invocationExpression, cancellationToken).Symbol is IMethodSymbol methodInfo) { if (!AttributeHelper.HasNoAllocationAttribute(methodInfo) && !AttributeHelper.HasIgnoreAllocationAttribute(methodInfo) && !IsWhitelisted(methodInfo) && !IsInSafeScope(semanticModel, invocationExpression)) { ReportError(context, invocationExpression, MethodSymbolSerializer.Serialize(methodInfo), ExternalMethodCallRule); } } if (context.Node is MemberAccessExpressionSyntax memberAccessExpression && semanticModel.GetSymbolInfo(memberAccessExpression, cancellationToken).Symbol is IPropertySymbol propertyInfo) { if (!AttributeHelper.HasNoAllocationAttribute(propertyInfo) && !AttributeHelper.HasNoAllocationAttribute(propertyInfo.GetMethod) && !AttributeHelper.HasIgnoreAllocationAttribute(propertyInfo) && !AttributeHelper.HasIgnoreAllocationAttribute(propertyInfo.GetMethod) && !IsAutoProperty(context, propertyInfo) && !IsWhitelisted(propertyInfo) && !IsInSafeScope(semanticModel, memberAccessExpression)) { ReportError(context, memberAccessExpression, MethodSymbolSerializer.Serialize(propertyInfo), UnsafePropertyAccessRule); } } }
private static IEnumerable <string> GenerateWhitelistSymbol(BaseMethodDeclarationSyntax methodDecl, SemanticModel semanticModel, CancellationToken token) { var body = methodDecl.Body; var statements = body.Statements; var invocationsExpr = statements.OfType <ExpressionStatementSyntax>() .Select(x => x.Expression) .OfType <InvocationExpressionSyntax>(); foreach (var invocationExpr in invocationsExpr) { var symbol = semanticModel.GetSymbolInfo(invocationExpr, token).Symbol; if (symbol?.Name != nameof(AllocationConfiguration.MakeSafe)) { continue; } var arguments = invocationExpr.ArgumentList.Arguments; if (arguments.Count != 1) { continue; } var lambdaExpr = arguments[0].Expression as ParenthesizedLambdaExpressionSyntax; if (lambdaExpr == null) { continue; } var childSymbol = semanticModel.GetSymbolInfo(lambdaExpr.Body, token).Symbol; switch (childSymbol) { case IMethodSymbol methodExpr: { yield return(MethodSymbolSerializer.Serialize(methodExpr)); break; } case IPropertySymbol memberExpr: { yield return(MethodSymbolSerializer.Serialize(memberExpr)); break; } } } }
private bool IsWhitelisted(IPropertySymbol methodInfo) { return(_whitelistedMethods.Contains(MethodSymbolSerializer.Serialize(methodInfo))); }