Пример #1
1
        internal async Task RemoveAllRenameAnnotationsAsync(IEnumerable<DocumentId> documentWithRenameAnnotations, AnnotationTable<RenameAnnotation> annotationSet, CancellationToken cancellationToken)
        {
            foreach (var documentId in documentWithRenameAnnotations)
            {
                if (_renamedSpansTracker.IsDocumentChanged(documentId))
                {
                    var document = _newSolution.GetDocument(documentId);
                    var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                    // For the computeReplacementToken and computeReplacementNode functions, use 
                    // the "updated" node to maintain any annotation removals from descendants.
                    var newRoot = root.ReplaceSyntax(
                        nodes: annotationSet.GetAnnotatedNodes(root),
                        computeReplacementNode: (original, updated) => annotationSet.WithoutAnnotations(updated, annotationSet.GetAnnotations(updated).ToArray()),
                        tokens: annotationSet.GetAnnotatedTokens(root),
                        computeReplacementToken: (original, updated) => annotationSet.WithoutAnnotations(updated, annotationSet.GetAnnotations(updated).ToArray()),
                        trivia: SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(),
                        computeReplacementTrivia: null);

                    _intermediateSolutionContainingOnlyModifiedDocuments = _intermediateSolutionContainingOnlyModifiedDocuments.WithDocumentSyntaxRoot(documentId, newRoot, PreservationMode.PreserveIdentity);
                }
            }

            _newSolution = _intermediateSolutionContainingOnlyModifiedDocuments;
        }
Пример #2
0
            public Session(
                RenameLocations renameLocationSet,
                Location renameSymbolDeclarationLocation,
                string originalText,
                string replacementText,
                OptionSet optionSet,
                Func<IEnumerable<ISymbol>, bool?> newSymbolsAreValid,
                CancellationToken cancellationToken)
            {
                _renameLocationSet = renameLocationSet;
                _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation;
                _originalText = originalText;
                _replacementText = replacementText;
                _optionSet = optionSet;
                _hasConflictCallback = newSymbolsAreValid;
                _cancellationToken = cancellationToken;

                _renamedSymbolDeclarationAnnotation = new RenameAnnotation();

                _conflictLocations = SpecializedCollections.EmptySet<ConflictLocationInfo>();
                _replacementTextValid = true;
                _possibleNameConflicts = new List<string>();

                // only process documents which possibly contain the identifiers.
                _documentsIdsToBeCheckedForConflict = new HashSet<DocumentId>();
                _documentIdOfRenameSymbolDeclaration = renameLocationSet.Solution.GetDocument(renameSymbolDeclarationLocation.SourceTree).Id;

                _renameAnnotations = new AnnotationTable<RenameAnnotation>(RenameAnnotation.Kind);
            }
Пример #3
0
            public Session(RenameLocationSet renameLocationSet, Location renameSymbolDeclarationLocation, string originalText, string replacementText, OptionSet optionSet, CancellationToken cancellationToken)
            {
                this.renameLocationSet = renameLocationSet;
                this.renameSymbolDeclarationLocation = renameSymbolDeclarationLocation;
                this.originalText = originalText;
                this.replacementText = replacementText;
                this.optionSet = optionSet;
                this.cancellationToken = cancellationToken;

                this.renamedSymbolDeclarationAnnotation = new RenameAnnotation();

                this.conflictLocations = SpecializedCollections.EmptySet<ConflictLocationInfo>();
                this.replacementTextValid = true;
                this.possibleNameConflicts = new List<string>();

                // only process documents which possibly contain the identifiers.
                this.documentsIdsToBeCheckedForConflict = new HashSet<DocumentId>();
                this.documentIdOfRenameSymbolDeclaration = renameLocationSet.Solution.GetDocument(renameSymbolDeclarationLocation.SourceTree).Id;

                this.renameAnnotations = new AnnotationTable<RenameAnnotation>(RenameAnnotation.Kind);
            }
