Esempio n. 1
0
        /// <summary>
        /// Gets all the declared local variables in the given <paramref name="declarationGroup"/>.
        /// </summary>
        /// <param name="declarationGroup">Variable declaration group</param>
        public static ImmutableArray <ILocalSymbol> GetDeclaredVariables(this IVariableDeclarationGroupOperation declarationGroup)
        {
            if (declarationGroup == null)
            {
                throw new ArgumentNullException(nameof(declarationGroup));
            }

            var arrayBuilder = ArrayBuilder <ILocalSymbol> .GetInstance();

            foreach (IVariableDeclarationOperation group in declarationGroup.Declarations)
            {
                group.GetDeclaredVariables(arrayBuilder);
            }

            return(arrayBuilder.ToImmutableAndFree());
        }
                    static async Task <Document?> HandleVariableDeclarator(IVariableDeclaratorOperation variableDeclaratorOperation, Document doc, SyntaxNode root, CancellationToken cancellationToken)
                    {
                        IVariableDeclarationOperation      variableDeclarationOperation      = (IVariableDeclarationOperation)variableDeclaratorOperation.Parent;
                        IVariableDeclarationGroupOperation variableGroupDeclarationOperation = (IVariableDeclarationGroupOperation)variableDeclarationOperation.Parent;

                        DocumentEditor editor = await DocumentEditor.CreateAsync(doc, cancellationToken).ConfigureAwait(false);

                        SyntaxGenerator generator     = editor.Generator;
                        ILocalSymbol    currentSymbol = variableDeclaratorOperation.Symbol;

                        var        variableInitializerOperation = variableDeclaratorOperation.GetVariableInitializer();
                        string     unitString = (string)variableInitializerOperation.Value.ConstantValue.Value;
                        char       charValue  = unitString[0];
                        SyntaxNode charLiteralExpressionNode = generator.LiteralExpression(charValue);
                        var        charTypeNode   = generator.TypeExpression(SpecialType.System_Char);
                        var        charSyntaxNode = generator.LocalDeclarationStatement(charTypeNode, currentSymbol.Name, charLiteralExpressionNode, isConst: true);

                        charSyntaxNode = charSyntaxNode.WithTriviaFrom(variableGroupDeclarationOperation.Syntax);
                        var newRoot = generator.ReplaceNode(root, variableGroupDeclarationOperation.Syntax, charSyntaxNode);

                        return(doc.WithSyntaxRoot(newRoot));
                    }
Esempio n. 3
0
        private bool ReportIfCanBeAwaitUsing(OperationAnalysisContext context, IOperation usingOperation, IVariableDeclarationGroupOperation operation)
        {
            foreach (var declaration in operation.Declarations)
            {
                if (declaration.Initializer?.Value != null)
                {
                    if (CanBeAwaitUsing(declaration.Initializer.Value))
                    {
                        ReportDiagnosticIfNeeded(context, usingOperation, "Prefer using 'await using'");
                        return(true);
                    }
                }

                foreach (var declarator in declaration.Declarators)
                {
                    if (declarator.Initializer != null && CanBeAwaitUsing(declarator.Initializer.Value))
                    {
                        ReportDiagnosticIfNeeded(context, usingOperation, "Prefer using 'await using'");
                        return(true);
                    }
                }
            }

            return(false);
        }
Esempio n. 4
0
 public override IOperation VisitVariableDeclarationGroup(IVariableDeclarationGroupOperation operation, object argument)
 {
     return(new VariableDeclarationGroupOperation(VisitArray(operation.Declarations), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit));
 }
Esempio n. 5
0
 public override void VisitVariableDeclarationGroup(IVariableDeclarationGroupOperation operation)
 {
     Assert.Equal(OperationKind.VariableDeclarationGroup, operation.Kind);
     AssertEx.Equal(operation.Declarations, operation.Children);
 }
