Example #1
0
        private void AnalyzeOperation(OperationAnalysisContext context)
        {
            var ifOperation = (IConditionalOperation)context.Operation;

            if (!(ifOperation.Syntax is TIfStatementSyntax ifStatement))
            {
                return;
            }

            var language = ifStatement.Language;

            var option = context.GetOption(_option, language);

            if (!option.Value)
            {
                return;
            }

            if (!TryMatchPattern(ifOperation, context.ContainingSymbol))
            {
                return;
            }

            var additionalLocations = ImmutableArray.Create(ifStatement.GetLocation());

            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         ifStatement.GetFirstToken().GetLocation(),
                                         option.Notification.Severity,
                                         additionalLocations,
                                         properties: null));
        }
Example #2
0
        private void AnalyzeOperation(OperationAnalysisContext context)
        {
            // We only create a diagnostic if the option's value is set to true.
            var option = context.GetOption(CodeStyleOptions2.PreferExplicitTupleNames, context.Compilation.Language);

            if (!option.Value)
            {
                return;
            }

            var severity = option.Notification.Severity;

            if (severity == ReportDiagnostic.Suppress)
            {
                return;
            }

            var fieldReferenceOperation = (IFieldReferenceOperation)context.Operation;

            var field = fieldReferenceOperation.Field;

            if (field.ContainingType.IsTupleType)
            {
                if (field.CorrespondingTupleField?.Equals(field) == true)
                {
                    var namedField = GetNamedField(field.ContainingType, field, context.CancellationToken);
                    if (namedField != null)
                    {
                        var memberAccessSyntax = fieldReferenceOperation.Syntax;
                        var nameNode           = memberAccessSyntax.ChildNodesAndTokens().Reverse().FirstOrDefault();
                        if (nameNode != null)
                        {
                            var properties = ImmutableDictionary <string, string> .Empty.Add(
                                nameof(ElementName), namedField.Name);

                            context.ReportDiagnostic(DiagnosticHelper.Create(
                                                         Descriptor,
                                                         nameNode.GetLocation(),
                                                         severity,
                                                         additionalLocations: null,
                                                         properties));
                        }
                    }
                }
            }
        }
        private void AnalyzeOperation(OperationAnalysisContext context, IOperation operation, IOperation?instanceOperation)
        {
            // this is a static reference so we don't care if it's qualified
            if (instanceOperation == null)
            {
                return;
            }

            // if we're not referencing `this.` or `Me.` (e.g., a parameter, local, etc.)
            if (instanceOperation.Kind != OperationKind.InstanceReference)
            {
                return;
            }

            // We shouldn't qualify if it is inside a property pattern
            if (context.Operation.Parent?.Kind == OperationKind.PropertySubpattern)
            {
                return;
            }

            // Initializer lists are IInvocationOperation which if passed to GetApplicableOptionFromSymbolKind
            // will incorrectly fetch the options for method call.
            // We still want to handle InstanceReferenceKind.ContainingTypeInstance
            if ((instanceOperation as IInstanceReferenceOperation)?.ReferenceKind == InstanceReferenceKind.ImplicitReceiver)
            {
                return;
            }

            // If we can't be qualified (e.g., because we're already qualified with `base.`), we're done.
            if (!CanMemberAccessBeQualified(context.ContainingSymbol, instanceOperation.Syntax))
            {
                return;
            }

            // if we can't find a member then we can't do anything.  Also, we shouldn't qualify
            // accesses to static members.
            if (IsStaticMemberOrIsLocalFunction(operation))
            {
                return;
            }

            if (instanceOperation.Syntax is not TSimpleNameSyntax simpleName)
            {
                return;
            }

            var applicableOption = QualifyMembersHelpers.GetApplicableOptionFromSymbolKind(operation);
            var optionValue      = context.GetOption(applicableOption, context.Operation.Syntax.Language);

            var shouldOptionBePresent = optionValue.Value;
            var severity = optionValue.Notification.Severity;

            if (!shouldOptionBePresent || severity == ReportDiagnostic.Suppress)
            {
                return;
            }

            if (!IsAlreadyQualifiedMemberAccess(simpleName))
            {
                context.ReportDiagnostic(DiagnosticHelper.Create(
                                             Descriptor,
                                             GetLocation(operation),
                                             severity,
                                             additionalLocations: null,
                                             properties: null));
            }
        }
        private void AnalyzeOperation(OperationAnalysisContext context, INamedTypeSymbol expressionTypeOpt)
        {
            var syntaxTree = context.Operation.Syntax.SyntaxTree;

            if (!IsSupported(syntaxTree.Options))
            {
                return;
            }

            var cancellationToken = context.CancellationToken;

            var throwOperation       = (IThrowOperation)context.Operation;
            var throwStatementSyntax = throwOperation.Syntax;

            var semanticModel = context.Operation.SemanticModel;

            var ifOperation = GetContainingIfOperation(
                semanticModel, throwOperation, cancellationToken);

            // This throw statement isn't parented by an if-statement.  Nothing to
            // do here.
            if (ifOperation == null)
            {
                return;
            }

            if (ifOperation.WhenFalse != null)
            {
                // Can't offer this if the 'if-statement' has an 'else-clause'.
                return;
            }

            var option = context.GetOption(_preferThrowExpressionOption);

            if (!option.Value)
            {
                return;
            }

            if (IsInExpressionTree(semanticModel, throwStatementSyntax, expressionTypeOpt, cancellationToken))
            {
                return;
            }

            if (!(ifOperation.Parent is IBlockOperation containingBlock))
            {
                return;
            }

            if (!TryDecomposeIfCondition(ifOperation, out var localOrParameter))
            {
                return;
            }

            if (!TryFindAssignmentExpression(containingBlock, ifOperation, localOrParameter,
                                             out var expressionStatement, out var assignmentExpression))
            {
                return;
            }

            if (!localOrParameter.GetSymbolType().CanAddNullCheck())
            {
                return;
            }

            // We found an assignment using this local/parameter.  Now, just make sure there
            // were no intervening accesses between the check and the assignment.
            if (ValueIsAccessed(
                    semanticModel, ifOperation, containingBlock,
                    localOrParameter, expressionStatement, assignmentExpression))
            {
                return;
            }

            // Ok, there were no intervening writes or accesses.  This check+assignment can be simplified.
            var allLocations = ImmutableArray.Create(
                ifOperation.Syntax.GetLocation(),
                throwOperation.Exception.Syntax.GetLocation(),
                assignmentExpression.Value.Syntax.GetLocation());

            context.ReportDiagnostic(
                DiagnosticHelper.Create(Descriptor, throwStatementSyntax.GetLocation(), option.Notification.Severity, additionalLocations: allLocations, properties: null));
        }