Here are the examples of the csharp api Microsoft.CodeAnalysis.Diagnostics.OperationAnalysisContext.ReportDiagnostic(Microsoft.CodeAnalysis.Diagnostic) taken from open source projects. By voting up you can indicate which examples are most useful and appropriate.
94 Examples
19
Source : BlockCallsAnalyzer.cs
with MIT License
from Azure
with MIT License
from Azure
private void HandleMemberReference(OperationreplacedysisContext operationContext)
{
var memberReference = (IMemberReferenceOperation)operationContext.Operation;
if (_blockConfig != null)
{
#region Handle property reference
string containingType = memberReference.Member.ContainingType.ToString();
if (!string.IsNullOrWhiteSpace(containingType) && _blockConfig.MatchesClreplacedToBlock(containingType))
{
_blockConfig.GetMatchingClreplacedConfig(containingType)?.ForEach(cConfig => {
if (cConfig.MethodsToBlock?.Count > 0)
{
BlockConfig.GetMatchingBlockMessageList(cConfig.PropertiesToBlock, memberReference.Member.Name)?.ForEach(strMessage =>
{
operationContext.ReportDiagnostic(memberReference.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(strMessage) ? new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, memberReference.Member.Name, containingType) } : new string[] { strMessage }
));
});
}
else
{
//No specific methods to block was indicated, however the type name did match the config, so the default action is to block all methods from this type
operationContext.ReportDiagnostic(memberReference.CreateDiagnostic(blockCallsDiagnosticDescriptor,
new string[] { string.Format(DEFAULT_PROPERTY_ACCESS_BLOCK_MESSAGE_FORMAT, "any property", containingType) }
));
}
});
}
#endregion
}
}
19
Source : BlockCallsAnalyzer.cs
with MIT License
from Azure
with MIT License
from Azure
private void HandleInvocation(OperationreplacedysisContext operationContext)
{
var invocation = (IInvocationOperation)operationContext.Operation;
if (_blockConfig != null)
{
#region Handle PInvoke method calls
if (invocation.TargetMethod.IsExtern && invocation.TargetMethod.GetDllImportData() != null)
{
//This is a PInvoke call
string targetPInvokeDll = invocation.TargetMethod.GetDllImportData().ModuleName;
if (_blockConfig.MatchesPInvokeToBlock(targetPInvokeDll))
{
//Current DLL name is in the list of PInvoke DLL's that should be blocked.
//Evaluate if the specific call is blocked
_blockConfig.GetMatchingPInvokeConfig(targetPInvokeDll)?.ForEach(piConfig => {
if (piConfig.MethodsToBlock?.Count > 0)
{
string pInvokeFunctionName = !string.IsNullOrWhiteSpace(invocation.TargetMethod.GetDllImportData().EntryPointName)? invocation.TargetMethod.GetDllImportData().EntryPointName : invocation.TargetMethod.Name;
BlockConfig.GetMatchingBlockMessageList(piConfig.MethodsToBlock, pInvokeFunctionName)?.ForEach(strMessage =>
{
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(strMessage) ? new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, invocation.TargetMethod.Name, targetPInvokeDll) } : new string[] { strMessage }
));
});
}
else
{
//No specific methods to block was indicated, however the DLL name did match the config, so the default action is to block all methods from this DLL
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(piConfig.MessageToShowWhenBlocked) ? new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, "any method", targetPInvokeDll) } : new string[] { piConfig.MessageToShowWhenBlocked }
));
}
});
}
}
#endregion
#region Handle clreplaced and instance method invocation
string containingType = invocation.TargetMethod.ContainingType.ToString();
if (!string.IsNullOrWhiteSpace(containingType) && _blockConfig.MatchesClreplacedToBlock(containingType))
{
_blockConfig.GetMatchingClreplacedConfig(containingType)?.ForEach(cConfig => {
if (cConfig.MethodsToBlock?.Count > 0)
{
BlockConfig.GetMatchingBlockMessageList(cConfig.MethodsToBlock, invocation.TargetMethod.Name)?.ForEach(strMessage =>
{
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(strMessage) ? new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, invocation.TargetMethod.Name, containingType) } : new string[] { strMessage }
));
});
}
else
{
//No specific methods to block was indicated, however the type name did match the config, so the default action is to block all methods from this type
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, "any method", containingType) }
));
}
});
}
containingType = invocation.Type.ToString(); //This is required to evaluate expressions where invocations take a generic Type as a parameter
if (!string.IsNullOrWhiteSpace(containingType) && _blockConfig.MatchesClreplacedToBlock(containingType))
{
bool blockedObjectCreation = false;
foreach (ClreplacedBlockConfig clreplacedConfig in _blockConfig.GetMatchingClreplacedConfig(containingType)?.Where(cConfig => cConfig?.IsObjectCreationBlocked == true))
{
blockedObjectCreation = true;
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(clreplacedConfig.MessageToShowWhenBlocked) ? new string[] { string.Format(DEFAULT_INSTANTIATION_BLOCK_MESSAGE_FORMAT, containingType) } : new string[] { clreplacedConfig.MessageToShowWhenBlocked }
));
}
if(!blockedObjectCreation)
{
_blockConfig.GetMatchingClreplacedConfig(containingType)?.ForEach(cConfig => {
if (cConfig.MethodsToBlock?.Count > 0)
{
BlockConfig.GetMatchingBlockMessageList(cConfig.MethodsToBlock, invocation.TargetMethod.Name)?.ForEach(strMessage =>
{
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(strMessage) ? new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, invocation.TargetMethod.Name, containingType) } : new string[] { strMessage }
));
});
}
else
{
//No specific methods to block was indicated, however the type name did match the config, so the default action is to block all methods from this type
operationContext.ReportDiagnostic(invocation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
new string[] { string.Format(DEFAULT_INVOCATION_BLOCK_MESSAGE_FORMAT, "any method", containingType) }
));
}
});
}
}
#endregion
}
}
19
Source : BlockCallsAnalyzer.cs
with MIT License
from Azure
with MIT License
from Azure
private void HandleObjectCreation(OperationreplacedysisContext operationContext)
{
var objectCreation = (IObjectCreationOperation)operationContext.Operation;
if (_blockConfig != null)
{
#region Handle object instantiation
string typeBeingInstantiated = objectCreation.Type.ToString();
if (!string.IsNullOrWhiteSpace(typeBeingInstantiated) && _blockConfig.MatchesClreplacedToBlock(typeBeingInstantiated))
{
foreach (ClreplacedBlockConfig clreplacedConfig in _blockConfig.GetMatchingClreplacedConfig(typeBeingInstantiated)?.Where(cConfig => cConfig?.IsObjectCreationBlocked == true))
{
operationContext.ReportDiagnostic(objectCreation.CreateDiagnostic(blockCallsDiagnosticDescriptor,
string.IsNullOrWhiteSpace(clreplacedConfig.MessageToShowWhenBlocked)? new string[] { string.Format(DEFAULT_INSTANTIATION_BLOCK_MESSAGE_FORMAT, typeBeingInstantiated) } : new string[] { clreplacedConfig.MessageToShowWhenBlocked }
));
}
}
#endregion
}
}
19
Source : AsyncAnalyzer.cs
with MIT License
from Azure
with MIT License
from Azure
private static void ReportConfigureAwaitDiagnostic(OperationreplacedysisContext context, IOperation operation)
{
var location = operation.Syntax.GetLocation();
var diagnostic = Diagnostic.Create(AZC0100, location);
context.ReportDiagnostic(diagnostic);
}
19
Source : TaskCompletionSourceAnalyzer.cs
with MIT License
from Azure
with MIT License
from Azure
private static void ReportDiagnostics(OperationreplacedysisContext context, TextSpan textSpan)
{
var location = context.Operation.Syntax.SyntaxTree.GetLocation(textSpan);
var diagnostic = Diagnostic.Create(Descriptors.AZC0013, location);
context.ReportDiagnostic(diagnostic);
}
19
Source : UniTaskAnalyzer.cs
with MIT License
from Cysharp
with MIT License
from Cysharp
private static void replacedyzeOperation(OperationreplacedysisContext context)
{
var token = context.Compilation.GetTypeByMetadataName(typeof(CancellationToken).FullName);
if (token == null) return;
if (context.Operation is IInvocationOperation invocation)
{
foreach (var arg in invocation.Arguments)
{
if (arg.ArgumentKind == ArgumentKind.DefaultValue)
{
if (SymbolEqualityComparer.Default.Equals(arg.Parameter.Type, token))
{
var diagnostic = Diagnostic.Create(Rule, arg.Syntax.GetLocation());
context.ReportDiagnostic(diagnostic);
}
}
}
}
}
19
Source : IMM005.cs
with MIT License
from dbolin
with MIT License
from dbolin
private static void CheckOperation(IOperation operation, OperationreplacedysisContext context, bool hasReportedThisCapture)
{
if(operation is IInstanceReferenceOperation op
&& op.ReferenceKind == InstanceReferenceKind.ContainingTypeInstance
&& (op.Parent is IArgumentOperation
|| op.Parent is ISymbolInitializerOperation
|| op.Parent is IreplacedignmentOperation))
{
var diagnostic = Diagnostic.Create(Rule, op.Syntax.GetLocation());
context.ReportDiagnostic(diagnostic);
}
bool reportedThisCapture = false;
if (!hasReportedThisCapture)
{
if (operation.Syntax is AnonymousFunctionExpressionSyntax syntax)
{
var model = operation.SemanticModel;
var dataFlowreplacedysis = model.replacedyzeDataFlow(syntax);
var capturedVariables = dataFlowreplacedysis.Captured;
if (capturedVariables.Any(x => x is IParameterSymbol p && p.IsThis))
{
var diagnostic = Diagnostic.Create(Rule, operation.Syntax.GetLocation());
context.ReportDiagnostic(diagnostic);
reportedThisCapture = true;
}
}
}
foreach (var child in operation.Children)
{
CheckOperation(child, context, reportedThisCapture || hasReportedThisCapture);
}
}
19
Source : PointerMemberAnalyzer.cs
with MIT License
from devlooped
with MIT License
from devlooped
void replacedyzeOperation(OperationreplacedysisContext context)
{
var invocation = (IInvocationOperation)context.Operation;
// Get the matching symbol for the given generator attribute from the current compilation.
var generator = context.Compilation.GetTypeByMetadataName(generatorAttribute.FullName);
if (generator == null)
return;
if (invocation.TargetMethod.GetAttributes().Any(x =>
SymbolEqualityComparer.Default.Equals(x.AttributeClreplaced, generator)))
{
var args = invocation.TargetMethod.TypeArguments
.OfType<INamedTypeSymbol>()
.Where(t => t.GetMembers()
.OfType<IMethodSymbol>()
.SelectMany(method => method.Parameters)
.Any(parameter => parameter.Type.Kind == SymbolKind.PointerType))
.ToArray();
if (args.Length > 0)
{
var diagnostic = Diagnostic.Create(
AvatarDiagnostics.PointerMember,
invocation.Syntax.GetLocation(),
string.Join(", ", args.Select(t => t.Name)));
context.ReportDiagnostic(diagnostic);
}
}
}
19
Source : ValidateTypesAnalyzer.cs
with MIT License
from devlooped
with MIT License
from devlooped
void replacedyzeOperation(OperationreplacedysisContext context)
{
var invocation = (IInvocationOperation)context.Operation;
// Get the matching symbol for the given generator attribute from the current compilation.
var generator = context.Compilation.GetTypeByMetadataName(generatorAttribute.FullName);
if (generator == null)
return;
if (invocation.TargetMethod.GetAttributes().Any(x => SymbolEqualityComparer.Default.Equals(x.AttributeClreplaced, generator)))
{
foreach (var enumType in invocation.TargetMethod.TypeArguments.Where(x => x.TypeKind == TypeKind.Enum))
{
context.ReportDiagnostic(Diagnostic.Create(
AvatarDiagnostics.EnumType,
invocation.Syntax.GetLocation(),
enumType.Name));
}
var clreplacedes = invocation.TargetMethod.TypeArguments.Where(x => x.TypeKind == TypeKind.Clreplaced).ToArray();
if (clreplacedes.Length > 1)
{
context.ReportDiagnostic(Diagnostic.Create(
AvatarDiagnostics.DuplicateBaseType,
invocation.Syntax.GetLocation()));
}
if (clreplacedes.Length == 1)
{
if (clreplacedes[0].IsSealed)
{
context.ReportDiagnostic(Diagnostic.Create(
AvatarDiagnostics.SealedBaseType,
invocation.Syntax.GetLocation(),
clreplacedes[0].Name));
}
else if (invocation.TargetMethod.TypeArguments.IndexOf(clreplacedes[0]) != 0)
{
context.ReportDiagnostic(Diagnostic.Create(
AvatarDiagnostics.BaseTypeNotFirst,
invocation.Syntax.GetLocation(),
clreplacedes[0].Name));
}
}
}
}
19
Source : TransitionAnalyzer.cs
with MIT License
from innerspacetrainings
with MIT License
from innerspacetrainings
private static void replacedyzeChildTransition(OperationreplacedysisContext context)
{
var invocationOperation = (IInvocationOperation)context.Operation;
if (!invocationOperation.Syntax.Parent.IsKind(SyntaxKind.Argument)) return;
var atomicStateNodeDefinitionType = context.Compilation.GetTypeByMetadataName("Statecharts.NET.Model.IAtomicStatenodeDefinition");
if (atomicStateNodeDefinitionType == null) return;
var isAtomicStatenodeDefinition = invocationOperation.Type.AllInterfaces.Any(i => i.Equals(atomicStateNodeDefinitionType));
if (!isAtomicStatenodeDefinition) return;
var statenodeName = ((LiteralExpressionSyntax)invocationOperation.Syntax.DescendantNodes()
.FirstOrDefault(node => node.IsKind(SyntaxKind.StringLiteralExpression)))?.Token.ValueText;
var childTransitionExpressions = invocationOperation
.Descendants()
.OfType<IInvocationOperation>()
.Where(invocation => invocation.TargetMethod.Name == "Child")
.Select(operation => (InvocationExpressionSyntax)operation.Syntax);
foreach (var expression in childTransitionExpressions)
{
var location = Location.Create(
expression.SyntaxTree,
TextSpan.FromBounds(
expression.ArgumentList.SpanStart - 5, // 5: "Child"
expression.ArgumentList.CloseParenToken.Span.End));
context.ReportDiagnostic(Diagnostic.Create(NoChildTransitionOnAtomicStatenode, location, statenodeName));
}
}
19
Source : ContextExtensions.cs
with MIT License
from meziantou
with MIT License
from meziantou
public static void ReportDiagnostic(this OperationreplacedysisContext context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IInvocationOperation operation, DiagnosticReportOptions options, params string[] messageArgs)
{
if (options.HasFlag(DiagnosticReportOptions.ReportOnMethodName) &&
operation.Syntax.ChildNodes().FirstOrDefault() is MemberAccessExpressionSyntax memberAccessExpression)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, memberAccessExpression.Name.GetLocation(), properties, messageArgs));
return;
}
context.ReportDiagnostic(descriptor, properties, operation, messageArgs);
}
19
Source : ContextExtensions.cs
with MIT License
from meziantou
with MIT License
from meziantou
public static void ReportDiagnostic(this OperationreplacedysisContext context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, SyntaxToken token, params string[] messageArgs)
{
context.ReportDiagnostic(CreateDiagnostic(descriptor, token.GetLocation(), properties, messageArgs));
}
19
Source : ContextExtensions.cs
with MIT License
from meziantou
with MIT License
from meziantou
public static void ReportDiagnostic(this OperationreplacedysisContext context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IOperation operation, params string[] messageArgs)
{
context.ReportDiagnostic(CreateDiagnostic(descriptor, operation.Syntax.GetLocation(), properties, messageArgs));
}
19
Source : ContextExtensions.cs
with MIT License
from meziantou
with MIT License
from meziantou
public static void ReportDiagnostic(this OperationreplacedysisContext context, DiagnosticDescriptor descriptor, ImmutableDictionary<string, string?>? properties, IInvocationOperation operation, DiagnosticReportOptions options, params string[] messageArgs)
{
if (options.HasFlag(DiagnosticReportOptions.ReportOnMethodName) &&
operation.Syntax.ChildNodes().FirstOrDefault() is MemberAccessExpressionSyntax memberAccessExpression)
{
context.ReportDiagnostic(Diagnostic.Create(descriptor, memberAccessExpression.Name.GetLocation(), properties, messageArgs));
return;
}
context.ReportDiagnostic(descriptor, properties, operation, messageArgs);
}
19
Source : AnonymousDelegatesShouldNotBeUsedToUnsubscribeFromEventsAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeOperation(OperationreplacedysisContext context)
{
var operation = (IEventreplacedignmentOperation)context.Operation;
if (operation.Adds)
return;
var handler = operation.HandlerValue;
while (handler is IConversionOperation op)
{
handler = op.Operand;
}
if (handler != null && handler is IDelegateCreationOperation delegateCreation)
{
if (delegateCreation.Target is IAnonymousFunctionOperation)
{
context.ReportDiagnostic(s_rule, operation);
}
}
}
19
Source : ArgumentExceptionShouldSpecifyArgumentNameAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var op = (IObjectCreationOperation)context.Operation;
if (op == null)
return;
var type = op.Type;
if (type == null)
return;
var exceptionType = context.Compilation.GetTypeByMetadataName("System.ArgumentException");
if (exceptionType == null)
return;
if (!type.IsEqualTo(exceptionType) && !type.InheritsFrom(exceptionType))
return;
var parameterName = "paramName";
if (type.IsEqualTo(context.Compilation.GetTypeByMetadataName("System.ComponentModel.InvalidEnumArgumentException")))
{
parameterName = "argumentName";
}
foreach (var argument in op.Arguments)
{
if (argument.Parameter == null || !string.Equals(argument.Parameter.Name, parameterName, StringComparison.Ordinal))
continue;
if (argument.Value.ConstantValue.HasValue)
{
if (argument.Value.ConstantValue.Value is string value)
{
var parameterNames = GetParameterNames(op);
if (parameterNames.Contains(value, StringComparer.Ordinal))
{
if (!(argument.Value is INameOfOperation))
{
var properties = ImmutableDictionary<string, string?>.Empty.Add(ArgumentNameKey, value);
context.ReportDiagnostic(s_nameofRule, properties, argument.Value);
}
return;
}
context.ReportDiagnostic(s_rule, argument, $"'{value}' is not a valid parameter name");
return;
}
}
// Cannot determine the value of the argument
return;
}
context.ReportDiagnostic(Diagnostic.Create(s_rule, op.Syntax.GetLocation(), $"Use an overload of '{type.ToDisplayString()}' with the parameter name"));
}
19
Source : ArgumentExceptionShouldSpecifyArgumentNameAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var op = (IObjectCreationOperation)context.Operation;
if (op == null)
return;
var type = op.Type;
if (type == null)
return;
var exceptionType = context.Compilation.GetTypeByMetadataName("System.ArgumentException");
if (exceptionType == null)
return;
if (!type.IsEqualTo(exceptionType) && !type.InheritsFrom(exceptionType))
return;
var parameterName = "paramName";
if (type.IsEqualTo(context.Compilation.GetTypeByMetadataName("System.ComponentModel.InvalidEnumArgumentException")))
{
parameterName = "argumentName";
}
foreach (var argument in op.Arguments)
{
if (argument.Parameter == null || !string.Equals(argument.Parameter.Name, parameterName, StringComparison.Ordinal))
continue;
if (argument.Value.ConstantValue.HasValue)
{
if (argument.Value.ConstantValue.Value is string value)
{
var parameterNames = GetParameterNames(op);
if (parameterNames.Contains(value, StringComparer.Ordinal))
{
if (!(argument.Value is INameOfOperation))
{
var properties = ImmutableDictionary<string, string?>.Empty.Add(ArgumentNameKey, value);
context.ReportDiagnostic(s_nameofRule, properties, argument.Value);
}
return;
}
context.ReportDiagnostic(s_rule, argument, $"'{value}' is not a valid parameter name");
return;
}
}
// Cannot determine the value of the argument
return;
}
context.ReportDiagnostic(Diagnostic.Create(s_rule, op.Syntax.GetLocation(), $"Use an overload of '{type.ToDisplayString()}' with the parameter name"));
}
19
Source : AvoidComparisonWithBoolConstantAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeBinaryOperation(OperationreplacedysisContext context)
{
var binaryOperation = (IBinaryOperation)context.Operation;
if (binaryOperation.OperatorKind != BinaryOperatorKind.Equals &&
binaryOperation.OperatorKind != BinaryOperatorKind.NotEquals)
{
return;
}
// There must be 2 valid operands
if (binaryOperation.LeftOperand?.Type is null || binaryOperation.RightOperand?.Type is null)
return;
// Operands must be explicit
if (binaryOperation.LeftOperand.IsImplicit || binaryOperation.RightOperand.IsImplicit)
return;
// Neither operand can be dynamic
if (binaryOperation.LeftOperand.Type.TypeKind == TypeKind.Dynamic || binaryOperation.RightOperand.Type.TypeKind == TypeKind.Dynamic)
return;
IOperation nodeToKeep;
IOperation nodeToRemove;
if (IsConstantBool(binaryOperation.LeftOperand))
{
nodeToKeep = binaryOperation.RightOperand;
nodeToRemove = binaryOperation.LeftOperand;
}
else if (IsConstantBool(binaryOperation.RightOperand))
{
nodeToKeep = binaryOperation.LeftOperand;
nodeToRemove = binaryOperation.RightOperand;
}
else
{
return;
}
// The fixer will need to prefix the remaining operand with '!' if the original comparison is "!= true" or "== false"
var logicalNotOperatorNeeded = (bool)nodeToRemove.ConstantValue.Value! ?
binaryOperation.OperatorKind == BinaryOperatorKind.NotEquals :
binaryOperation.OperatorKind == BinaryOperatorKind.Equals;
var properties = ImmutableDictionary.Create<string, string?>()
.Add("NodeToKeepSpanStart", nodeToKeep.Syntax.Span.Start.ToString(CultureInfo.InvariantCulture))
.Add("NodeToKeepSpanLength", nodeToKeep.Syntax.Span.Length.ToString(CultureInfo.InvariantCulture))
.Add("LogicalNotOperatorNeeded", logicalNotOperatorNeeded.ToString());
var operatorTokenLocation = ((BinaryExpressionSyntax)binaryOperation.Syntax).OperatorToken.GetLocation();
var diagnostic = Diagnostic.Create(s_rule, operatorTokenLocation, properties);
context.ReportDiagnostic(diagnostic);
}
19
Source : AvoidLockingOnPubliclyAccessibleInstanceAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeOperation(OperationreplacedysisContext context)
{
var operation = (ILockOperation)context.Operation;
if (operation.LockedValue is ITypeOfOperation)
{
context.ReportDiagnostic(s_rule, operation.LockedValue);
}
else if (operation.LockedValue is IInstanceReferenceOperation)
{
context.ReportDiagnostic(s_rule, operation.LockedValue);
}
else if (operation.LockedValue is IFieldReferenceOperation fieldReferenceOperation && fieldReferenceOperation.Field.IsVisibleOutsideOfreplacedembly())
{
context.ReportDiagnostic(s_rule, operation.LockedValue);
}
else if (operation.LockedValue is ILocalReferenceOperation localReference && localReference.Local.Type.IsEqualTo(context.Compilation.GetTypeByMetadataName("System.Type")))
{
context.ReportDiagnostic(s_rule, operation.LockedValue);
}
}
19
Source : AwaitTaskBeforeDisposingResourcesAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private void replacedyzeReturn(OperationreplacedysisContext context)
{
var op = (IReturnOperation)context.Operation;
var returnedValue = op.ReturnedValue;
if (returnedValue is null)
return;
var taskSymbol = context.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task");
var taskOfTSymbol = context.Compilation.GetTypeByMetadataName("System.Threading.Tasks.Task`1");
var valueTaskSymbol = context.Compilation.GetTypeByMetadataName("System.Threading.Tasks.ValueTask");
var valueTaskOfTSymbol = context.Compilation.GetTypeByMetadataName("System.Threading.Tasks.ValueTask`1");
if (IsTaskLike(returnedValue.Type))
{
// Must be in a using block
if (!IsInUsingOperation(op))
return;
if (!NeedAwait(returnedValue))
return;
context.ReportDiagnostic(s_rule, op);
}
static bool IsInUsingOperation(IOperation operation)
{
foreach (var parent in operation.Ancestors())
{
if (parent is IAnonymousFunctionOperation or ILocalFunctionOperation)
return false;
if (parent is IUsingOperation)
return true;
}
19
Source : DoNotNaNInComparisonsAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private void replacedyzeOperand(OperationreplacedysisContext context, IOperation operation)
{
while (operation is IConversionOperation conversion)
{
operation = conversion.Operand;
}
if (operation is IMemberReferenceOperation memberReference)
{
if (memberReference.Member.IsEqualTo(DoubleNaN))
{
context.ReportDiagnostic(s_rule, operation, "System.Double");
}
else if (memberReference.Member.IsEqualTo(SingleNaN))
{
context.ReportDiagnostic(s_rule, operation, "System.Single");
}
else if (memberReference.Member.IsEqualTo(HalfNaN))
{
context.ReportDiagnostic(s_rule, operation, "System.Half");
}
}
}
19
Source : DoNotRaiseApplicationExceptionAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context, INamedTypeSymbol reservedExceptionType)
{
var operation = (IThrowOperation)context.Operation;
if (operation == null || operation.Exception == null)
return;
var exceptionType = operation.Exception.GetActualType();
if (exceptionType.IsEqualTo(reservedExceptionType))
{
context.ReportDiagnostic(s_rule, operation);
}
}
19
Source : DoNotRaiseReservedExceptionTypeAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context, IEnumerable<INamedTypeSymbol> reservedExceptionTypes)
{
var operation = (IThrowOperation)context.Operation;
if (operation == null || operation.Exception == null)
return;
var exceptionType = operation.Exception.GetActualType();
if (exceptionType == null)
return;
if (reservedExceptionTypes.Any(type => exceptionType.IsEqualTo(type) || exceptionType.InheritsFrom(type)))
{
context.ReportDiagnostic(s_rule, operation, exceptionType.ToDisplayString());
}
}
19
Source : DoNotRemoveOriginalExceptionFromThrowStatementAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var operation = (IThrowOperation)context.Operation;
if (operation.Exception == null)
return;
if (operation.Exception is not ILocalReferenceOperation localReferenceOperation)
return;
var catchOperation = operation.Ancestors().OfType<ICatchClauseOperation>().FirstOrDefault();
if (catchOperation == null)
return;
if (catchOperation.Locals.Contains(localReferenceOperation.Local))
{
context.ReportDiagnostic(s_rule, operation);
}
}
19
Source : DoNotUseBlockingCallInAsyncContextAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private void ReportDiagnosticIfNeeded(OperationreplacedysisContext context, IOperation operation, string message)
{
if (!CanBeAsync(operation))
return;
if (IsAsyncContext(operation))
{
context.ReportDiagnostic(s_rule, operation, message);
}
else if (CanChangeParentMethodSignature(operation))
{
context.ReportDiagnostic(s_rule2, operation, message + " and make method async");
}
}
19
Source : DoNotUseDefaultEqualsOnValueTypeAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
public void replacedyzeInvocationOperation(OperationreplacedysisContext context)
{
var operation = (IInvocationOperation)context.Operation;
if (operation.TargetMethod.Name == nameof(ValueType.GetHashCode))
{
var actualType = operation.Children.FirstOrDefault()?.GetActualType();
if (actualType == null)
return;
if (IsStruct(actualType) && HasDefaultEqualsOrHashCodeImplementations(actualType))
{
context.ReportDiagnostic(s_rule, operation);
}
}
else if (operation.TargetMethod.Name == nameof(ValueType.Equals))
{
var actualType = operation.Children.FirstOrDefault()?.GetActualType();
if (actualType == null)
return;
if (IsStruct(actualType) && HasDefaultEqualsOrHashCodeImplementations(actualType))
{
context.ReportDiagnostic(s_rule, operation);
}
}
else if (IsImmutableCreateMethod(operation.TargetMethod))
{
var type = operation.TargetMethod.TypeArguments[0];
if (IsStruct(type) && HasDefaultEqualsOrHashCodeImplementations(type))
{
if (operation.TargetMethod.ContainingType.IsEqualTo(ImmutableSortedDictionarySymbol))
{
if (operation.TargetMethod.Parameters.Any(arg => arg.Type.IsEqualTo(IComparerSymbol?.Construct(type))))
return;
}
else
{
if (operation.TargetMethod.Parameters.Any(arg => arg.Type.IsEqualTo(IEqualityComparerSymbol?.Construct(type))))
return;
}
context.ReportDiagnostic(s_rule2, operation);
}
}
bool IsImmutableCreateMethod(IMethodSymbol methodSymbol)
{
var names = new[]
{
"Create",
"CreateBuilder",
"CreateRange",
};
var builderTypes = new[]
{
ImmutableDictionarySymbol,
ImmutableHashSetSymbol,
ImmutableSortedDictionarySymbol,
};
return methodSymbol.Arity >= 1 && names.Contains(methodSymbol.Name, StringComparer.Ordinal) && builderTypes.Any(type => type.IsEqualTo(methodSymbol.ContainingType.OriginalDefinition));
}
}
19
Source : DoNotUseDefaultEqualsOnValueTypeAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
public void replacedyzeFieldReferenceOperation(OperationreplacedysisContext context)
{
var operation = (IFieldReferenceOperation)context.Operation;
if (operation.Field.Name == "Empty")
{
var type = operation.Field.ContainingType;
if (type?.OriginalDefinition == null)
return;
if (HashSetSymbols.Any(t => type.OriginalDefinition.IsEqualTo(t)))
{
if (IsStruct(type.TypeArguments[0]) && HasDefaultEqualsOrHashCodeImplementations(type.TypeArguments[0]))
{
context.ReportDiagnostic(s_rule2, operation);
}
}
}
}
19
Source : DoNotUseDefaultEqualsOnValueTypeAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
public void replacedyzeObjectCreationOperation(OperationreplacedysisContext context)
{
var operation = (IObjectCreationOperation)context.Operation;
var type = operation.Type as INamedTypeSymbol;
if (type?.OriginalDefinition == null)
return;
if (operation.Constructor == null)
return;
if (HashSetSymbols.Any(t => type.OriginalDefinition.IsEqualTo(t)))
{
if (operation.Constructor.Parameters.Any(arg => arg.Type.IsEqualTo(IEqualityComparerSymbol?.Construct(type.TypeArguments[0]))))
return;
if (IsStruct(type.TypeArguments[0]) && HasDefaultEqualsOrHashCodeImplementations(type.TypeArguments[0]))
{
context.ReportDiagnostic(s_rule2, operation);
}
}
}
19
Source : DoNotUseEqualityComparerDefaultOfStringAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var operation = (IPropertyReferenceOperation)context.Operation;
if (!string.Equals(operation.Member.Name, nameof(EqualityComparer<string>.Default), StringComparison.Ordinal))
return;
var equalityComparerSymbol = context.Compilation.GetTypeByMetadataName("System.Collections.Generic.EqualityComparer`1");
if (equalityComparerSymbol == null)
return;
var equalityComparerStringSymbol = equalityComparerSymbol.Construct(context.Compilation.GetSpecialType(SpecialType.System_String));
if (operation.Member.ContainingType.IsEqualTo(equalityComparerStringSymbol))
{
if (operation.IsInNameofOperation())
return;
context.ReportDiagnostic(s_rule, operation, operation.Member.Name);
}
}
19
Source : DoNotUseEqualityOperatorsForSpanOfCharAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
public void replacedyzeBinaryOperator(OperationreplacedysisContext context)
{
var operation = (IBinaryOperation)context.Operation;
if (operation.OperatorKind == BinaryOperatorKind.Equals ||
operation.OperatorKind == BinaryOperatorKind.NotEquals)
{
if (!IsSpanOfString(operation.LeftOperand.Type) || !IsSpanOfString(operation.RightOperand.Type))
return;
// EnreplacedyFramework Core doesn't support StringComparison and evaluates everything client side...
// https://github.com/aspnet/EnreplacedyFrameworkCore/issues/1222
if (operation.IsInExpressionArgument())
return;
context.ReportDiagnostic(s_rule, operation, $"{operation.OperatorKind} operator");
}
}
19
Source : DoNotUseImplicitCultureSensitiveToStringAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeBinaryOperation(OperationreplacedysisContext context)
{
var operation = (IBinaryOperation)context.Operation;
if (operation.OperatorKind != BinaryOperatorKind.Add)
return;
if (!operation.Type.IsString())
return;
if (operation.ConstantValue.HasValue)
return;
if (!IsValidOperand(operation.LeftOperand))
{
context.ReportDiagnostic(s_stringConcatRule, operation.LeftOperand);
}
if (!IsValidOperand(operation.RightOperand))
{
context.ReportDiagnostic(s_stringConcatRule, operation.RightOperand);
}
}
19
Source : DoNotUseImplicitCultureSensitiveToStringAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeInterpolatedString(OperationreplacedysisContext context)
{
// Check if parent is InterpolatedString.Invariant($"") or conversion to string?
var operation = (IInterpolatedStringOperation)context.Operation;
if (operation.ConstantValue.HasValue)
return;
var parent = operation.Parent;
if (parent is IConversionOperation conversionOperation)
{
// `FormattableString _ = $""` is valid whereas `string _ = $""` may not be
if (conversionOperation.Type.IsEqualTo(context.Compilation.GetTypeByMetadataName("System.FormattableString")))
return;
}
foreach (var part in operation.Parts.OfType<IInterpolationOperation>())
{
var expression = part.Expression;
var type = expression.Type;
if (expression == null || type == null)
continue;
if (IsFormattableType(context.Compilation, type) && !IsConstantPositiveNumber(expression))
{
context.ReportDiagnostic(s_stringInterpolationRule, part);
}
}
}
19
Source : DoNotUseServerCertificateValidationCallbackAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context, List<ISymbol> eventSymbols)
{
var operation = (IPropertyReferenceOperation)context.Operation;
if (eventSymbols.Contains(operation.Property))
{
context.ReportDiagnostic(s_rule, operation);
}
}
19
Source : DoNotUseZeroToInitializeAnEnumValue.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void ValidateConversionOperation(OperationreplacedysisContext context, IConversionOperation operation)
{
if (!operation.IsImplicit)
return;
if (!operation.Type.IsEnumeration())
return;
// Skip "default" keyword
if (operation.Operand is ILiteralOperation && operation.Operand.ConstantValue.HasValue && operation.Operand.ConstantValue.Value is int i && i == 0)
{
context.ReportDiagnostic(s_rule, operation, operation.Type.ToDisplayString(SymbolDisplayFormat.CSharpShortErrorMessageFormat));
}
}
19
Source : DontUseDangerousThreadingMethodsAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var op = (IInvocationOperation)context.Operation;
if (string.Equals(op.TargetMethod.Name, "Abort", StringComparison.Ordinal) ||
string.Equals(op.TargetMethod.Name, "Suspend", StringComparison.Ordinal) ||
string.Equals(op.TargetMethod.Name, "Resume", StringComparison.Ordinal))
{
var types = context.Compilation.GetTypesByMetadataName("System.Threading.Thread");
foreach (var type in types)
{
if (op.TargetMethod.ContainingType.IsEqualTo(type))
{
context.ReportDiagnostic(s_rule, op);
}
}
}
}
19
Source : EmbedCaughtExceptionAsInnerExceptionAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeThrow(OperationreplacedysisContext context)
{
var operation = (IThrowOperation)context.Operation;
if (operation.Exception == null)
return;
var compilation = context.Compilation;
var exceptionSymbol = compilation.GetTypeByMetadataName("System.Exception");
if (exceptionSymbol == null)
return;
var catchOperation = operation.Ancestors().OfType<ICatchClauseOperation>().FirstOrDefault();
if (catchOperation == null)
return;
if (operation.Exception is IObjectCreationOperation objectCreationOperation)
{
if (objectCreationOperation.Constructor == null)
return;
var argument = objectCreationOperation.Arguments.FirstOrDefault(arg => IsPotentialParameter(arg?.Parameter, exceptionSymbol));
if (argument == null)
{
if (objectCreationOperation.Constructor.HasOverloadWithAdditionalParameterOfType(context.Compilation, exceptionSymbol))
{
context.ReportDiagnostic(s_rule, objectCreationOperation);
}
}
}
}
19
Source : EventsShouldHaveProperArgumentsAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeRaiseEvent(OperationreplacedysisContext context)
{
var operation = (IInvocationOperation)context.Operation;
var targetMethod = operation.TargetMethod;
if (targetMethod.Name != nameof(EventHandler.Invoke))
return;
if (targetMethod.Parameters.Length != 2)
return;
if (!targetMethod.Parameters[0].Type.IsObject())
return;
var eventArgsSymbol = context.Compilation.GetTypeByMetadataName("System.EventArgs");
if (!targetMethod.Parameters[1].Type.IsOrInheritFrom(eventArgsSymbol))
return;
var multicastDelegateSymbol = context.Compilation.GetTypeByMetadataName("System.MulticastDelegate");
if (!targetMethod.ContainingType.IsOrInheritFrom(multicastDelegateSymbol))
return;
var instance = operation.Instance;
if (instance == null)
return;
var ev = FindEvent(instance);
if (ev == null)
return;
// Argument validation
var senderArgument = operation.Arguments[0];
if (ev.IsStatic)
{
if (!IsNull(senderArgument))
{
context.ReportDiagnostic(s_senderStaticRule, senderArgument);
}
}
else
{
if (!IsThis(senderArgument))
{
context.ReportDiagnostic(s_senderInstanceRule, senderArgument);
}
}
var eventArgsArgument = operation.Arguments[1];
if (IsNull(eventArgsArgument))
{
context.ReportDiagnostic(s_eventArgsRule, eventArgsArgument);
}
}
19
Source : LocalVariablesShouldNotHideSymbolsAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private void replacedyzeVariableDeclaration(OperationreplacedysisContext context)
{
var operation = (IVariableDeclaratorOperation)context.Operation;
var semanticModel = operation.SemanticModel!;
var localSymbol = operation.Symbol;
if (localSymbol.IsImplicitlyDeclared || !localSymbol.CanBeReferencedByName)
return;
var containingType = localSymbol.ContainingType;
if (containingType == null)
return;
foreach (var member in GetSymbols(containingType, localSymbol.Name))
{
if (!semanticModel.IsAccessible(operation.Syntax.SpanStart, member))
continue;
if (member is IFieldSymbol)
{
ReportDiagnostic("field");
return;
}
if (member is IPropertySymbol)
{
ReportDiagnostic("property");
return;
}
}
void ReportDiagnostic(string type)
{
if (operation.Syntax is VariableDeclaratorSyntax declarator)
{
context.ReportDiagnostic(s_rule, declarator.Identifier, localSymbol.Name, type);
}
else
{
context.ReportDiagnostic(s_rule, operation, localSymbol.Name, type);
}
}
}
19
Source : OptimizeLinqUsageAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void WhereShouldBeBeforeOrderBy(OperationreplacedysisContext context, IInvocationOperation operation, List<INamedTypeSymbol> enumerableSymbols)
{
if (string.Equals(operation.TargetMethod.Name, nameof(Enumerable.OrderBy), StringComparison.Ordinal) ||
string.Equals(operation.TargetMethod.Name, nameof(Enumerable.OrderByDescending), StringComparison.Ordinal))
{
var parent = GetParentLinqOperation(operation);
if (parent != null && enumerableSymbols.Contains(parent.TargetMethod.ContainingType))
{
if (string.Equals(parent.TargetMethod.Name, nameof(Enumerable.Where), StringComparison.Ordinal))
{
var properties = CreateProperties(OptimizeLinqUsageData.CombineWhereWithNextMethod)
.Add("FirstOperationStart", operation.Syntax.Span.Start.ToString(CultureInfo.InvariantCulture))
.Add("FirstOperationLength", operation.Syntax.Span.Length.ToString(CultureInfo.InvariantCulture))
.Add("LastOperationStart", parent.Syntax.Span.Start.ToString(CultureInfo.InvariantCulture))
.Add("LastOperationLength", parent.Syntax.Span.Length.ToString(CultureInfo.InvariantCulture))
.Add("MethodName", parent.TargetMethod.Name);
context.ReportDiagnostic(s_optimizeWhereAndOrderByRule, properties, parent, operation.TargetMethod.Name);
}
}
}
}
19
Source : OptimizeLinqUsageAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void UseCountPropertyInsteadOfMethod(OperationreplacedysisContext context, IInvocationOperation operation)
{
if (operation.Arguments.Length != 1)
return;
if (string.Equals(operation.TargetMethod.Name, nameof(Enumerable.Count), StringComparison.Ordinal))
{
var collectionOfTSymbol = context.Compilation.GetTypeByMetadataName("System.Collections.Generic.ICollection`1");
var readOnlyCollectionOfTSymbol = context.Compilation.GetTypeByMetadataName("System.Collections.Generic.IReadOnlyCollection`1");
if (collectionOfTSymbol == null && readOnlyCollectionOfTSymbol == null)
return;
var actualType = operation.Arguments[0].Value.GetActualType();
if (actualType == null)
return;
if (actualType.TypeKind == TypeKind.Array)
{
var properties = CreateProperties(OptimizeLinqUsageData.UseLengthProperty);
context.ReportDiagnostic(s_listMethodsRule, properties, operation, DiagnosticReportOptions.ReportOnMethodName, "Length", operation.TargetMethod.Name);
return;
}
if (actualType.AllInterfaces.Any(i => i.OriginalDefinition.IsEqualTo(collectionOfTSymbol) || i.OriginalDefinition.IsEqualTo(readOnlyCollectionOfTSymbol)))
{
// Ensure the Count property is not an explicit implementation
var count = actualType.GetMembers("Count").OfType<IPropertySymbol>().FirstOrDefault(m => m.ExplicitInterfaceImplementations.Length == 0);
if (count != null)
{
var properties = CreateProperties(OptimizeLinqUsageData.UseCountProperty);
context.ReportDiagnostic(s_listMethodsRule, properties, operation, DiagnosticReportOptions.ReportOnMethodName, "Count", operation.TargetMethod.Name);
return;
}
}
}
else if (string.Equals(operation.TargetMethod.Name, nameof(Enumerable.LongCount), StringComparison.Ordinal))
{
var actualType = operation.Arguments[0].Value.GetActualType();
if (actualType != null && actualType.TypeKind == TypeKind.Array)
{
var properties = CreateProperties(OptimizeLinqUsageData.UseLongLengthProperty);
context.ReportDiagnostic(s_listMethodsRule, properties, operation, DiagnosticReportOptions.ReportOnMethodName, "LongLength", operation.TargetMethod.Name);
}
}
}
19
Source : OptimizeLinqUsageAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void UseFindInsteadOfFirstOrDefault(OperationreplacedysisContext context, IInvocationOperation operation)
{
if (!string.Equals(operation.TargetMethod.Name, nameof(Enumerable.FirstOrDefault), StringComparison.Ordinal))
return;
if (operation.Arguments.Length != 2)
return;
var listSymbol = context.Compilation.GetTypeByMetadataName("System.Collections.Generic.List`1");
var firstArgumentType = operation.Arguments[0].Value.GetActualType();
if (firstArgumentType == null)
return;
if (firstArgumentType.OriginalDefinition.IsEqualTo(listSymbol))
{
var properties = CreateProperties(OptimizeLinqUsageData.UseFindMethod);
context.ReportDiagnostic(s_listMethodsRule, properties, operation, DiagnosticReportOptions.ReportOnMethodName, "Find()", operation.TargetMethod.Name);
}
}
19
Source : OptimizeLinqUsageAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void UseIndexerInsteadOfElementAt(OperationreplacedysisContext context, IInvocationOperation operation)
{
ImmutableDictionary<string, string?>? properties = null;
var argCount = -1;
if (string.Equals(operation.TargetMethod.Name, nameof(Enumerable.ElementAt), StringComparison.Ordinal))
{
properties = CreateProperties(OptimizeLinqUsageData.UseIndexer);
argCount = 2;
}
else if (string.Equals(operation.TargetMethod.Name, nameof(Enumerable.First), StringComparison.Ordinal))
{
properties = CreateProperties(OptimizeLinqUsageData.UseIndexerFirst);
argCount = 1;
}
else if (string.Equals(operation.TargetMethod.Name, nameof(Enumerable.Last), StringComparison.Ordinal))
{
properties = CreateProperties(OptimizeLinqUsageData.UseIndexerLast);
argCount = 1;
}
if (argCount < 0)
return;
if (operation.Arguments.Length != argCount)
return;
var listSymbol = context.Compilation.GetTypeByMetadataName("System.Collections.Generic.IList`1");
var readOnlyListSymbol = context.Compilation.GetTypeByMetadataName("System.Collections.Generic.IReadOnlyList`1");
if (listSymbol == null && readOnlyListSymbol == null)
return;
var actualType = operation.Arguments[0].Value.GetActualType();
if (actualType == null)
return;
if (actualType.AllInterfaces.Any(i => i.OriginalDefinition.IsEqualTo(listSymbol) || i.OriginalDefinition.IsEqualTo(readOnlyListSymbol)))
{
context.ReportDiagnostic(s_indexerInsteadOfElementAtRule, properties, operation, DiagnosticReportOptions.ReportOnMethodName, "[]", operation.TargetMethod.Name);
}
}
19
Source : OptimizeLinqUsageAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void UseCastInsteadOfSelect(OperationreplacedysisContext context, IInvocationOperation operation)
{
var semanticModel = operation.SemanticModel!;
if (!string.Equals(operation.TargetMethod.Name, nameof(Enumerable.Select), StringComparison.Ordinal))
return;
// A valid 'Select' operation always has 2 arguments, regardless of whether the underlying code syntax is
// that of a call to an extension method: source.Select(selector);
// or to a static method: Enumerable.Select(source, selector);
// Operation's first argument -> 'source'
// Operation's second argument -> 'selector'
if (operation.Arguments.Length != 2)
return;
var selectorArg = operation.Arguments[1];
var returnOp = selectorArg.Descendants().OfType<IReturnOperation>().FirstOrDefault();
if (returnOp is null)
return;
// If what's returned is not a cast value or the cast is done by 'as' operator
if (returnOp.ReturnedValue is not IConversionOperation castOp || castOp.IsTryCast || castOp.Type == null)
return;
// If the cast is not applied directly to the source element (one of the selector's arguments)
if (castOp.Operand.Kind != OperationKind.ParameterReference)
return;
// Ensure the code is valid after replacement. The semantic may be different if you use Cast<T>() instead of Select(x => (T)x).
// Current conversion: (Type)value
// Cast<T>() conversion: (Type)(object)value
if (!CanReplaceByCast(castOp))
return;
// Determine if we're casting to a nullable type.
// TODO: Revisit this once https://github.com/dotnet/roslyn/pull/42403 is merged.
var selectMethodSymbol = semanticModel.GetSymbolInfo(operation.Syntax).Symbol as IMethodSymbol;
var nullableFlowState = selectMethodSymbol?.TypeArgumentNullableAnnotations[1] == NullableAnnotation.Annotated ?
NullableFlowState.MaybeNull :
NullableFlowState.None;
// Get the cast type's minimally qualified name, in the current context
var castType = castOp.Type.ToMinimalDisplayString(semanticModel, nullableFlowState, operation.Syntax.SpanStart);
var properties = CreateProperties(OptimizeLinqUsageData.UseCastInsteadOfSelect)
.Add("CastType", castType);
context.ReportDiagnostic(s_useCastInsteadOfSelect, properties, operation, DiagnosticReportOptions.ReportOnMethodName, castType);
static bool CanReplaceByCast(IConversionOperation op)
{
if (op.Conversion.IsUserDefined || op.Conversion.IsNumeric)
return false;
// Handle enums: source.Select<MyEnum, byte>(item => (byte)item);
// Using Cast<T> is only possible when the enum underlying type is the same as the conversion type
var operandActualType = op.Operand.GetActualType();
var enumerationType = operandActualType.GetEnumerationType();
if (enumerationType != null)
{
if (!enumerationType.IsEqualTo(op.Type))
return false;
}
return true;
}
}
19
Source : OptimizeStringBuilderUsageAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static bool IsOptimizable(OperationreplacedysisContext context, IOperation operation, string methodName, IArgumentOperation argument)
{
if (argument.ConstantValue.HasValue)
return false;
var value = argument.Value;
if (value is IInterpolatedStringOperation)
{
if (TryGetConstStringValue(value, out var constValue))
{
if (constValue.Length == 0)
{
if (string.Equals(methodName, nameof(StringBuilder.AppendLine), System.StringComparison.Ordinal))
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.RemoveArgument);
context.ReportDiagnostic(s_rule, properties, operation, "Remove the useless argument");
}
else
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.RemoveMethod);
context.ReportDiagnostic(s_rule, properties, operation, "Remove this no-op call");
}
return true;
}
else if (constValue.Length == 1)
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.ReplaceWithChar)
.Add("ConstantValue", constValue);
context.ReportDiagnostic(s_rule, properties, argument, $"Replace {methodName}(string) with {methodName}(char)");
return true;
}
return false;
}
else
{
if (string.Equals(methodName, nameof(StringBuilder.Insert), System.StringComparison.Ordinal))
return false;
var properties = CreateProperties(OptimizeStringBuilderUsageData.SplitStringInterpolation);
context.ReportDiagnostic(s_rule, properties, operation, $"Replace string interpolation with multiple {methodName} calls");
return true;
}
}
else if (TryGetConstStringValue(value, out var constValue))
{
if (constValue.Length == 0)
{
if (string.Equals(methodName, nameof(StringBuilder.AppendLine), System.StringComparison.Ordinal))
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.RemoveArgument);
context.ReportDiagnostic(s_rule, properties, operation, "Remove the useless argument");
}
else
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.RemoveMethod);
context.ReportDiagnostic(s_rule, properties, operation, "Remove this no-op call");
}
return true;
}
else if (constValue.Length == 1)
{
if (string.Equals(methodName, nameof(StringBuilder.Append), System.StringComparison.Ordinal) || string.Equals(methodName, nameof(StringBuilder.Insert), System.StringComparison.Ordinal))
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.ReplaceWithChar)
.Add("ConstantValue", constValue);
context.ReportDiagnostic(s_rule, properties, argument, $"Replace {methodName}(string) with {methodName}(char)");
return true;
}
}
return false;
}
else if (value is IBinaryOperation binaryOperation)
{
if (string.Equals(methodName, nameof(StringBuilder.Append), System.StringComparison.Ordinal) || string.Equals(methodName, nameof(StringBuilder.AppendLine), System.StringComparison.Ordinal))
{
if (binaryOperation.OperatorKind == BinaryOperatorKind.Add && value.Type.IsString())
{
if (IsConstString(binaryOperation.LeftOperand) && IsConstString(binaryOperation.RightOperand))
return false;
var properties = CreateProperties(OptimizeStringBuilderUsageData.SplitAddOperator);
context.ReportDiagnostic(s_rule, properties, operation, $"Replace the string concatenation by multiple {methodName} calls");
return true;
}
}
}
else if (value is IInvocationOperation invocationOperation)
{
var targetMethod = invocationOperation.TargetMethod;
if (string.Equals(targetMethod.Name, "ToString", System.StringComparison.Ordinal))
{
if (targetMethod.Parameters.Length == 0 && targetMethod.ReturnType.IsString())
{
if (invocationOperation.Instance?.Type?.IsValueType == true && !IsPrimitive(invocationOperation.Instance.Type))
return false;
var properties = CreateProperties(OptimizeStringBuilderUsageData.RemoveToString);
if (string.Equals(methodName, nameof(StringBuilder.AppendLine), System.StringComparison.Ordinal))
{
context.ReportDiagnostic(s_rule, properties, operation, "Replace with Append().AppendLine()");
}
else
{
context.ReportDiagnostic(s_rule, properties, operation, "Remove the ToString call");
}
return true;
}
if (targetMethod.Parameters.Length == 2 &&
targetMethod.ReturnType.IsString() &&
targetMethod.Parameters[0].Type.IsString() &&
invocationOperation.Arguments[0].Value.ConstantValue.HasValue && // Only replace for constant formats
targetMethod.Parameters[1].Type.IsEqualTo(context.Compilation.GetTypeByMetadataName("System.IFormatProvider")))
{
if (string.Equals(methodName, nameof(StringBuilder.AppendLine), System.StringComparison.Ordinal))
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.ReplaceWithAppendFormat);
context.ReportDiagnostic(s_rule, properties, operation, "Use AppendFormat().AppendLine()");
return true;
}
else
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.ReplaceWithAppendFormat);
context.ReportDiagnostic(s_rule, properties, operation, "Use AppendFormat");
return true;
}
}
}
else if (string.Equals(targetMethod.Name, nameof(string.Substring), System.StringComparison.Ordinal) && targetMethod.ContainingType.IsString())
{
var properties = CreateProperties(OptimizeStringBuilderUsageData.ReplaceSubstring);
context.ReportDiagnostic(s_rule, properties, operation, $"Use {methodName}(string, int, int) instead of Substring");
return true;
}
}
return false;
}
19
Source : RemoveUselessToStringAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeOperation(OperationreplacedysisContext context)
{
var operation = (IInvocationOperation)context.Operation;
if (operation.IsImplicit)
return;
if (string.Equals(operation.TargetMethod.Name, nameof(string.ToString), StringComparison.Ordinal) &&
operation.TargetMethod.ContainingType.IsString())
{
context.ReportDiagnostic(s_rule, operation);
}
}
19
Source : ReplaceEnumToStringWithNameofAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var operation = (IInvocationOperation)context.Operation;
if (operation.TargetMethod.Name != nameof(object.ToString))
return;
if (!operation.TargetMethod.ContainingType.IsEqualTo(context.Compilation.GetSpecialType(SpecialType.System_Enum)))
return;
if (operation.Children.First() is not IMemberReferenceOperation expression)
return;
if (expression.Member.ContainingType.EnumUnderlyingType == null)
return;
context.ReportDiagnostic(s_rule, operation);
}
19
Source : UseAnOverloadThatHaveCancellationTokenAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
public void replacedyzeInvocation(OperationreplacedysisContext context)
{
var operation = (IInvocationOperation)context.Operation;
if (HasExplicitCancellationTokenArgument(operation))
return;
if (!HasAnOverloadWithCancellationToken(operation))
return;
var possibleCancellationTokens = string.Join(", ", FindCancellationTokens(operation));
if (!string.IsNullOrEmpty(possibleCancellationTokens))
{
context.ReportDiagnostic(s_useAnOverloadThatHaveCancellationTokenWhenACancellationTokenIsAvailableRule, operation, possibleCancellationTokens);
}
else
{
var parentMethod = operation.GetContainingMethod();
if (parentMethod is not null && parentMethod.IsOverrideOrInterfaceImplementation())
return;
context.ReportDiagnostic(s_useAnOverloadThatHaveCancellationTokenRule, operation, possibleCancellationTokens);
}
}
19
Source : UseConfigureAwaitAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
public void replacedyzeForEachStatement(OperationreplacedysisContext context)
{
if (context.Operation is not IForEachLoopOperation operation)
return;
if (!operation.IsAsynchronous)
return;
// ConfiguredCancelableAsyncEnumerable
var collectionType = operation.Collection.GetActualType();
if (collectionType == null)
return;
if (collectionType.OriginalDefinition.IsEqualTo(ConfiguredCancelableAsyncEnumerableSymbol))
{
// Enumerable().WithCancellation(ct) or Enumerable().ConfigureAwait(false)
if (HasConfigureAwait(operation.Collection) && HasPartOfTypeIAsyncEnumerable(operation.Collection))
return;
// Check if it's a variable reference that is already configured
// note: this doesn't check if the value is well-configured
// https://github.com/meziantou/Meziantou.replacedyzer/issues/232
if (operation.Collection.UnwrapImplicitConversionOperations() is ILocalReferenceOperation)
return;
}
if (!CanAddConfigureAwait(collectionType, operation.Collection))
return;
if (MustUseConfigureAwait(operation.SemanticModel!, context.Options, operation.Syntax, context.CancellationToken))
{
context.ReportDiagnostic(s_rule, operation.Collection);
}
static bool HasConfigureAwait(IOperation operation)
{
if (operation is IInvocationOperation invocation)
{
if (invocation.TargetMethod.Name == "ConfigureAwait")
return true;
}
foreach (var child in operation.Children)
{
if (HasConfigureAwait(child))
return true;
}
return false;
}
bool HasPartOfTypeIAsyncEnumerable(IOperation operation)
{
if (operation.Type.IsEqualTo(IAsyncEnumerableSymbol))
return true;
foreach (var child in operation.Children)
{
if (HasConfigureAwait(child))
return true;
}
return false;
}
}
19
Source : UseEventArgsEmptyAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyze(OperationreplacedysisContext context)
{
var operation = (IObjectCreationOperation)context.Operation;
if (operation == null || operation.Constructor == null)
return;
if (operation.Arguments.Length > 0)
return;
var type = context.Compilation.GetTypeByMetadataName("System.EventArgs");
if (operation.Constructor.ContainingType.IsEqualTo(type))
{
context.ReportDiagnostic(s_rule, operation);
}
}
19
Source : ValueReturnedByStreamReadShouldBeUsedAnalyzer.cs
with MIT License
from meziantou
with MIT License
from meziantou
private static void replacedyzeOperation(OperationreplacedysisContext context)
{
var invocation = (IInvocationOperation)context.Operation;
var targetMethod = invocation.TargetMethod;
if (targetMethod.Name != nameof(Stream.Read) && targetMethod.Name != nameof(Stream.ReadAsync))
return;
var streamSymbol = context.Compilation.GetTypeByMetadataName("System.IO.Stream");
if (!targetMethod.ContainingType.IsOrInheritFrom(streamSymbol))
return;
var parent = invocation.Parent;
if (parent is IAwaitOperation)
{
parent = parent.Parent;
}
if (parent == null || parent is IBlockOperation || parent is IExpressionStatementOperation)
{
context.ReportDiagnostic(s_rule, invocation, targetMethod.Name);
}
}
See More Examples