Esempio n. 6
0
        private bool TryFindMatchingLocalDeclarationImmediatelyAbove(
            IConditionalOperation ifOperation, ISimpleAssignmentOperation trueAssignment, ISimpleAssignmentOperation falseAssignment,
            out IVariableDeclarationGroupOperation localDeclaration, out IVariableDeclaratorOperation declarator)
        {
            localDeclaration = null;
            declarator       = null;

            // See if both assignments are to the same local.
            if (!(trueAssignment.Target is ILocalReferenceOperation trueLocal) ||
                !(falseAssignment.Target is ILocalReferenceOperation falseLocal) ||
                !Equals(trueLocal.Local, falseLocal.Local))
            {
                return(false);
            }

            // If so, see if that local was declared immediately above the if-statement.
            var parentBlock = ifOperation.Parent as IBlockOperation;

            if (parentBlock == null)
            {
                return(false);
            }

            var ifIndex = parentBlock.Operations.IndexOf(ifOperation);

            if (ifIndex <= 0)
            {
                return(false);
            }

            localDeclaration = parentBlock.Operations[ifIndex - 1] as IVariableDeclarationGroupOperation;
            if (localDeclaration == null)
            {
                return(false);
            }

            if (localDeclaration.Declarations.Length != 1)
            {
                return(false);
            }

            var declaration = localDeclaration.Declarations[0];
            var declarators = declaration.Declarators;

            if (declarators.Length != 1)
            {
                return(false);
            }

            declarator = declarators[0];
            var variable = declarator.Symbol;

            if (!Equals(variable, trueLocal.Local))
            {
                // wasn't a declaration of the local we're assigning to.
                return(false);
            }

            var variableName = variable.Name;

            var variableInitializer = declarator.Initializer ?? declaration.Initializer;

            if (variableInitializer?.Value != null)
            {
                var unwrapped = UnwrapImplicitConversion(variableInitializer.Value);
                // the variable has to either not have an initializer, or it needs to be basic
                // literal/default expression.
                if (!(unwrapped is ILiteralOperation) &&
                    !(unwrapped is IDefaultValueOperation))
                {
                    return(false);
                }
            }

            // If the variable is referenced in the condition of the 'if' block, we can't merge the
            // declaration and assignments.
            return(!ReferencesLocalVariable(ifOperation.Condition, variable));
        }
Esempio n. 7
0
        public sealed override void Initialize(AnalysisContext context)
        {
            context.RegisterOperationBlockStartAction(
                (operationBlockContext) =>
            {
                if (operationBlockContext.OwningSymbol is IMethodSymbol containingMethod)
                {
                    HashSet <ILocalSymbol> mightBecomeConstLocals = new HashSet <ILocalSymbol>();
                    HashSet <ILocalSymbol> assignedToLocals       = new HashSet <ILocalSymbol>();

                    operationBlockContext.RegisterOperationAction(
                        (operationContext) =>
                    {
                        if (operationContext.Operation is IAssignmentOperation assignment)
                        {
                            AssignTo(
                                assignment.Target,
                                assignedToLocals,
                                mightBecomeConstLocals
                                );
                        }
                        else if (
                            operationContext.Operation
                            is IIncrementOrDecrementOperation increment
                            )
                        {
                            AssignTo(
                                increment.Target,
                                assignedToLocals,
                                mightBecomeConstLocals
                                );
                        }
                        else
                        {
                            throw TestExceptionUtilities.UnexpectedValue(
                                operationContext.Operation
                                );
                        }
                    },
                        OperationKind.SimpleAssignment,
                        OperationKind.CompoundAssignment,
                        OperationKind.Increment
                        );

                    operationBlockContext.RegisterOperationAction(
                        (operationContext) =>
                    {
                        IInvocationOperation invocation =
                            (IInvocationOperation)operationContext.Operation;
                        foreach (IArgumentOperation argument in invocation.Arguments)
                        {
                            if (
                                argument.Parameter.RefKind == RefKind.Out ||
                                argument.Parameter.RefKind == RefKind.Ref
                                )
                            {
                                AssignTo(
                                    argument.Value,
                                    assignedToLocals,
                                    mightBecomeConstLocals
                                    );
                            }
                        }
                    },
                        OperationKind.Invocation
                        );

                    operationBlockContext.RegisterOperationAction(
                        (operationContext) =>
                    {
                        IVariableDeclarationGroupOperation declaration =
                            (IVariableDeclarationGroupOperation)operationContext.Operation;
                        foreach (
                            IVariableDeclaratorOperation variable in declaration.Declarations.SelectMany(
                                decl => decl.Declarators
                                )
                            )
                        {
                            ILocalSymbol local = variable.Symbol;
                            if (!local.IsConst && !assignedToLocals.Contains(local))
                            {
                                var localType = local.Type;
                                if (
                                    (
                                        !localType.IsReferenceType ||
                                        localType.SpecialType
                                        == SpecialType.System_String
                                    ) &&
                                    localType.SpecialType != SpecialType.None
                                    )
                                {
                                    IVariableInitializerOperation initializer =
                                        variable.GetVariableInitializer();
                                    if (
                                        initializer != null &&
                                        initializer.Value.ConstantValue.HasValue
                                        )
                                    {
                                        mightBecomeConstLocals.Add(local);
                                    }
                                }
                            }
                        }
                    },
                        OperationKind.VariableDeclarationGroup
                        );

                    operationBlockContext.RegisterOperationBlockEndAction(
                        (operationBlockEndContext) =>
                    {
                        foreach (ILocalSymbol couldBeConstLocal in mightBecomeConstLocals)
                        {
                            Report(
                                operationBlockEndContext,
                                couldBeConstLocal,
                                LocalCouldBeConstDescriptor
                                );
                        }
                    }
                        );
                }
            }
                );
        }
Esempio n. 8
0
 public virtual void VisitVariableDeclarationGroup(IVariableDeclarationGroupOperation operation)
 {
     DefaultVisit(operation);
 }
