Пример #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)));
        }
Пример #2
0
            public static async Task RemoveWrittenFields(
                Document document,
                ConcurrentDictionary <IFieldSymbol, bool> writableFields,
                CancellationToken cancellationToken)
            {
                var scanner = new WriteUsagesScanner(
                    await document.GetSemanticModelAsync(cancellationToken),
                    writableFields);

                scanner.Visit(await document.GetSyntaxRootAsync(cancellationToken));
            }
            public static async Task RemoveWrittenFields(
                Document document,
                ConcurrentDictionary <IFieldSymbol, bool> writableFields,
                CancellationToken cancellationToken)
            {
                if (document.Project.Language != LanguageNames.CSharp)
                {
                    return;
                }

                var scanner = new WriteUsagesScanner(
                    await document.GetSemanticModelAsync(cancellationToken),
                    writableFields);

                scanner.Visit(await document.GetSyntaxRootAsync(cancellationToken));
            }
 public static async Task RemoveWrittenFields(
     Document document,
     ConcurrentDictionary<IFieldSymbol, bool> writableFields,
     CancellationToken cancellationToken)
 {
     var scanner = new WriteUsagesScanner(
         await document.GetSemanticModelAsync(cancellationToken),
         writableFields);
     scanner.Visit(await document.GetSyntaxRootAsync(cancellationToken));
 }