private static bool TryGetDescriptorCreateMethodAndArguments( IFieldInitializerOperation fieldInitializer, INamedTypeSymbol diagnosticDescriptorType, out IMethodSymbol creationMethod, out ImmutableArray <IArgumentOperation> creationArguments) { (creationMethod, creationArguments) = fieldInitializer.Value switch { IObjectCreationOperation objectCreation when IsDescriptorConstructor(objectCreation.Constructor) => (objectCreation.Constructor, objectCreation.Arguments), IInvocationOperation invocation when IsCreateHelper(invocation.TargetMethod) => (invocation.TargetMethod, invocation.Arguments), _ => default }; return(creationMethod != null); bool IsDescriptorConstructor(IMethodSymbol method) => method.ContainingType.Equals(diagnosticDescriptorType); // Heuristic to identify helper methods to create DiagnosticDescriptor: // "A method invocation that returns 'DiagnosticDescriptor' and has a first string parameter named 'id'" bool IsCreateHelper(IMethodSymbol method) => method.ReturnType.Equals(diagnosticDescriptorType) && !method.Parameters.IsEmpty && method.Parameters[0].Name == DiagnosticIdParameterName && method.Parameters[0].Type.SpecialType == SpecialType.System_String; }
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 VisitFieldInitializer(IFieldInitializerOperation operation) { foreach (var field in operation.InitializedFields) { // empty loop body, just want to make sure it won't crash. } base.VisitFieldInitializer(operation); }
public override void VisitFieldInitializer(IFieldInitializerOperation operation) { Assert.Equal(OperationKind.FieldInitializer, operation.Kind); foreach (var field in operation.InitializedFields) { Assert.NotNull(field); } VisitSymbolInitializer(operation); }
private static void AnalyzeTitle(IMethodSymbol descriptorCreationMethod, IFieldInitializerOperation creation, Action <Diagnostic> reportDiagnostic) { IParameterSymbol title = descriptorCreationMethod.Parameters.FirstOrDefault(p => p.Name == "title"); if (title != null && title.Type != null && title.Type.SpecialType == SpecialType.System_String) { Diagnostic diagnostic = creation.Value.CreateDiagnostic(UseLocalizableStringsInDescriptorRule, WellKnownTypeNames.MicrosoftCodeAnalysisLocalizableString); reportDiagnostic(diagnostic); } }
override public void VisitFieldInitializer(IFieldInitializerOperation operation) { Graph = ControlFlowGraph.Create(operation); }
public override IOperation VisitFieldInitializer(IFieldInitializerOperation operation, object argument) { return(new FieldInitializer(operation.Locals, operation.InitializedFields, Visit(operation.Value), operation.Kind, ((Operation)operation).SemanticModel, operation.Syntax, operation.Type, operation.ConstantValue, operation.IsImplicit)); }
public sealed override void Initialize(AnalysisContext context) { context.RegisterCompilationStartAction( (compilationContext) => { Dictionary <IFieldSymbol, HashSet <INamedTypeSymbol> > fieldsSourceTypes = new Dictionary <IFieldSymbol, HashSet <INamedTypeSymbol> >(); compilationContext.RegisterOperationBlockStartAction( (operationBlockContext) => { if (operationBlockContext.OwningSymbol is IMethodSymbol containingMethod) { Dictionary <ILocalSymbol, HashSet <INamedTypeSymbol> > localsSourceTypes = new Dictionary <ILocalSymbol, HashSet <INamedTypeSymbol> >(); // Track explicit assignments. operationBlockContext.RegisterOperationAction( (operationContext) => { if (operationContext.Operation is IAssignmentOperation assignment) { AssignTo(assignment.Target, localsSourceTypes, fieldsSourceTypes, assignment.Value); } else if (operationContext.Operation is IIncrementOrDecrementOperation increment) { SyntaxNode syntax = increment.Syntax; ITypeSymbol type = increment.Type; Optional <object> constantValue = new Optional <object>(1); bool isImplicit = increment.IsImplicit; var value = new LiteralExpression(operationContext.Compilation.GetSemanticModel(syntax.SyntaxTree), syntax, type, constantValue, isImplicit); AssignTo(increment.Target, localsSourceTypes, fieldsSourceTypes, value); } else { throw TestExceptionUtilities.UnexpectedValue(operationContext.Operation); } }, OperationKind.SimpleAssignment, OperationKind.CompoundAssignment, OperationKind.Increment); // Track arguments that match out or ref parameters. 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, localsSourceTypes, fieldsSourceTypes, argument.Parameter.Type); } } }, OperationKind.Invocation); // Track local variable initializations. operationBlockContext.RegisterOperationAction( (operationContext) => { IVariableInitializerOperation initializer = (IVariableInitializerOperation)operationContext.Operation; if (initializer.Parent is IVariableDeclarationOperation variableDeclaration) { foreach (ILocalSymbol local in variableDeclaration.Variables) { AssignTo(local, local.Type, localsSourceTypes, initializer.Value); } } }, OperationKind.VariableInitializer); // Report locals that could have more specific types. operationBlockContext.RegisterOperationBlockEndAction( (operationBlockEndContext) => { foreach (ILocalSymbol local in localsSourceTypes.Keys) { if (HasMoreSpecificSourceType(local, local.Type, localsSourceTypes, out var mostSpecificSourceType)) { Report(operationBlockEndContext, local, mostSpecificSourceType, LocalCouldHaveMoreSpecificTypeDescriptor); } } }); } }); // Track field initializations. compilationContext.RegisterOperationAction( (operationContext) => { IFieldInitializerOperation initializer = (IFieldInitializerOperation)operationContext.Operation; foreach (IFieldSymbol initializedField in initializer.InitializedFields) { AssignTo(initializedField, initializedField.Type, fieldsSourceTypes, initializer.Value); } }, OperationKind.FieldInitializer); // Report fields that could have more specific types. compilationContext.RegisterCompilationEndAction( (compilationEndContext) => { foreach (IFieldSymbol field in fieldsSourceTypes.Keys) { if (HasMoreSpecificSourceType(field, field.Type, fieldsSourceTypes, out var mostSpecificSourceType)) { Report(compilationEndContext, field, mostSpecificSourceType, FieldCouldHaveMoreSpecificTypeDescriptor); } } }); }); }
public virtual void VisitFieldInitializer(IFieldInitializerOperation operation) { DefaultVisit(operation); }
public override void VisitFieldInitializer([NotNull] IFieldInitializerOperation operation) { base.VisitFieldInitializer(operation); }
public override TAbstractAnalysisValue VisitFieldInitializer(IFieldInitializerOperation operation, object argument) { return(VisitSymbolInitializer(operation, operation.InitializedFields, argument)); }
private static void AnalyzeTitle(OperationAnalysisContext operationAnalysisContext, ImmutableArray <IArgumentOperation> creationArguments, IFieldInitializerOperation creation) { IArgumentOperation titleArgument = creationArguments.FirstOrDefault(a => a.Parameter.Name.Equals("title", StringComparison.OrdinalIgnoreCase)); if (titleArgument?.Parameter.Type.SpecialType != SpecialType.System_String) { return; } operationAnalysisContext.ReportDiagnostic(creation.Value.CreateDiagnostic(UseLocalizableStringsInDescriptorRule, WellKnownTypeNames.MicrosoftCodeAnalysisLocalizableString)); if (!TryGetNonEmptyConstantStringValue(titleArgument, out var title)) { return; } if (IsMultiSentences(title) || EndsWithPeriod(title) || ContainsLineReturn(title)) { operationAnalysisContext.ReportDiagnostic(titleArgument.CreateDiagnostic(DefineDiagnosticTitleCorrectlyRule)); } }
public override bool VisitFieldInitializer([NotNull] IFieldInitializerOperation operation1, [CanBeNull] IOperation argument) { return(argument is IFieldInitializerOperation operation2 && AreBaseOperationsEqual(operation1, operation2) && AreSymbolSequencesEqual(operation1.InitializedFields, operation2.InitializedFields)); }