Пример #4
0
            public Session(RenameLocationSet renameLocationSet, Location renameSymbolDeclarationLocation, string originalText, string replacementText, OptionSet optionSet, CancellationToken cancellationToken)
            {
                _renameLocationSet = renameLocationSet;
                _renameSymbolDeclarationLocation = renameSymbolDeclarationLocation;
                _originalText      = originalText;
                _replacementText   = replacementText;
                _optionSet         = optionSet;
                _cancellationToken = cancellationToken;

                _renamedSymbolDeclarationAnnotation = new RenameAnnotation();

                _conflictLocations     = SpecializedCollections.EmptySet <ConflictLocationInfo>();
                _replacementTextValid  = true;
                _possibleNameConflicts = new List <string>();

                // only process documents which possibly contain the identifiers.
                _documentsIdsToBeCheckedForConflict  = new HashSet <DocumentId>();
                _documentIdOfRenameSymbolDeclaration = renameLocationSet.Solution.GetDocument(renameSymbolDeclarationLocation.SourceTree).Id;

                _renameAnnotations = new AnnotationTable <RenameAnnotation>(RenameAnnotation.Kind);
            }
 public RenameRewriterParameters(
     RenameAnnotation renamedSymbolDeclarationAnnotation,
     Document document,
     SemanticModel semanticModel,
     SyntaxNode syntaxRoot,
     string replacementText,
     string originalText,
     ICollection <string> possibleNameConflicts,
     Dictionary <TextSpan, RenameLocation> renameLocations,
     ImmutableDictionary <TextSpan, ImmutableSortedSet <TextSpan>?> stringAndCommentTextSpans,
     ISet <TextSpan> conflictLocationSpans,
     Solution originalSolution,
     ISymbol renameSymbol,
     bool replacementTextValid,
     RenamedSpansTracker renameSpansTracker,
     bool isRenamingInStrings,
     bool isRenamingInComments,
     AnnotationTable <RenameAnnotation> renameAnnotations,
     CancellationToken cancellationToken)
 {
     RenamedSymbolDeclarationAnnotation = renamedSymbolDeclarationAnnotation;
     Document                  = document;
     SemanticModel             = semanticModel;
     SyntaxRoot                = syntaxRoot;
     OriginalSyntaxTree        = semanticModel.SyntaxTree;
     ReplacementText           = replacementText;
     OriginalText              = originalText;
     PossibleNameConflicts     = possibleNameConflicts;
     RenameLocations           = renameLocations;
     StringAndCommentTextSpans = stringAndCommentTextSpans;
     ConflictLocationSpans     = conflictLocationSpans;
     OriginalSolution          = originalSolution;
     RenameSymbol              = renameSymbol;
     ReplacementTextValid      = replacementTextValid;
     CancellationToken         = cancellationToken;
     RenameSpansTracker        = renameSpansTracker;
     IsRenamingInStrings       = isRenamingInStrings;
     IsRenamingInComments      = isRenamingInComments;
     RenameAnnotations         = renameAnnotations;
 }
        public void CalculateCoverage_FileExists_WithLines_ReturnsCodeCoverageTable()
        {
            var annotations = new[]
            {
                new { fileName = "first", id = 1, index = 2, hitCount = 1, coverage = 100.0m, line = "first_1" },
                new { fileName = "second", id = 2, index = 8, hitCount = 3, coverage = 100.0m, line = "second_2" },
                new { fileName = "third", id = 3, index = 13, hitCount = 0, coverage = 0.0m, line = string.Empty }
            };

            var annotationTable = new AnnotationTable();
            foreach (var a in annotations)
            {
                annotationTable.Add(a.fileName);
                annotationTable[a.fileName].Add(new Annotation(a.id, a.index, a.hitCount));
            }

            var calculator = new CodeCoverageCalculator(null, annotationTable)
            {
                FileReader = new StubFileReader
                {
                    ExistsValue = true,
                    GetLinesValue = annotations.Select(a => a.line)
                }
            };

            var actualCoverage = calculator.CalculateCoverage();

            var expectedCoverage = new CodeCoverageTable
            {
                Total = (decimal)2 / 3 * 100
            };

            foreach (var a in annotations)
                expectedCoverage.Add(a.fileName, a.coverage);

            Assert.AreEqual(expectedCoverage.Plugin, actualCoverage.Plugin);
            Assert.AreEqual(expectedCoverage.Total, actualCoverage.Total);
            Assert.AreEqual(expectedCoverage.ToString(), actualCoverage.ToString());
            CollectionAssert.AreEqual(expectedCoverage, actualCoverage);
        }