Esempio n. 9
0
 public override void VisitVariableDeclarationGroup([NotNull] IVariableDeclarationGroupOperation operation)
 {
     base.VisitVariableDeclarationGroup(operation);
 }
 public override void VisitVariableDeclarationGroup([NotNull] IVariableDeclarationGroupOperation operation)
 {
     IncrementStatementCount(operation);
     base.VisitVariableDeclarationGroup(operation);
 }
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            Document          doc = context.Document;
            CancellationToken cancellationToken = context.CancellationToken;
            SyntaxNode        root = await doc.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            if (root.FindNode(context.Span) is SyntaxNode expression)
            {
                SemanticModel semanticModel = await doc.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

                var operation = semanticModel.GetOperation(expression, cancellationToken);
                if (operation is IArgumentOperation argumentOperation)
                {
                    var localReferenceOperation = argumentOperation.Value as ILocalReferenceOperation;
                    var literalOperation        = argumentOperation.Value as ILiteralOperation;
                    if (localReferenceOperation == null && literalOperation == null)
                    {
                        return;
                    }

                    IVariableDeclaratorOperation?variableDeclaratorOperation = default;
                    if (localReferenceOperation != null)
                    {
                        ILocalSymbol    localArgumentDeclaration = localReferenceOperation.Local;
                        SyntaxReference declaringSyntaxReference = localArgumentDeclaration.DeclaringSyntaxReferences.FirstOrDefault();
                        if (declaringSyntaxReference is null)
                        {
                            return;
                        }

                        variableDeclaratorOperation = semanticModel.GetOperationWalkingUpParentChain(await declaringSyntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false), cancellationToken) as IVariableDeclaratorOperation;

                        if (variableDeclaratorOperation == null)
                        {
                            return;
                        }

                        var variableInitializerOperation = variableDeclaratorOperation.GetVariableInitializer();
                        if (variableInitializerOperation == null)
                        {
                            return;
                        }

                        IVariableDeclarationOperation variableDeclarationOperation = (IVariableDeclarationOperation)variableDeclaratorOperation.Parent;
                        if (variableDeclarationOperation == null)
                        {
                            return;
                        }

                        IVariableDeclarationGroupOperation variableGroupDeclarationOperation = (IVariableDeclarationGroupOperation)variableDeclarationOperation.Parent;
                        if (variableGroupDeclarationOperation.Declarations.Length != 1)
                        {
                            return;
                        }

                        if (variableDeclarationOperation.Declarators.Length != 1)
                        {
                            return;
                        }
                    }

                    context.RegisterCodeFix(
                        CodeAction.Create(
                            title: MicrosoftNetCoreAnalyzersResources.PreferConstCharOverConstUnitStringInStringBuilderTitle,
                            createChangedDocument: async c =>
                    {
                        if (literalOperation != null)
                        {
                            return(await HandleStringLiteral(literalOperation, doc, root, cancellationToken).ConfigureAwait(false));
                        }
                        else
                        {
                            RoslynDebug.Assert(variableDeclaratorOperation != null);
                            return(await HandleVariableDeclarator(variableDeclaratorOperation !, doc, root, cancellationToken).ConfigureAwait(false));
                        }
                    },
                            equivalenceKey: MicrosoftNetCoreAnalyzersResources.PreferConstCharOverConstUnitStringInStringBuilderMessage),
                        context.Diagnostics);
Esempio n. 12
0
 public override bool VisitVariableDeclarationGroup([NotNull] IVariableDeclarationGroupOperation operation1,
                                                    [CanBeNull] IOperation argument)
 {
     return(argument is IVariableDeclarationGroupOperation operation2 &&
            AreBaseOperationsEqual(operation1, operation2));
 }
            private void AnalyzeVariableDeclarationGroupOperation(OperationAnalysisContext context, IVariableDeclarationGroupOperation declarationGroup)
            {
                foreach (var declaration in declarationGroup.Declarations)
                {
                    foreach (var declarator in declaration.Declarators)
                    {
                        if (declarator.Initializer == null)
                        {
                            continue;
                        }

                        // ConfiguredCancelableAsyncEnumerable
                        var variableType = declarator.Initializer.Value.GetActualType();
                        if (variableType == null || variableType.IsEqualTo(ConfiguredAsyncDisposableSymbol))
                        {
                            return;
                        }

                        if (!CanAddConfigureAwait(variableType))
                        {
                            return;
                        }

                        if (MustUseConfigureAwait(declarator.SemanticModel, declarator.Syntax, context.CancellationToken))
                        {
                            context.ReportDiagnostic(s_rule, declarator.Initializer.Value);
                        }
                    }
                }
            }
Esempio n. 14
0
 public override void VisitVariableDeclarationGroup(IVariableDeclarationGroupOperation operation)
 {
     base.VisitVariableDeclarationGroup(operation);
     throw new NotImplementedException();
 }