private static bool AssignedType(ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out ITypeSymbol memberType) { foreach (var reference in symbol.DeclaringSyntaxReferences) { var node = reference.GetSyntax(cancellationToken); if (AssignmentExecutionWalker.SingleForSymbol( symbol, node.FirstAncestor <TypeDeclarationSyntax>(), Search.TopLevel, semanticModel, cancellationToken, out var assignment) && assignment.Right is IdentifierNameSyntax identifier) { var ctor = assignment.FirstAncestor <ConstructorDeclarationSyntax>(); if (ctor != null && ctor.ParameterList != null && ctor.ParameterList.Parameters.TryFirst( p => p.Identifier.ValueText == identifier.Identifier.ValueText, out var parameter)) { memberType = semanticModel.GetDeclaredSymbolSafe(parameter, cancellationToken)?.Type; return(true); } } } memberType = null; return(false); }
internal static bool TryGetAssignment(this BlockSyntax body, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken, out AssignmentExpressionSyntax result) { result = null; if (symbol == null) { return(false); } return(AssignmentExecutionWalker.FirstWith(symbol, body, Search.TopLevel, semanticModel, cancellationToken, out result)); }
/// <inheritdoc/> protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context) { var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken) .ConfigureAwait(false); foreach (var diagnostic in context.Diagnostics) { var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan); if (node is IdentifierNameSyntax identifierName) { context.RegisterCodeFix( "Throw if null.", (editor, _) => editor.ReplaceNode( node, SyntaxFactory.ParseExpression($"{identifierName.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({identifierName.Identifier.ValueText}))").WithSimplifiedNames()), this.GetType(), diagnostic); } else if (node is ParameterSyntax parameter) { var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken) .ConfigureAwait(false); var method = parameter.FirstAncestor <BaseMethodDeclarationSyntax>(); if (method != null) { using (var walker = AssignmentExecutionWalker.Borrow(method, Search.TopLevel, semanticModel, context.CancellationToken)) { if (TryFirstAssignedWith(parameter, walker.Assignments, out var assignedValue)) { context.RegisterCodeFix( "Throw if null on first assignment.", (editor, _) => editor.ReplaceNode( assignedValue, SyntaxFactory.ParseExpression($"{assignedValue.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({assignedValue.Identifier.ValueText}))").WithSimplifiedNames()), this.GetType(), diagnostic); } else if (method.Body != null) { context.RegisterCodeFix( "Add null check.", (editor, _) => editor.ReplaceNode( method.Body, method.Body.InsertNodesBefore( method.Body.Statements[0], new[] { IfNullThrow(parameter.Identifier.ValueText) })), this.GetType(), diagnostic); } } } } } }
/// <inheritdoc/> protected override async Task RegisterCodeFixesAsync(DocumentEditorCodeFixContext context) { var syntaxRoot = await context.Document.GetSyntaxRootAsync(context.CancellationToken) .ConfigureAwait(false); foreach (var diagnostic in context.Diagnostics) { var node = syntaxRoot.FindNode(diagnostic.Location.SourceSpan); if (node is IdentifierNameSyntax identifierName) { context.RegisterCodeFix( "Throw if null.", (editor, _) => editor.ReplaceNode( node, SyntaxFactory.ParseExpression($"{identifierName.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({identifierName.Identifier.ValueText}))").WithSimplifiedNames()), this.GetType(), diagnostic); } else if (node is ParameterSyntax parameter) { var semanticModel = await context.Document.GetSemanticModelAsync(context.CancellationToken) .ConfigureAwait(false); if (parameter.Parent is ParameterListSyntax parameterList && parameterList.Parent is BaseMethodDeclarationSyntax methodDeclaration) { using (var walker = AssignmentExecutionWalker.Borrow(methodDeclaration, Scope.Member, semanticModel, context.CancellationToken)) { if (TryFirstAssignedWith(parameter, walker.Assignments, out var assignedValue)) { context.RegisterCodeFix( "Throw if null on first assignment.", (editor, _) => editor.ReplaceNode( assignedValue, SyntaxFactory.ParseExpression($"{assignedValue.Identifier.ValueText} ?? throw new System.ArgumentNullException(nameof({assignedValue.Identifier.ValueText}))").WithSimplifiedNames()), this.GetType(), diagnostic); } else if (methodDeclaration.Body is BlockSyntax block) { context.RegisterCodeFix( "Add null check.", (editor, _) => editor.ReplaceNode( block, x => WithNullCheck(x, parameter)), this.GetType(), diagnostic); } } } } } }
private static bool IsInjected(FieldOrProperty member, TypeDeclarationSyntax typeDeclaration, SemanticModel semanticModel, CancellationToken cancellationToken) { using (var walker = AssignmentExecutionWalker.For(member.Symbol, typeDeclaration, Scope.Instance, semanticModel, cancellationToken)) { foreach (var assignment in walker.Assignments) { if (assignment.TryFirstAncestorOrSelf <ConstructorDeclarationSyntax>(out _) && semanticModel.GetSymbolSafe(assignment.Right, cancellationToken) is IParameterSymbol) { return(true); } } } return(false); }
internal static bool AssignsSymbolInSetter(IPropertySymbol property, ISymbol symbol, SemanticModel semanticModel, CancellationToken cancellationToken) { var setMethod = property?.SetMethod; if (setMethod == null || setMethod.DeclaringSyntaxReferences.Length == 0) { return(false); } if (TryGetSetter(property, cancellationToken, out AccessorDeclarationSyntax setter)) { if (AssignmentExecutionWalker.FirstForSymbol(symbol, setter, Search.Recursive, semanticModel, cancellationToken)) { 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); }