Пример #7
0
 public RenameRewriterParameters(
     RenameAnnotation renamedSymbolDeclarationAnnotation,
     Document document,
     SemanticModel semanticModel,
     SyntaxNode syntaxRoot,
     string replacementText,
     string originalText,
     ICollection <string> possibleNameConflicts,
     Dictionary <TextSpan, RenameLocation> renameLocations,
     ImmutableDictionary <TextSpan, ImmutableSortedSet <TextSpan>?> stringAndCommentTextSpans,
     ISet <TextSpan> conflictLocationSpans,
     Solution originalSolution,
     ISymbol renameSymbol,
     bool replacementTextValid,
     RenamedSpansTracker renameSpansTracker,
     RenameOptionSet optionSet,
     AnnotationTable <RenameAnnotation> renameAnnotations,
     CancellationToken cancellationToken
     )
 {
     this.RenamedSymbolDeclarationAnnotation = renamedSymbolDeclarationAnnotation;
     this.Document                  = document;
     this.SemanticModel             = semanticModel;
     this.SyntaxRoot                = syntaxRoot;
     this.OriginalSyntaxTree        = semanticModel.SyntaxTree;
     this.ReplacementText           = replacementText;
     this.OriginalText              = originalText;
     this.PossibleNameConflicts     = possibleNameConflicts;
     this.RenameLocations           = renameLocations;
     this.StringAndCommentTextSpans = stringAndCommentTextSpans;
     this.ConflictLocationSpans     = conflictLocationSpans;
     this.OriginalSolution          = originalSolution;
     this.RenameSymbol              = renameSymbol;
     this.ReplacementTextValid      = replacementTextValid;
     this.CancellationToken         = cancellationToken;
     this.RenameSpansTracker        = renameSpansTracker;
     this.OptionSet                 = optionSet;
     this.RenameAnnotations         = renameAnnotations;
 }
Пример #8
0
        internal void RemoveAllRenameAnnotations(IEnumerable<DocumentId> documentWithRenameAnnotations, AnnotationTable<RenameAnnotation> annotationSet, CancellationToken cancellationToken)
        {
            foreach (var documentId in documentWithRenameAnnotations)
            {
                if (this.renamedSpansTracker.IsDocumentChanged(documentId))
                {
                    var document = newSolution.GetDocument(documentId);
                    var root = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                    var newRoot = root.ReplaceSyntax(
                        annotationSet.GetAnnotatedNodes(root),
                        (original, dummy) => annotationSet.WithoutAnnotations(original, annotationSet.GetAnnotations(original).ToArray()),
                        annotationSet.GetAnnotatedTokens(root),
                        (original, dummy) => annotationSet.WithoutAnnotations(original, annotationSet.GetAnnotations(original).ToArray()),
                        SpecializedCollections.EmptyEnumerable<SyntaxTrivia>(),
                        computeReplacementTrivia: null);

                    this.intermediateSolutionContainingOnlyModifiedDocuments = this.intermediateSolutionContainingOnlyModifiedDocuments.WithDocumentSyntaxRoot(documentId, newRoot);
                }
            }

            this.newSolution = this.intermediateSolutionContainingOnlyModifiedDocuments;
        }
Пример #9
0
 public RenameRewriterParameters(
     RenameAnnotation renamedSymbolDeclarationAnnotation,
     Document document,
     SemanticModel semanticModel,
     SyntaxNode syntaxRoot,
     string replacementText,
     string originalText,
     ICollection<string> possibleNameConflicts,
     Dictionary<TextSpan, RenameLocation> renameLocations,
     ISet<TextSpan> stringAndCommentTextSpans,
     ISet<TextSpan> conflictLocationSpans,
     Solution originalSolution,
     ISymbol renameSymbol,
     bool replacementTextValid,
     CancellationToken cancellationToken,
     RenamedSpansTracker renameSpansTracker,
     OptionSet optionSet,
     AnnotationTable<RenameAnnotation> renameAnnotations)
 {
     this.RenamedSymbolDeclarationAnnotation = renamedSymbolDeclarationAnnotation;
     this.Document = document;
     this.SemanticModel = semanticModel;
     this.SyntaxRoot = syntaxRoot;
     this.OriginalSyntaxTree = semanticModel.SyntaxTree;
     this.ReplacementText = replacementText;
     this.OriginalText = originalText;
     this.PossibleNameConflicts = possibleNameConflicts;
     this.RenameLocations = renameLocations;
     this.StringAndCommentTextSpans = stringAndCommentTextSpans;
     this.ConflictLocationSpans = conflictLocationSpans;
     this.OriginalSolution = originalSolution;
     this.RenameSymbol = renameSymbol;
     this.ReplacementTextValid = replacementTextValid;
     this.CancellationToken = cancellationToken;
     this.RenameSpansTracker = renameSpansTracker;
     this.OptionSet = optionSet;
     this.RenameAnnotations = renameAnnotations;
 }
        public void CalculateCoverage_DoNotReadAnnotations_ReturnsCodeCoverageTable()
        {
            var annotations = new[]
            {
                new { fileName = "first", hitCount = 3, totalCount = 3, coverage = 100.0m, line = "first_1" },
                new { fileName = "second", hitCount = 4, totalCount = 5, coverage = 80.0m, line = "second_2" },
                new { fileName = "third", hitCount = 8, totalCount = 10, coverage = 80.0m, line = "third_3" },
                new { fileName = "fourth", hitCount = 1, totalCount = 5, coverage = 20.0m, line = "fourth_4" },
                new { fileName = "fifth", hitCount = 3, totalCount = 30, coverage = 10.0m, line = "fifth_5" }
            };

            var annotationTable = new AnnotationTable();
            int id = 0;
            foreach (var a in annotations)
            {
                annotationTable.Add(a.fileName);
                int hitCount = a.hitCount;
                for (int i = 0; i < a.totalCount; i++)
                    annotationTable[a.fileName].Add(new Annotation(id++, id, hitCount-- > 0 ? 1 : 0));
            }

            var calculator = new CodeCoverageCalculator(annotationTable);

            var actualCoverage = calculator.CalculateCoverage(false);

            var expectedCoverage = new CodeCoverageTable
            {
                Total = 35.84905660377358490566037736m
            };

            foreach (var a in annotations)
                expectedCoverage.Add(a.fileName, a.coverage);

            Assert.AreEqual(expectedCoverage.Plugin, actualCoverage.Plugin);
            Assert.AreEqual(expectedCoverage.Total, actualCoverage.Total);
            Assert.AreEqual(expectedCoverage.ToString(), actualCoverage.ToString());
            CollectionAssert.AreEqual(expectedCoverage, actualCoverage);
        }
