private static bool IsAddedToFieldOrProperty(ILocalSymbol symbol, BlockSyntax block, SemanticModel semanticModel, CancellationToken cancellationToken) { using (var pooledInvocations = InvocationWalker.Create(block)) { foreach (var invocation in pooledInvocations.Item.Invocations) { var method = semanticModel.GetSymbolSafe(invocation, cancellationToken) as IMethodSymbol; if (method?.Name == "Add") { using (var pooledIdentifiers = IdentifierNameWalker.Create(invocation.ArgumentList)) { foreach (var identifierName in pooledIdentifiers.Item.IdentifierNames) { var argSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken); if (symbol.Equals(argSymbol)) { return(true); } } } } } } return(false); }
internal static bool IsMemberDisposed(ISymbol member, IMethodSymbol disposeMethod, SemanticModel semanticModel, CancellationToken cancellationToken) { if (member == null || disposeMethod == null) { return(false); } foreach (var reference in disposeMethod.DeclaringSyntaxReferences) { var node = reference.GetSyntax(cancellationToken) as MethodDeclarationSyntax; using (var pooled = DisposeWalker.Create(disposeMethod, semanticModel, cancellationToken)) { foreach (var invocation in pooled.Item) { if (IsDisposing(invocation, member, semanticModel, cancellationToken)) { return(true); } } } using (var pooled = IdentifierNameWalker.Create(node)) { foreach (var identifier in pooled.Item.IdentifierNames) { var memberAccess = identifier.Parent as MemberAccessExpressionSyntax; if (memberAccess?.Expression is BaseExpressionSyntax) { var baseMethod = semanticModel.GetSymbolSafe(identifier, cancellationToken) as IMethodSymbol; if (baseMethod?.Name == "Dispose") { if (IsMemberDisposed(member, baseMethod, semanticModel, cancellationToken)) { return(true); } } } if (identifier.Identifier.ValueText != member.Name) { continue; } var symbol = semanticModel.GetSymbolSafe(identifier, cancellationToken); if (member.Equals(symbol) || (member as IPropertySymbol)?.OverriddenProperty?.Equals(symbol) == true) { return(true); } } } } return(false); }
private static bool IsInitializedWithOther(BasePropertyDeclarationSyntax x, BasePropertyDeclarationSyntax y, out int result) { bool IsInitializedWith(EqualsValueClauseSyntax initializer, PropertyDeclarationSyntax other) { using (var identifiers = IdentifierNameWalker.Borrow(initializer)) { foreach (var identifier in identifiers.IdentifierNames) { if (identifier.Identifier.ValueText == other.Identifier.ValueText) { if (identifier.Parent is MemberAccessExpressionSyntax memberAccess && memberAccess.Expression is IdentifierNameSyntax typeIdentifier && other.Parent is TypeDeclarationSyntax typeDeclarationSyntax && typeIdentifier.Identifier.ValueText != typeDeclarationSyntax.Identifier.ValueText) { continue; } return(true); } } } return(false); } if (x is PropertyDeclarationSyntax xDeclaration && y is PropertyDeclarationSyntax yDeclaration && xDeclaration.Parent == yDeclaration.Parent) { if (xDeclaration.Initializer is EqualsValueClauseSyntax xi && IsInitializedWith(xi, yDeclaration)) { result = 1; return(true); } if (yDeclaration.Initializer is EqualsValueClauseSyntax yi && IsInitializedWith(yi, xDeclaration)) { result = -1; return(true); } } result = 0; return(false); }
private static bool IsDisposedBefore(ISymbol symbol, ExpressionSyntax assignment, SemanticModel semanticModel, CancellationToken cancellationToken) { using (var pooled = InvocationWalker.Create(assignment.FirstAncestorOrSelf <MemberDeclarationSyntax>())) { foreach (var invocation in pooled.Item.Invocations) { if (invocation.IsBeforeInScope(assignment) != Result.Yes) { continue; } var invokedSymbol = semanticModel.GetSymbolSafe(invocation, cancellationToken); if (invokedSymbol?.Name != "Dispose") { continue; } var statement = invocation.FirstAncestorOrSelf <StatementSyntax>(); if (statement != null) { using (var pooledNames = IdentifierNameWalker.Create(statement)) { foreach (var identifierName in pooledNames.Item.IdentifierNames) { var otherSymbol = semanticModel.GetSymbolSafe(identifierName, cancellationToken); if (symbol.Equals(otherSymbol)) { return(true); } } } } } } return(false); }
private static bool IsRedundantAssignment(ISymbol left, AssignmentExpressionSyntax assignment, SyntaxNodeAnalysisContext context) { if (left is IDiscardSymbol || assignment.TryFirstAncestor <ObjectCreationExpressionSyntax>(out _)) { return(false); } if (assignment.TryFirstAncestor <MemberDeclarationSyntax>(out var member)) { if (!(member is ConstructorDeclarationSyntax) && context.SemanticModel.TryGetType(assignment.Left, context.CancellationToken, out var type) && FieldOrProperty.TryCreate(left, out _)) { if (type == KnownSymbol.Boolean || type.TypeKind == TypeKind.Enum) { return(false); } } using (var walker = AssignmentExecutionWalker.For(left, member, Scope.Member, context.SemanticModel, context.CancellationToken)) { foreach (var candidate in walker.Assignments) { if (candidate == assignment) { continue; } if (!MemberPath.Equals(candidate.Left, assignment.Left)) { continue; } if (candidate.IsExecutedBefore(assignment) == ExecutedBefore.Yes) { if (left is IParameterSymbol parameter && parameter.RefKind == RefKind.Out && assignment.TryFirstAncestor <BlockSyntax>(out var assignmentBlock) && candidate.TryFirstAncestor <BlockSyntax>(out var candidateBlock) && (candidateBlock.Contains(assignmentBlock) || candidateBlock.Statements.Last() is ReturnStatementSyntax)) { return(false); } using (var nameWalker = IdentifierNameWalker.Borrow(assignment.Right)) { foreach (var name in nameWalker.IdentifierNames) { if (left.Name == name.Identifier.ValueText && context.SemanticModel.TryGetSymbol( name, context.CancellationToken, out ISymbol symbol) && symbol.Equals(left)) { return(false); } } } return(true); } } } } return(false); }