private object FindAssignedConstant(SyntaxNode node, SemanticModel nodeSemanticModel, HashSet <SyntaxNode> visitedVariables)
        {
            return(node is TIdentifierNameSyntax identifier
                ? FindConstant(assignmentFinder.FindLinearPrecedingAssignmentExpression(IdentifierName(identifier), node, FindFieldInitializer), visitedVariables)
                : null);

            SyntaxNode FindFieldInitializer()
            {
                if (nodeSemanticModel.GetSymbolInfo(identifier).Symbol is IFieldSymbol fieldSymbol &&
                    VariableDeclarator(fieldSymbol.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax()) is { } variable &&
                    (visitedVariables == null || !visitedVariables.Contains(variable)))
                {
                    visitedVariables ??= new HashSet <SyntaxNode>();
                    visitedVariables.Add(variable);
                    return(InitializerValue(variable));
                }
Example #2
0
        public bool IsInvalidBuilderInitialization(InvocationContext context)
        {
            var current = context.Node;

            while (current != null)
            {
                current = RemoveParentheses(current);
                if (current is TInvocationSyntax invocation)
                {
                    var invocationContext = new InvocationContext(invocation, GetIdentifierName(invocation), context.SemanticModel);
                    if (descriptors.FirstOrDefault(x => x.IsMatch(invocationContext)) is { } desc)
                    {
                        return(!desc.IsValid(invocation));
                    }
                    current = GetExpression(invocation);
                }
                else if (IsMemberAccess(current, out var memberAccessExpression))
                {
                    current = memberAccessExpression;
                }
                else if (IsObjectCreation(current))
                {
                    // We're sure that full invocation chain started here => we've seen all configuration invocations.
                    return(!constructorIsSafe);
                }
                else if (IsIdentifier(current, out var identifierName))
                {
                    if (!(context.SemanticModel.GetSymbolInfo(current).Symbol is ILocalSymbol))
                    {
                        return(false);
                    }
                    // When tracking reaches the local variable in invocation chain 'variable.MethodA().MethodB()'
                    // we'll try to find preceding assignment to that variable to continue inspection of initialization chain.
                    current = assignmentFinder.FindLinearPrecedingAssignmentExpression(identifierName, current);
                }
                else
                {
                    return(false);
                }
            }
            return(false);
        }