Пример #11
0
        public static async Task <TRoot> ReplaceSyntaxAsync <TRoot>(
            this TRoot root,
            IEnumerable <SyntaxNode> nodes,
            Func <SyntaxNode, SyntaxNode, CancellationToken, Task <SyntaxNode> > computeReplacementNodeAsync,
            IEnumerable <SyntaxToken> tokens,
            Func <SyntaxToken, SyntaxToken, CancellationToken, Task <SyntaxToken> > computeReplacementTokenAsync,
            IEnumerable <SyntaxTrivia> trivia,
            Func <SyntaxTrivia, SyntaxTrivia, CancellationToken, Task <SyntaxTrivia> > computeReplacementTriviaAsync,
            CancellationToken cancellationToken)
            where TRoot : SyntaxNode
        {
            // index all nodes, tokens and trivia by the full spans they cover
            var nodesToReplace = nodes != null?nodes.ToDictionary(n => n.FullSpan) : new Dictionary <TextSpan, SyntaxNode>();

            var tokensToReplace = tokens != null?tokens.ToDictionary(t => t.FullSpan) : new Dictionary <TextSpan, SyntaxToken>();

            var triviaToReplace = trivia != null?trivia.ToDictionary(t => t.FullSpan) : new Dictionary <TextSpan, SyntaxTrivia>();

            var nodeReplacements   = new Dictionary <SyntaxNode, SyntaxNode>();
            var tokenReplacements  = new Dictionary <SyntaxToken, SyntaxToken>();
            var triviaReplacements = new Dictionary <SyntaxTrivia, SyntaxTrivia>();

            var retryAnnotations = new AnnotationTable <object>("RetryReplace");

            var spans = new List <TextSpan>(nodesToReplace.Count + tokensToReplace.Count + triviaToReplace.Count);

            spans.AddRange(nodesToReplace.Keys);
            spans.AddRange(tokensToReplace.Keys);
            spans.AddRange(triviaToReplace.Keys);

            while (spans.Count > 0)
            {
                // sort the spans of the items to be replaced so we can tell if any overlap
                spans.Sort((x, y) =>
                {
                    // order by end offset, and then by length
                    var d = x.End - y.End;

                    if (d == 0)
                    {
                        d = x.Length - y.Length;
                    }

                    return(d);
                });

                // compute replacements for all nodes that will go in the same batch
                // only spans that do not overlap go in the same batch.
                TextSpan previous = default(TextSpan);
                foreach (var span in spans)
                {
                    // only add to replacement map if we don't intersect with the previous node. This taken with the sort order
                    // should ensure that parent nodes are not processed in the same batch as child nodes.
                    if (previous == default(TextSpan) || !previous.IntersectsWith(span))
                    {
                        if (nodesToReplace.TryGetValue(span, out var currentNode))
                        {
                            var original = (SyntaxNode)retryAnnotations.GetAnnotations(currentNode).SingleOrDefault() ?? currentNode;
                            var newNode  = await computeReplacementNodeAsync(original, currentNode, cancellationToken).ConfigureAwait(false);

                            nodeReplacements[currentNode] = newNode;
                        }
                        else if (tokensToReplace.TryGetValue(span, out var currentToken))
                        {
                            var original = (SyntaxToken)retryAnnotations.GetAnnotations(currentToken).SingleOrDefault();
                            if (original == default(SyntaxToken))
                            {
                                original = currentToken;
                            }

                            var newToken = await computeReplacementTokenAsync(original, currentToken, cancellationToken).ConfigureAwait(false);

                            tokenReplacements[currentToken] = newToken;
                        }
                        else if (triviaToReplace.TryGetValue(span, out var currentTrivia))
                        {
                            var original = (SyntaxTrivia)retryAnnotations.GetAnnotations(currentTrivia).SingleOrDefault();
                            if (original == default(SyntaxTrivia))
                            {
                                original = currentTrivia;
                            }

                            var newTrivia = await computeReplacementTriviaAsync(original, currentTrivia, cancellationToken).ConfigureAwait(false);

                            triviaReplacements[currentTrivia] = newTrivia;
                        }
                    }

                    previous = span;
                }

                bool retryNodes  = false;
                bool retryTokens = false;
                bool retryTrivia = false;

                // replace nodes in batch
                // submit all nodes so we can annotate the ones we don't replace
                root = root.ReplaceSyntax(
                    nodes: nodesToReplace.Values,
                    computeReplacementNode: (original, rewritten) =>
                {
                    if (rewritten != original || !nodeReplacements.TryGetValue(original, out var replaced))
                    {
                        // the subtree did change, or we didn't have a replacement for it in this batch
                        // so we need to add an annotation so we can find this node again for the next batch.
                        replaced   = retryAnnotations.WithAdditionalAnnotations(rewritten, original);
                        retryNodes = true;
                    }

                    return(replaced);
                },
                    tokens: tokensToReplace.Values,
                    computeReplacementToken: (original, rewritten) =>
                {
                    if (rewritten != original || !tokenReplacements.TryGetValue(original, out var replaced))
                    {
                        // the subtree did change, or we didn't have a replacement for it in this batch
                        // so we need to add an annotation so we can find this node again for the next batch.
                        replaced    = retryAnnotations.WithAdditionalAnnotations(rewritten, original);
                        retryTokens = true;
                    }

                    return(replaced);
                },
                    trivia: triviaToReplace.Values,
                    computeReplacementTrivia: (original, rewritten) =>
                {
                    if (!triviaReplacements.TryGetValue(original, out var replaced))
                    {
                        // the subtree did change, or we didn't have a replacement for it in this batch
                        // so we need to add an annotation so we can find this node again for the next batch.
                        replaced    = retryAnnotations.WithAdditionalAnnotations(rewritten, original);
                        retryTrivia = true;
                    }

                    return(replaced);
                });

                nodesToReplace.Clear();
                tokensToReplace.Clear();
                triviaToReplace.Clear();
                spans.Clear();

                // prepare next batch out of all remaining annotated nodes
                if (retryNodes)
                {
                    nodesToReplace = retryAnnotations.GetAnnotatedNodes(root).ToDictionary(n => n.FullSpan);
                    spans.AddRange(nodesToReplace.Keys);
                }

                if (retryTokens)
                {
                    tokensToReplace = retryAnnotations.GetAnnotatedTokens(root).ToDictionary(t => t.FullSpan);
                    spans.AddRange(tokensToReplace.Keys);
                }

                if (retryTrivia)
                {
                    triviaToReplace = retryAnnotations.GetAnnotatedTrivia(root).ToDictionary(t => t.FullSpan);
                    spans.AddRange(triviaToReplace.Keys);
                }
            }

            return(root);
        }
