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);
        }
Esempio n. 2
0
        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);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 4
0
        /// <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);
        }
Esempio n. 6
0
        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);
        }