public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationStartContext =>
            {
                Compilation compilation         = compilationStartContext.Compilation;
                INamedTypeSymbol stopwatchType  = compilation.GetTypeByMetadataName("System.Diagnostics.Stopwatch");
                INamedTypeSymbol clockTimerType = compilation.GetTypeByMetadataName("Tocsoft.DateTimeAbstractions.ClockTimer");

                compilationStartContext.RegisterOperationAction(
                    operationContext =>
                {
                    IVariableDeclarationOperation invocation = (IVariableDeclarationOperation)operationContext.Operation;

                    foreach (var declarator in invocation.Declarators)
                    {
                        if (declarator.Symbol.Type == null || declarator.Symbol.Type != stopwatchType)
                        {
                            return;
                        }
                        var location = (invocation.Syntax as VariableDeclarationSyntax).Type.GetLocation();

                        operationContext.ReportDiagnostic(Diagnostic.Create(
                                                              clockTimerType == null ? referenceRule : referenceRuleDirected,
                                                              location,
                                                              declarator.Symbol.Type.Name,
                                                              clockTimerType?.Name));
                    }
                }, OperationKind.VariableDeclaration);
            });
        }
예제 #2
0
 private static void GetDeclaredVariables(this IVariableDeclarationOperation declaration, ArrayBuilder <ILocalSymbol> arrayBuilder)
 {
     foreach (var decl in declaration.Declarators)
     {
         arrayBuilder.Add(decl.Symbol);
     }
 }
        public static void RegisterMemberAccess(this AnalysisContext context, Action <InvocationAnalysisContext> action)
        {
            var operationKinds = new[]
            {
                OperationKind.Invocation,
                OperationKind.SimpleAssignment,
                OperationKind.VariableDeclaration,
                OperationKind.ObjectCreation,
                OperationKind.FieldInitializer,
                OperationKind.FieldReference,
            };

            context.RegisterOperationAction(ctx =>
            {
                ISymbol?symbol = ctx.Operation switch
                {
                    IInvocationOperation invocation => invocation.TargetMethod,
                    IPropertyReferenceOperation property => property.Property.Type,
                    IObjectCreationOperation creation => creation.Type,
                    ISimpleAssignmentOperation assignment => assignment.Type,
                    IFieldInitializerOperation fieldInitializer => fieldInitializer.Type,
                    IFieldReferenceOperation fieldRef => fieldRef.Type,
                    IVariableDeclarationOperation variableDeclaration => variableDeclaration.Type,
                    _ => null,
                };

                if (symbol is null)
                {
                    return;
                }

                var location = ctx.Operation.Syntax.GetLocation();
                var newCtx   = new InvocationAnalysisContext(symbol, location, ctx.Compilation, ctx.Options, ctx.ReportDiagnostic, ctx.CancellationToken);

                action(newCtx);
            }, operationKinds);

            context.RegisterSymbolAction(ctx =>
            {
                var symbol = ctx.Symbol switch
                {
                    IPropertySymbol property => property.Type,
                    IParameterSymbol parameter => parameter.Type,
                    IMethodSymbol method => method.ReturnsVoid ? null : method.ReturnType,
                    IFieldSymbol field => field.Type,
                    _ => null,
                };

                if (symbol is null)
                {
                    return;
                }

                var location = ctx.Symbol.Locations[0];
                var newCtx   = new InvocationAnalysisContext(symbol, location, ctx.Compilation, ctx.Options, ctx.ReportDiagnostic, ctx.CancellationToken);

                action(newCtx);
            }, SymbolKind.Property, SymbolKind.Method, SymbolKind.Parameter, SymbolKind.Field);
        }
        public override void VisitVariableDeclaration(IVariableDeclarationOperation operation)
        {
            foreach (var symbol in operation.Variables)
            {
                // empty loop body, just want to make sure it won't crash.
            }

            base.VisitVariableDeclaration(operation);
        }