Пример #12
0
        internal async Task <Solution> SimplifyAsync(Solution solution, IEnumerable <DocumentId> documentIds, bool replacementTextValid, AnnotationTable <RenameAnnotation> renameAnnotations, CancellationToken cancellationToken)
        {
            foreach (var documentId in documentIds)
            {
                if (this.IsDocumentChanged(documentId))
                {
                    var document = solution.GetDocument(documentId);

                    if (replacementTextValid)
                    {
                        var optionSet = solution.Workspace.Options;
                        document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, optionSet, cancellationToken).ConfigureAwait(false);

                        document = await Formatter.FormatAsync(document, Formatter.Annotation, cancellationToken : cancellationToken).ConfigureAwait(false);
                    }

                    // Simplification may have removed escaping and formatted whitespace.  We need to update
                    // our list of modified spans accordingly
                    if (_documentToModifiedSpansMap.ContainsKey(documentId))
                    {
                        _documentToModifiedSpansMap[documentId].Clear();
                    }

                    if (_documentToComplexifiedSpansMap.ContainsKey(documentId))
                    {
                        _documentToComplexifiedSpansMap[documentId].Clear();
                    }

                    var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                    // First, get all the complexified statements
                    var nodeAnnotations = renameAnnotations.GetAnnotatedNodesAndTokens <RenameNodeSimplificationAnnotation>(root)
                                          .Select(x => Tuple.Create(renameAnnotations.GetAnnotations <RenameNodeSimplificationAnnotation>(x).First(), (SyntaxNode)x));

                    HashSet <SyntaxToken> modifiedTokensInComplexifiedStatements = new HashSet <SyntaxToken>();
                    foreach (var annotationAndNode in nodeAnnotations)
                    {
                        var oldSpan = annotationAndNode.Item1.OriginalTextSpan;
                        var node    = annotationAndNode.Item2;

                        var annotationAndTokens2 = renameAnnotations.GetAnnotatedNodesAndTokens <RenameTokenSimplificationAnnotation>(node)
                                                   .Select(x => Tuple.Create(renameAnnotations.GetAnnotations <RenameTokenSimplificationAnnotation>(x).First(), (SyntaxToken)x));

                        List <ValueTuple <TextSpan, TextSpan> > modifiedSubSpans = new List <ValueTuple <TextSpan, TextSpan> >();
                        foreach (var annotationAndToken in annotationAndTokens2)
                        {
                            modifiedTokensInComplexifiedStatements.Add(annotationAndToken.Item2);
                            modifiedSubSpans.Add(ValueTuple.Create(annotationAndToken.Item1.OriginalTextSpan, annotationAndToken.Item2.Span));
                        }

                        AddComplexifiedSpan(documentId, oldSpan, node.Span, modifiedSubSpans);
                    }

                    // Now process the rest of the renamed spans
                    var annotationAndTokens = renameAnnotations.GetAnnotatedNodesAndTokens <RenameTokenSimplificationAnnotation>(root)
                                              .Where(x => !modifiedTokensInComplexifiedStatements.Contains((SyntaxToken)x))
                                              .Select(x => Tuple.Create(renameAnnotations.GetAnnotations <RenameTokenSimplificationAnnotation>(x).First(), (SyntaxToken)x));

                    foreach (var annotationAndToken in annotationAndTokens)
                    {
                        AddModifiedSpan(documentId, annotationAndToken.Item1.OriginalTextSpan, annotationAndToken.Item2.Span);
                    }

                    var annotationAndTrivias = renameAnnotations.GetAnnotatedTrivia <RenameTokenSimplificationAnnotation>(root)
                                               .Select(x => Tuple.Create(renameAnnotations.GetAnnotations <RenameTokenSimplificationAnnotation>(x).First(), x));

                    foreach (var annotationAndTrivia in annotationAndTrivias)
                    {
                        AddModifiedSpan(documentId, annotationAndTrivia.Item1.OriginalTextSpan, annotationAndTrivia.Item2.Span);
                    }

                    solution = document.Project.Solution;
                }
            }

            return(solution);
        }
