Esempio n. 1
0
		static async Task<SyntaxNode> GetNewRootWithAddedNamespaces(Document document, SyntaxNode relativeToNode,
			CancellationToken cancellationToken, ImmutableHashSet<string> namespaceQualifiedStrings)
		{
			var namespaceWithUsings = relativeToNode
				.GetAncestorsOrThis<NamespaceDeclarationSyntax>()
				.FirstOrDefault(ns => ns.DescendantNodes().OfType<UsingDirectiveSyntax>().Any());

			var root = await document.GetSyntaxRootAsync(cancellationToken);
			SyntaxNode newRoot;

			var usings = namespaceQualifiedStrings
				.Select(ns => UsingDirective(ParseName(ns).WithAdditionalAnnotations(Simplifier.Annotation)));

			if (namespaceWithUsings != null)
			{
				var newNamespaceDeclaration = namespaceWithUsings.WithUsings(namespaceWithUsings.Usings.AddRange(usings));
				newRoot = root.ReplaceNode(namespaceWithUsings, newNamespaceDeclaration);
			}
			else
			{
				var compilationUnit = (CompilationUnitSyntax)root;
				newRoot = compilationUnit.WithUsings(compilationUnit.Usings.AddRange(usings));
			}
			return newRoot;
		}
            private SyntaxNode Complexify(SyntaxNode originalNode, SyntaxNode newNode)
            {
                _isProcessingComplexifiedSpans = true;
                _modifiedSubSpans = new List<ValueTuple<TextSpan, TextSpan>>();

                var annotation = new SyntaxAnnotation();
                newNode = newNode.WithAdditionalAnnotations(annotation);
                var speculativeTree = originalNode.SyntaxTree.GetRoot(_cancellationToken).ReplaceNode(originalNode, newNode);
                newNode = speculativeTree.GetAnnotatedNodes<SyntaxNode>(annotation).First();

                _speculativeModel = GetSemanticModelForNode(newNode, _semanticModel);
                Debug.Assert(_speculativeModel != null, "expanding a syntax node which cannot be speculated?");

                var oldSpan = originalNode.Span;
                var expandParameter = originalNode.GetAncestorsOrThis(n => n is SimpleLambdaExpressionSyntax || n is ParenthesizedLambdaExpressionSyntax).Count() == 0;

                newNode = _simplificationService.Expand(newNode,
                                                                    _speculativeModel,
                                                                    annotationForReplacedAliasIdentifier: null,
                                                                    expandInsideNode: null,
                                                                    expandParameter: expandParameter,
                                                                    cancellationToken: _cancellationToken);
                speculativeTree = originalNode.SyntaxTree.GetRoot(_cancellationToken).ReplaceNode(originalNode, newNode);
                newNode = speculativeTree.GetAnnotatedNodes<SyntaxNode>(annotation).First();

                _speculativeModel = GetSemanticModelForNode(newNode, _semanticModel);

                newNode = base.Visit(newNode);
                var newSpan = newNode.Span;

                newNode = newNode.WithoutAnnotations(annotation);
                newNode = _renameAnnotations.WithAdditionalAnnotations(newNode, new RenameNodeSimplificationAnnotation() { OriginalTextSpan = oldSpan });

                _renameSpansTracker.AddComplexifiedSpan(_documentId, oldSpan, new TextSpan(oldSpan.Start, newSpan.Length), _modifiedSubSpans);
                _modifiedSubSpans = null;

                _isProcessingComplexifiedSpans = false;
                _speculativeModel = null;
                return newNode;
            }
            public override SyntaxNode Visit(SyntaxNode node)
            {
                if (node == null)
                {
                    return node;
                }

                var isInConflictLambdaBody = false;
                var lambdas = node.GetAncestorsOrThis(n => n is SimpleLambdaExpressionSyntax || n is ParenthesizedLambdaExpressionSyntax);
                if (lambdas.Count() != 0)
                {
                    foreach (var lambda in lambdas)
                    {
                        if (_conflictLocations.Any(cf => cf.Contains(lambda.Span)))
                        {
                            isInConflictLambdaBody = true;
                            break;
                        }
                    }
                }

                var shouldComplexifyNode =
                    !isInConflictLambdaBody &&
                    _skipRenameForComplexification == 0 &&
                    !_isProcessingComplexifiedSpans &&
                    _conflictLocations.Contains(node.Span);

                SyntaxNode result;

                // in case the current node was identified as being a complexification target of
                // a previous node, we'll handle it accordingly.
                if (shouldComplexifyNode)
                {
                    _skipRenameForComplexification += shouldComplexifyNode ? 1 : 0;
                    result = base.Visit(node);
                    _skipRenameForComplexification -= shouldComplexifyNode ? 1 : 0;
                    result = Complexify(node, result);
                }
                else
                {
                    result = base.Visit(node);
                }

                return result;
            }
        /// <summary>
        /// Gets the semantic model for the given node.
        /// If the node belongs to the syntax tree of the original semantic model, then returns originalSemanticModel.
        /// Otherwise, returns a speculative model.
        /// The assumption for the later case is that span start position of the given node in it's syntax tree is same as
        /// the span start of the original node in the original syntax tree.
        /// </summary>
        public static SemanticModel GetSemanticModelForNode(SyntaxNode node, SemanticModel originalSemanticModel)
        {
            if (node.SyntaxTree == originalSemanticModel.SyntaxTree)
            {
                // This is possible if the previous rename phase didn't rewrite any nodes in this tree.
                return originalSemanticModel;
            }

            var nodeToSpeculate = node.GetAncestorsOrThis(n => SpeculationAnalyzer.CanSpeculateOnNode(n)).LastOrDefault();
            if (nodeToSpeculate == null)
            {
                if (node.IsKind(SyntaxKind.NameMemberCref))
                {
                    nodeToSpeculate = ((NameMemberCrefSyntax)node).Name;
                }
                else if (node.IsKind(SyntaxKind.QualifiedCref))
                {
                    nodeToSpeculate = ((QualifiedCrefSyntax)node).Container;
                }
                else if (node.IsKind(SyntaxKind.TypeConstraint))
                {
                    nodeToSpeculate = ((TypeConstraintSyntax)node).Type;
                }
                else if (node is BaseTypeSyntax)
                {
                    nodeToSpeculate = ((BaseTypeSyntax)node).Type;
                }
                else
                {
                    return null;
                }
            }

            bool isInNamespaceOrTypeContext = SyntaxFacts.IsInNamespaceOrTypeContext(node as ExpressionSyntax);
            var position = nodeToSpeculate.SpanStart;
            return SpeculationAnalyzer.CreateSpeculativeSemanticModelForNode(nodeToSpeculate, originalSemanticModel, position, isInNamespaceOrTypeContext);
        }
        public override IEnumerable<SyntaxNode> GetOuterReturnStatements(SyntaxNode commonRoot, IEnumerable<SyntaxNode> jumpsOutOfRegion)
        {
            var returnStatements = jumpsOutOfRegion.Where(s => s is ReturnStatementSyntax);

            var container = commonRoot.GetAncestorsOrThis<SyntaxNode>().Where(a => a.IsReturnableConstruct()).FirstOrDefault();
            if (container == null)
            {
                return SpecializedCollections.EmptyEnumerable<SyntaxNode>();
            }

            var returnableConstructPairs = returnStatements.Select(r => Tuple.Create(r, r.GetAncestors<SyntaxNode>().Where(a => a.IsReturnableConstruct()).FirstOrDefault()))
                                                           .Where(p => p.Item2 != null);

            // now filter return statements to only include the one under outmost container
            return returnableConstructPairs.Where(p => p.Item2 == container).Select(p => p.Item1);
        }