예제 #5
0
        /// <summary>
        /// Gets the variable initializer for the given <paramref name="declarationOperation"/>, checking to see if there is a parent initializer
        /// if the single variable initializer is null.
        /// </summary>
        /// <param name="declarationOperation">Single variable declaration to retrieve initializer for.</param>
        public static IVariableInitializerOperation GetVariableInitializer(this IVariableDeclarationOperation declarationOperation)
        {
            if (declarationOperation == null)
            {
                throw new ArgumentNullException(nameof(declarationOperation));
            }

            return(declarationOperation.Initializer ?? (declarationOperation.Parent as IVariableDeclarationOperation)?.Initializer);
        }
예제 #6
0
        /// <summary>
        /// Gets all the declared local variables in the given <paramref name="declaration"/>.
        /// </summary>
        /// <param name="declaration">Variable declaration</param>
        public static ImmutableArray <ILocalSymbol> GetDeclaredVariables(this IVariableDeclarationOperation declaration)
        {
            if (declaration == null)
            {
                throw new ArgumentNullException(nameof(declaration));
            }

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

            declaration.GetDeclaredVariables(arrayBuilder);
            return(arrayBuilder.ToImmutableAndFree());
        }
예제 #7
0
        public override void VisitVariableDeclaration(IVariableDeclarationOperation operation)
        {
            Assert.Equal(OperationKind.VariableDeclaration, operation.Kind);
            IEnumerable <IOperation> children = operation.Declarators;
            var initializer = operation.Initializer;

            if (initializer != null)
            {
                children = children.Concat(new[] { initializer });
            }

            AssertEx.Equal(children, operation.Children);
        }
 private static void AnalyzeVariableDeclaration(OperationAnalysisContext context, IVariableDeclarationOperation variableDeclaration)
 {
     foreach (var declarator in variableDeclaration.Declarators)
     {
         if (IsInternal(context, declarator.Symbol.Type))
         {
             var syntax = context.Operation.Syntax switch
             {
                 CSharpSyntax.VariableDeclarationSyntax s => s.Type,
                  _ => context.Operation.Syntax
             };
             context.ReportDiagnostic(Diagnostic.Create(Descriptor, syntax.GetLocation(), declarator.Symbol.Type));
             return;
         }
     }
 }
                    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));
                    }
예제 #10
0
 public override IOperation VisitVariableDeclaration(IVariableDeclarationOperation operation, object argument)
 {
     return(new VariableDeclaration(VisitArray(operation.Declarators), Visit(operation.Initializer), ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit));
 }
예제 #11
0
 public virtual void VisitVariableDeclaration(IVariableDeclarationOperation operation)
 {
     DefaultVisit(operation);
 }
 protected abstract TVariableDeclarationSyntax GetDeclaratorSyntax(IVariableDeclarationOperation declarator);
        private bool TryFindMatchingLocalDeclarationImmediatelyAbove(
            IConditionalOperation ifOperation, ISimpleAssignmentOperation trueAssignment, ISimpleAssignmentOperation falseAssignment,
            out IVariableDeclarationGroupOperation localDeclaration, out IVariableDeclarationOperation 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.IsImplicit)
            {
                return(false);
            }

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

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

            declarator = declarators;
            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));
        }
예제 #14
0
 public override void VisitVariableDeclaration([NotNull] IVariableDeclarationOperation operation)
 {
     base.VisitVariableDeclaration(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);
예제 #16
0
 protected override VariableDeclarationSyntax GetDeclaratorSyntax(IVariableDeclarationOperation declarator)
 => (VariableDeclarationSyntax)declarator.Syntax;
예제 #17
0
 public override bool VisitVariableDeclaration([NotNull] IVariableDeclarationOperation operation1,
                                               [CanBeNull] IOperation argument)
 {
     return(argument is IVariableDeclarationOperation operation2 && AreBaseOperationsEqual(operation1, operation2));
 }