Пример #13
0
        internal async Task<Solution> SimplifyAsync(Solution solution, IEnumerable<DocumentId> documentIds, bool replacementTextValid, AnnotationTable<RenameAnnotation> renameAnnotations, CancellationToken cancellationToken)
        {
            foreach (var documentId in documentIds)
            {
                if (this.IsDocumentChanged(documentId))
                {
                    var document = solution.GetDocument(documentId);

                    if (replacementTextValid)
                    {
                        var optionSet = solution.Workspace.Options;
                        document = await Simplifier.ReduceAsync(document, Simplifier.Annotation, optionSet, cancellationToken).ConfigureAwait(false);
                        document = await Formatter.FormatAsync(document, Formatter.Annotation, cancellationToken: cancellationToken).ConfigureAwait(false);
                    }

                    // Simplification may have removed escaping and formatted whitespace.  We need to update
                    // our list of modified spans accordingly
                    if (_documentToModifiedSpansMap.ContainsKey(documentId))
                    {
                        _documentToModifiedSpansMap[documentId].Clear();
                    }

                    if (_documentToComplexifiedSpansMap.ContainsKey(documentId))
                    {
                        _documentToComplexifiedSpansMap[documentId].Clear();
                    }

                    var root = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                    // First, get all the complexified statements
                    var nodeAnnotations = renameAnnotations.GetAnnotatedNodesAndTokens<RenameNodeSimplificationAnnotation>(root)
                        .Select(x => Tuple.Create(renameAnnotations.GetAnnotations<RenameNodeSimplificationAnnotation>(x).First(), (SyntaxNode)x));

                    HashSet<SyntaxToken> modifiedTokensInComplexifiedStatements = new HashSet<SyntaxToken>();
                    foreach (var annotationAndNode in nodeAnnotations)
                    {
                        var oldSpan = annotationAndNode.Item1.OriginalTextSpan;
                        var node = annotationAndNode.Item2;

                        var annotationAndTokens2 = renameAnnotations.GetAnnotatedNodesAndTokens<RenameTokenSimplificationAnnotation>(node)
                               .Select(x => Tuple.Create(renameAnnotations.GetAnnotations<RenameTokenSimplificationAnnotation>(x).First(), (SyntaxToken)x));

                        List<ValueTuple<TextSpan, TextSpan>> modifiedSubSpans = new List<ValueTuple<TextSpan, TextSpan>>();
                        foreach (var annotationAndToken in annotationAndTokens2)
                        {
                            modifiedTokensInComplexifiedStatements.Add(annotationAndToken.Item2);
                            modifiedSubSpans.Add(ValueTuple.Create(annotationAndToken.Item1.OriginalTextSpan, annotationAndToken.Item2.Span));
                        }

                        AddComplexifiedSpan(documentId, oldSpan, node.Span, modifiedSubSpans);
                    }

                    // Now process the rest of the renamed spans
                    var annotationAndTokens = renameAnnotations.GetAnnotatedNodesAndTokens<RenameTokenSimplificationAnnotation>(root)
                        .Where(x => !modifiedTokensInComplexifiedStatements.Contains((SyntaxToken)x))
                        .Select(x => Tuple.Create(renameAnnotations.GetAnnotations<RenameTokenSimplificationAnnotation>(x).First(), (SyntaxToken)x));

                    foreach (var annotationAndToken in annotationAndTokens)
                    {
                        AddModifiedSpan(documentId, annotationAndToken.Item1.OriginalTextSpan, annotationAndToken.Item2.Span);
                    }

                    var annotationAndTrivias = renameAnnotations.GetAnnotatedTrivia<RenameTokenSimplificationAnnotation>(root)
                        .Select(x => Tuple.Create(renameAnnotations.GetAnnotations<RenameTokenSimplificationAnnotation>(x).First(), (SyntaxTrivia)x));

                    foreach (var annotationAndTrivia in annotationAndTrivias)
                    {
                        AddModifiedSpan(documentId, annotationAndTrivia.Item1.OriginalTextSpan, annotationAndTrivia.Item2.Span);
                    }

                    solution = document.Project.Solution;
                }
            }

            return solution;
        }
