コード例 #1
0
        private void AnalyzeNode(SyntaxNodeAnalysisContext context, INamedTypeSymbol ienumerableType)
        {
            var semanticModel            = context.SemanticModel;
            var objectCreationExpression = (TObjectCreationExpressionSyntax)context.Node;
            var language          = objectCreationExpression.Language;
            var cancellationToken = context.CancellationToken;

            var option = context.GetOption(CodeStyleOptions2.PreferCollectionInitializer, language);

            if (!option.Value)
            {
                // not point in analyzing if the option is off.
                return;
            }

            // Object creation can only be converted to collection initializer if it
            // implements the IEnumerable type.
            var objectType = context.SemanticModel.GetTypeInfo(objectCreationExpression, cancellationToken);

            if (objectType.Type == null || !objectType.Type.AllInterfaces.Contains(ienumerableType))
            {
                return;
            }

            var matches = ObjectCreationExpressionAnalyzer <TExpressionSyntax, TStatementSyntax, TObjectCreationExpressionSyntax, TMemberAccessExpressionSyntax, TInvocationExpressionSyntax, TExpressionStatementSyntax, TVariableDeclaratorSyntax> .Analyze(
                semanticModel, GetSyntaxFacts(), objectCreationExpression, cancellationToken);

            if (matches == null || matches.Value.Length == 0)
            {
                return;
            }

            var containingStatement = objectCreationExpression.FirstAncestorOrSelf <TStatementSyntax>();

            if (containingStatement == null)
            {
                return;
            }

            var nodes       = ImmutableArray.Create <SyntaxNode>(containingStatement).AddRange(matches.Value);
            var syntaxFacts = GetSyntaxFacts();

            if (syntaxFacts.ContainsInterleavedDirective(nodes, cancellationToken))
            {
                return;
            }

            var locations = ImmutableArray.Create(objectCreationExpression.GetLocation());

            var severity = option.Notification.Severity;

            context.ReportDiagnostic(DiagnosticHelper.Create(
                                         Descriptor,
                                         objectCreationExpression.GetLocation(),
                                         severity,
                                         additionalLocations: locations,
                                         properties: null));

            FadeOutCode(context, matches.Value, locations);
        }
コード例 #2
0
        protected override Task FixAllAsync(
            Document document, ImmutableArray <Diagnostic> diagnostics,
            SyntaxEditor editor, CancellationToken cancellationToken)
        {
            // Fix-All for this feature is somewhat complicated.  As Collection-Initializers
            // could be arbitrarily nested, we have to make sure that any edits we make
            // to one Collection-Initializer are seen by any higher ones.  In order to do this
            // we actually process each object-creation-node, one at a time, rewriting
            // the tree for each node.  In order to do this effectively, we use the '.TrackNodes'
            // feature to keep track of all the object creation nodes as we make edits to
            // the tree.  If we didn't do this, then we wouldn't be able to find the
            // second object-creation-node after we make the edit for the first one.
            var workspace    = document.Project.Solution.Workspace;
            var syntaxFacts  = document.GetLanguageService <ISyntaxFactsService>();
            var originalRoot = editor.OriginalRoot;

            var originalObjectCreationNodes = new Stack <TObjectCreationExpressionSyntax>();

            foreach (var diagnostic in diagnostics)
            {
                var objectCreation = (TObjectCreationExpressionSyntax)originalRoot.FindNode(
                    diagnostic.AdditionalLocations[0].SourceSpan, getInnermostNodeForTie: true);
                originalObjectCreationNodes.Push(objectCreation);
            }

            // We're going to be continually editing this tree.  Track all the nodes we
            // care about so we can find them across each edit.
            var currentRoot = originalRoot.TrackNodes(originalObjectCreationNodes);

            while (originalObjectCreationNodes.Count > 0)
            {
                var originalObjectCreation = originalObjectCreationNodes.Pop();
                var objectCreation         = currentRoot.GetCurrentNodes(originalObjectCreation).Single();

                var analyzer = new ObjectCreationExpressionAnalyzer <TExpressionSyntax, TStatementSyntax, TObjectCreationExpressionSyntax, TMemberAccessExpressionSyntax, TInvocationExpressionSyntax, TExpressionStatementSyntax, TVariableDeclaratorSyntax>(
                    syntaxFacts, objectCreation);
                var matches = analyzer.Analyze();
                if (matches == null || matches.Value.Length == 0)
                {
                    continue;
                }

                var statement    = objectCreation.FirstAncestorOrSelf <TStatementSyntax>();
                var newStatement = GetNewStatement(statement, objectCreation, matches.Value)
                                   .WithAdditionalAnnotations(Formatter.Annotation);

                var subEditor = new SyntaxEditor(currentRoot, workspace);

                subEditor.ReplaceNode(statement, newStatement);
                foreach (var match in matches)
                {
                    subEditor.RemoveNode(match);
                }

                currentRoot = subEditor.GetChangedRoot();
            }

            editor.ReplaceNode(originalRoot, currentRoot);
            return(SpecializedTasks.EmptyTask);
        }
コード例 #3
0
        private void AnalyzeNode(SyntaxNodeAnalysisContext context, INamedTypeSymbol ienumerableType)
        {
            if (!AreCollectionInitializersSupported(context))
            {
                return;
            }

            var semanticModel            = context.SemanticModel;
            var objectCreationExpression = (TObjectCreationExpressionSyntax)context.Node;
            var language          = objectCreationExpression.Language;
            var syntaxTree        = objectCreationExpression.SyntaxTree;
            var cancellationToken = context.CancellationToken;

            var optionSet = context.Options.GetDocumentOptionSetAsync(syntaxTree, cancellationToken).GetAwaiter().GetResult();

            if (optionSet == null)
            {
                return;
            }

            var option = optionSet.GetOption(CodeStyleOptions.PreferCollectionInitializer, language);

            if (!option.Value)
            {
                // not point in analyzing if the option is off.
                return;
            }

            // Object creation can only be converted to collection initializer if it
            // implements the IEnumerable type.
            var objectType = context.SemanticModel.GetTypeInfo(objectCreationExpression, cancellationToken);

            if (objectType.Type == null || !objectType.Type.AllInterfaces.Contains(ienumerableType))
            {
                return;
            }

            var analyzer = new ObjectCreationExpressionAnalyzer <TExpressionSyntax, TStatementSyntax, TObjectCreationExpressionSyntax, TMemberAccessExpressionSyntax, TInvocationExpressionSyntax, TExpressionStatementSyntax, TVariableDeclaratorSyntax>(
                semanticModel, GetSyntaxFactsService(), objectCreationExpression, cancellationToken);
            var matches = analyzer.Analyze();

            if (matches == null || matches.Value.Length == 0)
            {
                return;
            }

            var locations = ImmutableArray.Create(objectCreationExpression.GetLocation());

            var severity = option.Notification.Value;

            context.ReportDiagnostic(Diagnostic.Create(
                                         CreateDescriptorWithSeverity(severity),
                                         objectCreationExpression.GetLocation(),
                                         additionalLocations: locations));

            FadeOutCode(context, optionSet, matches.Value, locations);
        }