//--- Class Methods --- private static void AnalyzeInvocation(SyntaxNodeAnalysisContext context) { var semanticModel = context.SemanticModel; var node = context.Node; // check to see if the invocation target is in the current assembly var invocationInfo = context.SemanticModel.GetSymbolInfo(node); if (!invocationInfo.Symbol?.ContainingAssembly.Name.Equals(context.SemanticModel.Compilation.AssemblyName) ?? true) { return; } foreach (var argument in from invocationNode in node.DescendantNodes() // find all arguments where invocationNode.Kind() == SyntaxKind.Argument let argumentDescendantNode = invocationNode.DescendantNodes().FirstOrDefault() where argumentDescendantNode != null // do not evaluate out parameters on method invocations where argumentDescendantNode.Parent.GetFirstToken().Kind() != SyntaxKind.OutKeyword // check if the argument type is IEnumerable, and if it is abstract let typeInfo = semanticModel.GetTypeInfo(argumentDescendantNode) // TODO (2016-02-25, steveb): concrete classes that implement IEnumerable<> may be lazy; this check doesn't account for that where MaterializedCollectionsUtils.IsAbstractCollectionType(typeInfo) where MaterializedCollectionsUtils.ShouldReportOnCollectionNode(semanticModel, argumentDescendantNode) select argumentDescendantNode ) { ReportDiagnostic(context, argument.GetLocation()); } }
private static void AnalyzeReturnStatement(SyntaxNodeAnalysisContext context) { var semanticModel = context.SemanticModel; var node = context.Node.DescendantNodes().FirstOrDefault(); if (node == null) { return; } var typeInfo = semanticModel.GetTypeInfo(node); if (MaterializedCollectionsUtils.IsAbstractCollectionType(typeInfo)) { if (MaterializedCollectionsUtils.ShouldReportOnCollectionNode(semanticModel, node)) { ReportDiagnostic(context, node.GetLocation()); } } }