Пример #14
0
        internal async Task RemoveAllRenameAnnotationsAsync(IEnumerable <DocumentId> documentWithRenameAnnotations, AnnotationTable <RenameAnnotation> annotationSet, CancellationToken cancellationToken)
        {
            foreach (var documentId in documentWithRenameAnnotations)
            {
                if (_renamedSpansTracker.IsDocumentChanged(documentId))
                {
                    var document = _newSolution.GetDocument(documentId);
                    var root     = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

                    // For the computeReplacementToken and computeReplacementNode functions, use
                    // the "updated" node to maintain any annotation removals from descendants.
                    var newRoot = root.ReplaceSyntax(
                        nodes: annotationSet.GetAnnotatedNodes(root),
                        computeReplacementNode: (original, updated) => annotationSet.WithoutAnnotations(updated, annotationSet.GetAnnotations(updated).ToArray()),
                        tokens: annotationSet.GetAnnotatedTokens(root),
                        computeReplacementToken: (original, updated) => annotationSet.WithoutAnnotations(updated, annotationSet.GetAnnotations(updated).ToArray()),
                        trivia: SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(),
                        computeReplacementTrivia: null);

                    _intermediateSolutionContainingOnlyModifiedDocuments = _intermediateSolutionContainingOnlyModifiedDocuments.WithDocumentSyntaxRoot(documentId, newRoot, PreservationMode.PreserveIdentity);
                }
            }

            _newSolution = _intermediateSolutionContainingOnlyModifiedDocuments;
        }
            public RenameRewriter(RenameRewriterParameters parameters)
                : base(visitIntoStructuredTrivia: true)
            {
                this.documentId = parameters.Document.Id;
                this.renameRenamableSymbolDeclaration = parameters.RenamedSymbolDeclarationAnnotation;
                this.solution = parameters.OriginalSolution;
                this.replacementText = parameters.ReplacementText;
                this.originalText = parameters.OriginalText;
                this.possibleNameConflicts = parameters.PossibleNameConflicts;
                this.renameLocations = parameters.RenameLocations;
                this.conflictLocations = parameters.ConflictLocationSpans;
                this.cancellationToken = parameters.CancellationToken;
                this.semanticModel = (SemanticModel)parameters.SemanticModel;
                this.renamedSymbol = parameters.RenameSymbol;
                this.replacementTextValid = parameters.ReplacementTextValid;
                this.renameSpansTracker = parameters.RenameSpansTracker;
                this.isRenamingInStrings = parameters.OptionSet.GetOption(RenameOptions.RenameInStrings);
                this.isRenamingInComments = parameters.OptionSet.GetOption(RenameOptions.RenameInComments);
                this.stringAndCommentTextSpans = parameters.StringAndCommentTextSpans;
                this.renameAnnotations = parameters.RenameAnnotations;

                this.aliasSymbol = this.renamedSymbol as IAliasSymbol;
                this.renamableDeclarationLocation = this.renamedSymbol.Locations.Where(loc => loc.IsInSource && loc.SourceTree == semanticModel.SyntaxTree).FirstOrDefault();
                this.isVerbatim = this.replacementText.StartsWith("@");

                this.simplificationService = LanguageService.GetService<ISimplificationService>(parameters.Document);
            }
