Exemplo n.º 1
0
        public async Task <Solution> ProcessAsync(
            Document document,
            SyntaxNode syntaxRoot,
            CancellationToken cancellationToken)
        {
            if (m_unwrittenWritableFields == null)
            {
                using (await SemaphoreLock.GetAsync(m_processUsagesLock))
                {
                    // A global analysis must be run before we can do any actual processing, because a field might
                    // be written in a different file than it is declared (even private ones may be split between
                    // partial classes).

                    // It's also quite expensive, which is why it's being done inside the lock, so
                    // that the entire solution is not processed for each input file individually
                    if (m_unwrittenWritableFields == null)
                    {
                        List <Document> allDocuments =
                            document.Project.Solution.Projects.SelectMany(p => p.Documents).ToList();
                        HashSet <IFieldSymbol>[] fields = await Task.WhenAll(
                            allDocuments
                            .AsParallel()
                            .Select(
                                doc => WritableFieldScanner.Scan(doc, cancellationToken)));

                        var writableFields = new ConcurrentDictionary <IFieldSymbol, bool>(
                            fields.SelectMany(s => s).Select(f => new KeyValuePair <IFieldSymbol, bool>(f, true)));

                        await Task.WhenAll(
                            allDocuments.AsParallel()
                            .Select(
                                doc => WriteUsagesScanner.RemoveWrittenFields(
                                    doc,
                                    writableFields,
                                    cancellationToken)));

                        m_unwrittenWritableFields = writableFields;
                    }
                }
            }

            if (m_unwrittenWritableFields.Count == 0)
            {
                // If there are no unwritten writable fields, skip all the rewriting
                return(document.Project.Solution);
            }

            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken);

            var application = new ReadonlyRewriter(
                m_unwrittenWritableFields,
                await document.GetSemanticModelAsync(cancellationToken));

            return(document.Project.Solution.WithDocumentSyntaxRoot(document.Id, application.Visit(root)));
        }
        public async Task<Solution> ProcessAsync(
            Document document,
            SyntaxNode syntaxRoot,
            CancellationToken cancellationToken)
        {
            if (_unwrittenWritableFields == null)
            {
                using (await SemaphoreLock.GetAsync(_processUsagesLock))
                {
                    // A global analysis must be run before we can do any actual processing, because a field might
                    // be written in a different file than it is declared (even private ones may be split between
                    // partial classes).

                    // It's also quite expensive, which is why it's being done inside the lock, so
                    // that the entire solution is not processed for each input file individually
                    if (_unwrittenWritableFields == null)
                    {
                        List<Document> allDocuments =
                            document.Project.Solution.Projects.SelectMany(p => p.Documents).ToList();
                        HashSet<IFieldSymbol>[] fields = await Task.WhenAll(
                            allDocuments
                                .AsParallel()
                                .Select(
                                    doc => WritableFieldScanner.Scan(doc, cancellationToken)));

                        var writableFields = new ConcurrentDictionary<IFieldSymbol, bool>(
                            fields.SelectMany(s => s).Select(f => new KeyValuePair<IFieldSymbol, bool>(f, true)));

                        await Task.WhenAll(
                            allDocuments.AsParallel()
                                .Select(
                                    doc => WriteUsagesScanner.RemoveWrittenFields(
                                        doc,
                                        writableFields,
                                        cancellationToken)));

                        _unwrittenWritableFields = writableFields;
                    }
                }
            }

            if (_unwrittenWritableFields.Count == 0)
            {
                // If there are no unwritten writable fields, skip all the rewriting
                return document.Project.Solution;
            }

            SyntaxNode root = await document.GetSyntaxRootAsync(cancellationToken);
            var application = new ReadonlyRewriter(
                _unwrittenWritableFields,
                await document.GetSemanticModelAsync(cancellationToken));
            return document.Project.Solution.WithDocumentSyntaxRoot(document.Id, application.Visit(root));
        }