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); }); }
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); }
/// <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); }
/// <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()); }
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)); }
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)); }
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)); }
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);
protected override VariableDeclarationSyntax GetDeclaratorSyntax(IVariableDeclarationOperation declarator) => (VariableDeclarationSyntax)declarator.Syntax;
public override bool VisitVariableDeclaration([NotNull] IVariableDeclarationOperation operation1, [CanBeNull] IOperation argument) { return(argument is IVariableDeclarationOperation operation2 && AreBaseOperationsEqual(operation1, operation2)); }