Пример #16
0
        private void InternalBeginAnnotation <T>(Key <T> key, T value)
        {
            AnnotationTable <T> annotationTable = GetAnnotationTable(key, true);

            annotationTable.BeginValue(CharCount, value);
        }
 public CodeCoverageCalculator(AnnotationTable annotationTable)
     : this (null, annotationTable)
 {
 }
 public CodeCoverageCalculator(FileInfo annotationFile, AnnotationTable annotationTable)
 {
     FileReader = new AnnotationFileReader(annotationFile);
     _annotationTable = annotationTable;
 }
            public RenameRewriter(RenameRewriterParameters parameters)
                : base(visitIntoStructuredTrivia: true)
            {
                _documentId = parameters.Document.Id;
                _renameRenamableSymbolDeclaration = parameters.RenamedSymbolDeclarationAnnotation;
                _solution = parameters.OriginalSolution;
                _replacementText = parameters.ReplacementText;
                _originalText = parameters.OriginalText;
                _possibleNameConflicts = parameters.PossibleNameConflicts;
                _renameLocations = parameters.RenameLocations;
                _conflictLocations = parameters.ConflictLocationSpans;
                _cancellationToken = parameters.CancellationToken;
                _semanticModel = parameters.SemanticModel;
                _renamedSymbol = parameters.RenameSymbol;
                _replacementTextValid = parameters.ReplacementTextValid;
                _renameSpansTracker = parameters.RenameSpansTracker;
                _isRenamingInStrings = parameters.OptionSet.GetOption(RenameOptions.RenameInStrings);
                _isRenamingInComments = parameters.OptionSet.GetOption(RenameOptions.RenameInComments);
                _stringAndCommentTextSpans = parameters.StringAndCommentTextSpans;
                _renameAnnotations = parameters.RenameAnnotations;

                _aliasSymbol = _renamedSymbol as IAliasSymbol;
                _renamableDeclarationLocation = _renamedSymbol.Locations.FirstOrDefault(loc => loc.IsInSource && loc.SourceTree == _semanticModel.SyntaxTree);
                _isVerbatim = _replacementText.StartsWith("@", StringComparison.Ordinal);

                _simplificationService = parameters.Document.Project.LanguageServices.GetService<ISimplificationService>();
                _semanticFactsService = parameters.Document.Project.LanguageServices.GetService<ISemanticFactsService>();
            }
 public Annotator()
 {
     AnnotationIndexes = new Dictionary<string, int>();
     AnnotationTable = new AnnotationTable();
     Config = Program.Config;
 }
Пример #21
0
        internal void RemoveAllRenameAnnotations(IEnumerable <DocumentId> documentWithRenameAnnotations, AnnotationTable <RenameAnnotation> annotationSet, CancellationToken cancellationToken)
        {
            foreach (var documentId in documentWithRenameAnnotations)
            {
                if (this.renamedSpansTracker.IsDocumentChanged(documentId))
                {
                    var document = newSolution.GetDocument(documentId);
                    var root     = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);
                    var newRoot  = root.ReplaceSyntax(
                        annotationSet.GetAnnotatedNodes(root),
                        (original, dummy) => annotationSet.WithoutAnnotations(original, annotationSet.GetAnnotations(original).ToArray()),
                        annotationSet.GetAnnotatedTokens(root),
                        (original, dummy) => annotationSet.WithoutAnnotations(original, annotationSet.GetAnnotations(original).ToArray()),
                        SpecializedCollections.EmptyEnumerable <SyntaxTrivia>(),
                        computeReplacementTrivia: null);

                    this.intermediateSolutionContainingOnlyModifiedDocuments = this.intermediateSolutionContainingOnlyModifiedDocuments.WithDocumentSyntaxRoot(documentId, newRoot, PreservationMode.PreserveIdentity);
                }
            }

            this.newSolution = this.intermediateSolutionContainingOnlyModifiedDocuments;
        }