private async Task<Solution> RenameThenRemoveAsyncTokenAsync(Document document, SyntaxNode node, IMethodSymbol methodSymbol, CancellationToken cancellationToken)
        {
            var name = methodSymbol.Name;
            var newName = name.Substring(0, name.Length - AsyncSuffix.Length);
            var solution = document.Project.Solution;
            var options = solution.Workspace.Options;

            // Store the path to this node.  That way we can find it post rename.
            var syntaxPath = new SyntaxPath(node);

            // Rename the method to remove the 'Async' suffix, then remove the 'async' keyword.
            var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, options, cancellationToken).ConfigureAwait(false);
            var newDocument = newSolution.GetDocument(document.Id);
            var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxNode newNode;
            if (syntaxPath.TryResolve<SyntaxNode>(newRoot, out newNode))
            {
                var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken);
                return await RemoveAsyncTokenAsync(newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false);
            }

            return newSolution;
        }
Beispiel #2
0
        public void FailFirstType()
        {
            var node = SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("Hi"));

            var path = new SyntaxPath(node);
            Assert.False(path.TryResolve(SyntaxFactory.ParseExpression("Foo()"), out SyntaxNode recovered));
        }
Beispiel #3
0
 public void RecoverChild()
 {
     var node = SyntaxFactory.ParseExpression("Foo()");
     var child = ((InvocationExpressionSyntax)node).ArgumentList;
     var path = new SyntaxPath(child);
     Assert.True(path.TryResolve(node, out SyntaxNode recovered));
     Assert.Equal(child, recovered);
 }
Beispiel #4
0
        public void FailChildType()
        {
            var root = SyntaxFactory.ParseExpression("Foo(a)");
            var path = new SyntaxPath(((InvocationExpressionSyntax)root).ArgumentList.Arguments.First().Expression);

            var root2 = SyntaxFactory.ParseExpression("Foo(3)");
            Assert.False(path.TryResolve(root2, out SyntaxNode recovered));
        }
Beispiel #5
0
 public void TestRoot1()
 {
     var tree = SyntaxFactory.ParseSyntaxTree(string.Empty);
     var root = tree.GetRoot();
     var path = new SyntaxPath(root);
     Assert.True(path.TryResolve(tree, CancellationToken.None, out SyntaxNode node));
     Assert.Equal(root, node);
 }
 public WorkItem(
     DocumentId documentId, string language, InvocationReasons invocationReasons, bool isLowPriority,
     SyntaxPath activeMember, IAsyncToken asyncToken)
     : this(documentId, documentId.ProjectId, language, invocationReasons, isLowPriority,
            activeMember, ImmutableHashSet.Create <IIncrementalAnalyzer>(),
            false, asyncToken)
 {
 }
Beispiel #7
0
        public void RecoverSingle()
        {
            var node = SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("Hi"));

            var path = new SyntaxPath(node);
            Assert.True(path.TryResolve(node, out SyntaxNode recovered));
            Assert.Equal(node, recovered);
        }
 public WorkItem(
     DocumentId documentId, string language, InvocationReasons invocationReasons, bool isLowPriority,
     SyntaxPath activeMember, IAsyncToken asyncToken)
     : this(documentId, documentId.ProjectId, language, invocationReasons, isLowPriority,
            activeMember, ImmutableHashSet.Create<IIncrementalAnalyzer>(),
            false, asyncToken)
 {
 }
Beispiel #9
0
 public void RecoverGeneric()
 {
     var root = SyntaxFactory.ParseExpression("Foo()");
     var node = ((InvocationExpressionSyntax)root).ArgumentList;
     var path = new SyntaxPath(node);
     Assert.True(path.TryResolve(root, out ArgumentListSyntax recovered));
     Assert.Equal(node, recovered);
 }
Beispiel #10
0
        public void RecoverGeneric()
        {
            var root = SyntaxFactory.ParseExpression("Goo()");
            var node = ((InvocationExpressionSyntax)root).ArgumentList;
            var path = new SyntaxPath(node);

            Assert.True(path.TryResolve(root, out ArgumentListSyntax recovered));
            Assert.Equal(node, recovered);
        }
Beispiel #11
0
        public void RecoverChild()
        {
            var node  = SyntaxFactory.ParseExpression("Goo()");
            var child = ((InvocationExpressionSyntax)node).ArgumentList;
            var path  = new SyntaxPath(child);

            Assert.True(path.TryResolve(node, out SyntaxNode recovered));
            Assert.Equal(child, recovered);
        }
Beispiel #12
0
        public void RecoverSingle()
        {
            var node = SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("Hi"));

            var path = new SyntaxPath(node);

            Assert.True(path.TryResolve(node, out SyntaxNode recovered));
            Assert.Equal(node, recovered);
        }
Beispiel #13
0
        public void FailChildCount()
        {
            var root = SyntaxFactory.ParseExpression("Goo(a, b)");
            var path = new SyntaxPath(((InvocationExpressionSyntax)root).ArgumentList.Arguments.Last());

            var root2 = SyntaxFactory.ParseExpression("Goo(a)");

            Assert.False(path.TryResolve(root2, out SyntaxNode recovered));
        }
Beispiel #14
0
        public void TestRoot1()
        {
            var tree = SyntaxFactory.ParseSyntaxTree(string.Empty);
            var root = tree.GetRoot();
            var path = new SyntaxPath(root);

            Assert.True(path.TryResolve(tree, CancellationToken.None, out SyntaxNode node));
            Assert.Equal(root, node);
        }
Beispiel #15
0
        public void FailChildType()
        {
            var root = SyntaxFactory.ParseExpression("Goo(a)");
            var path = new SyntaxPath(((InvocationExpressionSyntax)root).ArgumentList.Arguments.First().Expression);

            var root2 = SyntaxFactory.ParseExpression("Goo(3)");

            Assert.False(path.TryResolve(root2, out SyntaxNode _));
        }
Beispiel #16
0
        public void FailFirstType()
        {
            var node = SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("Hi"));

            var        path = new SyntaxPath(node);
            SyntaxNode recovered;

            Assert.False(path.TryResolve(SyntaxFactory.ParseExpression("Foo()"), out recovered));
        }
Beispiel #17
0
        public void FailChildCount()
        {
            var root = SyntaxFactory.ParseExpression("Foo(a, b)");
            var path = new SyntaxPath(((InvocationExpressionSyntax)root).ArgumentList.Arguments.Last());

            var root2 = SyntaxFactory.ParseExpression("Foo(a)");

            SyntaxNode recovered;
            Assert.False(path.TryResolve(root2, out recovered));
        }
Beispiel #18
0
        public void TestRoot4()
        {
            var text = "class C {}";
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var root = tree.GetRoot();
            var path = new SyntaxPath(root);

            tree = WithReplaceFirst(tree, "C", "D");
            Assert.True(path.TryResolve(tree, CancellationToken.None, out SyntaxNode node));
            Assert.Equal(SyntaxKind.CompilationUnit, node.Kind());
        }
Beispiel #19
0
        public void TestRoot2()
        {
            var text = SourceText.From(string.Empty);
            var tree = SyntaxFactory.ParseSyntaxTree(string.Empty);
            var root = tree.GetCompilationUnitRoot();
            var path = new SyntaxPath(root);

            var newText = text.WithChanges(new TextChange(new TextSpan(0, 0), "class C {}"));
            var newTree = tree.WithChangedText(newText);

            Assert.True(path.TryResolve(newTree, CancellationToken.None, out SyntaxNode node));
            Assert.Equal(SyntaxKind.CompilationUnit, node.Kind());
        }
        private async Task <Solution> RenameThenRemoveAsyncTokenAsync(
            Document document,
            SyntaxNode node,
            IMethodSymbol methodSymbol,
            CancellationToken cancellationToken
            )
        {
            var name     = methodSymbol.Name;
            var newName  = name.Substring(0, name.Length - AsyncSuffix.Length);
            var solution = document.Project.Solution;

            // Store the path to this node.  That way we can find it post rename.
            var syntaxPath = new SyntaxPath(node);

            // Rename the method to remove the 'Async' suffix, then remove the 'async' keyword.
            var newSolution = await Renamer
                              .RenameSymbolAsync(
                solution,
                methodSymbol,
                newName,
                solution.Options,
                cancellationToken
                )
                              .ConfigureAwait(false);

            var newDocument = newSolution.GetDocument(document.Id);
            var newRoot     = await newDocument
                              .GetSyntaxRootAsync(cancellationToken)
                              .ConfigureAwait(false);

            if (syntaxPath.TryResolve(newRoot, out SyntaxNode newNode))
            {
                var semanticModel = await newDocument
                                    .GetSemanticModelAsync(cancellationToken)
                                    .ConfigureAwait(false);

                var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(
                    newNode,
                    cancellationToken
                    );
                return(await RemoveAsyncTokenAsync(
                           newDocument,
                           newMethod,
                           newNode,
                           cancellationToken
                           )
                       .ConfigureAwait(false));
            }

            return(newSolution);
        }
Beispiel #21
0
        private void UpdateNodeAndReacquireParentNodeKey <T>(Action <SyntaxNode, T> parameterUpdater, T value)
        {
            Action <SyntaxNode, T> updater = (n, v) =>
            {
                var parentNode     = _parentHandle.Value.LookupNode();
                var parentNodePath = new SyntaxPath(parentNode);

                parameterUpdater(n, v);

                _parentHandle.Value.ReacquireNodeKey(parentNodePath, CancellationToken.None);
            };

            UpdateNode(updater, value);
        }
Beispiel #22
0
        protected void UpdateNodeAndReacquireNodeKey <T>(Action <SyntaxNode, T> updater, T value, bool trackKinds = true)
        {
            FileCodeModel.EnsureEditor(() =>
            {
                // Sometimes, changing an element can result in needing to update its node key.

                var node     = LookupNode();
                var nodePath = new SyntaxPath(node, trackKinds);

                updater(node, value);

                ReacquireNodeKey(nodePath, CancellationToken.None);
            });
        }
Beispiel #23
0
        /// <summary>
        /// This function re-acquires the key for this code element using the given syntax path.
        /// </summary>
        internal void ReacquireNodeKey(SyntaxPath syntaxPath, CancellationToken cancellationToken)
        {
            Debug.Assert(syntaxPath != null);
            if (!syntaxPath.TryResolve(GetSyntaxTree(), cancellationToken, out SyntaxNode node))
            {
                throw Exceptions.ThrowEFail();
            }

            var newNodeKey = CodeModelService.GetNodeKey(node);

            FileCodeModel.UpdateCodeElementNodeKey(this, _nodeKey, newNodeKey);

            _nodeKey = newNodeKey;
        }
Beispiel #24
0
        public void TestRemoveUsing()
        {
            var text = SourceText.From("using X; class C {}");
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var root = (CompilationUnitSyntax)tree.GetRoot();
            var path = new SyntaxPath(root.Members[0]);

            var newText = WithReplaceFirst(text, "using X;", "");
            var newTree = tree.WithChangedText(newText);

            Assert.True(path.TryResolve(newTree, CancellationToken.None, out SyntaxNode node));

            Assert.Equal(SyntaxKind.ClassDeclaration, node.Kind());
        }
Beispiel #25
0
        public void TestMethodBodyChange()
        {
            var text =
                @"namespace N {
    class C {
      void M1() {
        int i1;
      }
      void M2() {
        int i2;
      }
      void M3() {
        int i3;
      }
    }
  }";

            var tree          = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)(
                tree.GetRoot() as CompilationUnitSyntax
                ).Members[0];
            var classDecl = (TypeDeclarationSyntax)namespaceDecl.Members[0];

            var member1 = classDecl.Members[0];
            var member2 = classDecl.Members[1];
            var member3 = classDecl.Members[2];

            var path1 = new SyntaxPath(member1);
            var path2 = new SyntaxPath(member2);
            var path3 = new SyntaxPath(member3);

            tree = WithReplaceFirst(
                WithReplaceFirst(WithReplaceFirst(tree, "i1", "j1"), "i2", "j2"),
                "i3",
                "j3"
                );
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2));
            Assert.True(path3.TryResolve(tree, CancellationToken.None, out SyntaxNode n3));

            Assert.Equal(SyntaxKind.MethodDeclaration, n1.Kind());
            Assert.Equal("M1", ((MethodDeclarationSyntax)n1).Identifier.ValueText);

            Assert.Equal(SyntaxKind.MethodDeclaration, n2.Kind());
            Assert.Equal("M2", ((MethodDeclarationSyntax)n2).Identifier.ValueText);

            Assert.Equal(SyntaxKind.MethodDeclaration, n3.Kind());
            Assert.Equal("M3", ((MethodDeclarationSyntax)n3).Identifier.ValueText);
        }
        public void TestRoot3()
        {
            var text = SourceText.From("class C {}");
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var root = tree.GetRoot();
            var path = new SyntaxPath(root);

            var newText = text.WithChanges(new TextChange(new TextSpan(0, text.Length), ""));
            var newTree = tree.WithChangedText(newText);

            SyntaxNode node;

            Assert.True(path.TryResolve(newTree, CancellationToken.None, out node));
            Assert.Equal(SyntaxKind.CompilationUnit, node.CSharpKind());
        }
Beispiel #27
0
        public EnvDTE.CodeParameter AddParameter(string name, object type, object position)
        {
            return(FileCodeModel.EnsureEditor(() =>
            {
                // The parameters are part of the node key, so we need to update it
                // after adding a parameter.
                var node = LookupNode();
                var nodePath = new SyntaxPath(node);

                var parameter = FileCodeModel.AddParameter(this, node, name, type, position);

                ReaquireNodeKey(nodePath, CancellationToken.None);

                return parameter;
            }));
        }
                public WorkItem With(
                    InvocationReasons invocationReasons, SyntaxPath currentMember,
                    ImmutableHashSet <IIncrementalAnalyzer> analyzers, bool retry, IAsyncToken asyncToken)
                {
                    // dispose old one
                    AsyncToken.Dispose();

                    // create new work item
                    return(new WorkItem(
                               DocumentId, ProjectId, Language,
                               InvocationReasons.With(invocationReasons),
                               IsLowPriority,
                               ActiveMember == currentMember ? currentMember : null,
                               Union(analyzers), IsRetry || retry,
                               asyncToken));
                }
Beispiel #29
0
        public void TestPP1()
        {
            var text =
                @"namespace N {
    class C {
    }
    struct D {
    }
  }";

            var text2 =
                @"namespace N {
#if true
    class C {
    }
    struct D {
    }
#endif
  }";

            var tree          = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)((CompilationUnitSyntax)tree.GetRoot()).Members[0];
            var class1        = (TypeDeclarationSyntax)namespaceDecl.Members[0];
            var class2        = (TypeDeclarationSyntax)namespaceDecl.Members[1];

            var path1 = new SyntaxPath(class1);
            var path2 = new SyntaxPath(class2);

            tree = WithReplace(tree, 0, text.Length, text2);

            SyntaxNode n1;
            SyntaxNode n2;

            Assert.True(path1.TryResolve(tree, CancellationToken.None, out n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out n2));

            Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind());
            Assert.Equal("C", ((TypeDeclarationSyntax)n1).Identifier.ValueText);
            Assert.Equal(SyntaxKind.StructDeclaration, n2.Kind());
            Assert.Equal("D", ((TypeDeclarationSyntax)n2).Identifier.ValueText);
        }
Beispiel #30
0
                public void Enqueue(Document document, SyntaxPath changedMember)
                {
                    UpdateLastAccessTime();

                    using (_workGate.DisposableWait(CancellationToken))
                    {
                        if (_pendingWork.TryGetValue(document.Id, out var data))
                        {
                            // create new async token and dispose old one.
                            var newAsyncToken = Listener.BeginAsyncOperation(nameof(Enqueue), tag: _registration.Workspace);
                            data.AsyncToken.Dispose();

                            _pendingWork[document.Id] = new Data(document, data.ChangedMember == changedMember ? changedMember : null, newAsyncToken);
                            return;
                        }

                        _pendingWork.Add(document.Id, new Data(document, changedMember, Listener.BeginAsyncOperation(nameof(Enqueue), tag: _registration.Workspace)));
                        _gate.Release();
                    }

                    Logger.Log(FunctionId.WorkCoordinator_SemanticChange_Enqueue, s_enqueueLogger, Environment.TickCount, document.Id, changedMember != null);
                }
Beispiel #31
0
        public void TestAddFieldBefore()
        {
            var text =
                @"namespace N {
    class C {
      void M1() {
        int i1;
      }
      bool M2() {
        int i2;
      }
    }
  }";

            var tree          = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)((CompilationUnitSyntax)tree.GetRoot()).Members[0];
            var classDecl     = (TypeDeclarationSyntax)namespaceDecl.Members[0];

            var member1 = classDecl.Members[0];
            var member2 = classDecl.Members[1];

            var path1 = new SyntaxPath(member1);
            var path2 = new SyntaxPath(member2);

            tree = WithReplaceFirst(tree, "bool", "int field; bool");

            SyntaxNode n1;
            SyntaxNode n2;

            Assert.True(path1.TryResolve(tree, CancellationToken.None, out n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out n2));

            Assert.Equal(SyntaxKind.MethodDeclaration, n1.Kind());
            Assert.Equal("M1", ((MethodDeclarationSyntax)n1).Identifier.ValueText);

            Assert.Equal(SyntaxKind.MethodDeclaration, n2.Kind());
            Assert.Equal("M2", ((MethodDeclarationSyntax)n2).Identifier.ValueText);
        }
                public void Enqueue(Document document, SyntaxPath changedMember)
                {
                    this.UpdateLastAccessTime();

                    using (this.workGate.DisposableWait(this.CancellationToken))
                    {
                        Data data;
                        if (this.pendingWork.TryGetValue(document.Id, out data))
                        {
                            // create new async token and dispose old one.
                            var newAsyncToken = this.Listener.BeginAsyncOperation("EnqueueSemanticChange");
                            data.AsyncToken.Dispose();

                            this.pendingWork[document.Id] = new Data(document, data.ChangedMember == changedMember ? changedMember : null, newAsyncToken);
                            return;
                        }

                        this.pendingWork.Add(document.Id, new Data(document, changedMember, this.Listener.BeginAsyncOperation("EnqueueSemanticChange")));
                        this.gate.Release();
                    }

                    Logger.Log(FunctionId.WorkCoordinator_SemanticChange_Enqueue, enqueueLogger, Environment.TickCount, document.Id, changedMember != null);
                }
Beispiel #33
0
        public void RemoveParameter(object element)
        {
            FileCodeModel.EnsureEditor(() =>
            {
                // The parameters are part of the node key, so we need to update it
                // after removing a parameter.
                var node     = LookupNode();
                var nodePath = new SyntaxPath(node);

                var codeElement = ComAggregate.TryGetManagedObject <AbstractCodeElement>(element);

                codeElement ??= ComAggregate.TryGetManagedObject <AbstractCodeElement>(this.Parameters.Item(element));

                if (codeElement == null)
                {
                    throw new ArgumentException(ServicesVSResources.Element_is_not_valid, nameof(element));
                }

                codeElement.Delete();

                ReacquireNodeKey(nodePath, CancellationToken.None);
            });
        }
                private WorkItem(
                    DocumentId documentId,
                    ProjectId projectId,
                    string language,
                    InvocationReasons invocationReasons,
                    bool isLowPriority,
                    SyntaxPath activeMember,
                    ImmutableHashSet<IIncrementalAnalyzer> analyzers,
                    bool retry,
                    IAsyncToken asyncToken)
                {
                    this.DocumentId = documentId;
                    this.ProjectId = projectId;
                    this.Language = language;
                    this.InvocationReasons = invocationReasons;
                    this.IsLowPriority = isLowPriority;

                    this.ActiveMember = activeMember;
                    this.Analyzers = analyzers;

                    this.IsRetry = retry;

                    this.AsyncToken = asyncToken;
                }
                private WorkItem(
                    DocumentId documentId,
                    ProjectId projectId,
                    string language,
                    InvocationReasons invocationReasons,
                    bool isLowPriority,
                    SyntaxPath activeMember,
                    ImmutableHashSet <IIncrementalAnalyzer> analyzers,
                    bool retry,
                    IAsyncToken asyncToken)
                {
                    DocumentId        = documentId;
                    ProjectId         = projectId;
                    Language          = language;
                    InvocationReasons = invocationReasons;
                    IsLowPriority     = isLowPriority;

                    ActiveMember = activeMember;
                    Analyzers    = analyzers;

                    IsRetry = retry;

                    AsyncToken = asyncToken;
                }
Beispiel #36
0
 public Data(Document document, SyntaxPath changedMember, IAsyncToken asyncToken)
 {
     AsyncToken    = asyncToken;
     Document      = document;
     ChangedMember = changedMember;
 }
Beispiel #37
0
        public void TestChangeType1()
        {
            var text =
@"namespace N {
    class C {
      void Foo();
    }
    class D {
    }
  }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)((CompilationUnitSyntax)tree.GetRoot()).Members[0];
            var class1 = (TypeDeclarationSyntax)namespaceDecl.Members[0];
            var class2 = (TypeDeclarationSyntax)namespaceDecl.Members[1];
            var method1 = class1.Members[0];

            var path1 = new SyntaxPath(class1);
            var path2 = new SyntaxPath(class2);
            var path3 = new SyntaxPath(method1);

            tree = WithReplaceFirst(tree, "class", "struct");
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1));
            Assert.False(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2));
            Assert.False(path3.TryResolve(tree, CancellationToken.None, out SyntaxNode n3));

            Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind());
            Assert.Equal("D", ((TypeDeclarationSyntax)n1).Identifier.ValueText);
        }
Beispiel #38
0
        public static void LogWorkItemEnqueue(
            LogAggregator logAggregator, string language, DocumentId documentId, InvocationReasons reasons, bool lowPriority, SyntaxPath activeMember, bool added)
        {
            logAggregator.IncreaseCount(language);
            logAggregator.IncreaseCount(added ? NewWorkItem : UpdateWorkItem);

            if (documentId != null)
            {
                logAggregator.IncreaseCount(activeMember == null ? TopLevel : MemberLevel);

                if (lowPriority)
                {
                    logAggregator.IncreaseCount(LowerPriority);
                    logAggregator.IncreaseCount(ValueTuple.Create(LowerPriority, documentId.Id));
                }
            }

            foreach (var reason in reasons)
            {
                logAggregator.IncreaseCount(reason);
            }
        }
        private async Task<Solution> RenameThenAddAsyncTokenAsync(
            bool keepVoid, Document document, SyntaxNode node,
            IMethodSymbol methodSymbol, CancellationToken cancellationToken)
        {
            var name = methodSymbol.Name;
            var newName = name + AsyncSuffix;
            var solution = document.Project.Solution;

            // Store the path to this node.  That way we can find it post rename.
            var syntaxPath = new SyntaxPath(node);

            // Rename the method to add the 'Async' suffix, then add the 'async' keyword.
            var newSolution = await Renamer.RenameSymbolAsync(solution, methodSymbol, newName, solution.Options, cancellationToken).ConfigureAwait(false);
            var newDocument = newSolution.GetDocument(document.Id);
            var newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            SyntaxNode newNode;
            if (syntaxPath.TryResolve(newRoot, out newNode))
            {
                var semanticModel = await newDocument.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);
                var newMethod = (IMethodSymbol)semanticModel.GetDeclaredSymbol(newNode, cancellationToken);
                return await AddAsyncTokenAsync(keepVoid, newDocument, newMethod, newNode, cancellationToken).ConfigureAwait(false);
            }

            return newSolution;
        }
Beispiel #40
0
 public Data(Document document, SyntaxPath changedMember, IAsyncToken asyncToken)
 {
     this.AsyncToken    = asyncToken;
     this.Document      = document;
     this.ChangedMember = changedMember;
 }
Beispiel #41
0
        public void RemoveParameter(object element)
        {
            FileCodeModel.EnsureEditor(() =>
            {
                // The parameters are part of the node key, so we need to update it
                // after removing a parameter.
                var node = LookupNode();
                var nodePath = new SyntaxPath(node);

                var codeElement = ComAggregate.TryGetManagedObject<AbstractCodeElement>(element);

                if (codeElement == null)
                {
                    codeElement = ComAggregate.TryGetManagedObject<AbstractCodeElement>(this.Parameters.Item(element));
                }

                if (codeElement == null)
                {
                    throw new ArgumentException(ServicesVSResources.ElementIsNotValid, "element");
                }

                codeElement.Delete();

                ReaquireNodeKey(nodePath, CancellationToken.None);
            });
        }
Beispiel #42
0
        public void TestRemoveUsing()
        {
            var text = SourceText.From("using X; class C {}");
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var root = (CompilationUnitSyntax)tree.GetRoot();
            var path = new SyntaxPath(root.Members[0]);

            var newText = WithReplaceFirst(text, "using X;", "");
            var newTree = tree.WithChangedText(newText);
            Assert.True(path.TryResolve(newTree, CancellationToken.None, out SyntaxNode node));

            Assert.Equal(SyntaxKind.ClassDeclaration, node.Kind());
        }
Beispiel #43
0
 public GlobalNodeKey(SyntaxNodeKey nodeKey, SyntaxPath path)
 {
     this.NodeKey = nodeKey;
     this.Path = path;
 }
Beispiel #44
0
        public void TestComment()
        {
            var text =
@"namespace N {
    class C {
    }
    struct D {
    }
  }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)((CompilationUnitSyntax)tree.GetRoot()).Members[0];
            var class1 = (TypeDeclarationSyntax)namespaceDecl.Members[0];
            var class2 = (TypeDeclarationSyntax)namespaceDecl.Members[1];

            var path1 = new SyntaxPath(class1);
            var path2 = new SyntaxPath(class2);

            tree = WithReplaceFirst(WithReplaceFirst(tree, "class", "/* foo */ class"), "struct", "/* bar */ struct");

            SyntaxNode n1;
            SyntaxNode n2;
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out n2));

            Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind());
            Assert.Equal("C", ((TypeDeclarationSyntax)n1).Identifier.ValueText);
            Assert.Equal(SyntaxKind.StructDeclaration, n2.Kind());
            Assert.Equal("D", ((TypeDeclarationSyntax)n2).Identifier.ValueText);
        }
        private void TryStartRenameSession(Workspace workspace, Solution oldSolution, Solution newSolution, CancellationToken cancellationToken)
        {
            var changedDocuments = newSolution.GetChangedDocuments(oldSolution);
            foreach (var documentId in changedDocuments)
            {
                var document = newSolution.GetDocument(documentId);
                if (!document.SupportsSyntaxTree)
                {
                    continue;
                }

                var root = document.GetSyntaxRootSynchronously(cancellationToken);

                var renameTokenOpt = root.GetAnnotatedNodesAndTokens(RenameAnnotation.Kind)
                                         .Where(s => s.IsToken)
                                         .Select(s => s.AsToken())
                                         .FirstOrNullable();

                if (renameTokenOpt.HasValue)
                {
                    // It's possible that the workspace's current solution is not the same as
                    // newSolution. This can happen if the workspace host performs other edits
                    // during ApplyChanges, such as in the Venus scenario where indentation and
                    // formatting can happen. To work around this, we create a SyntaxPath to the
                    // rename token in the newSolution and resolve it to the current solution.

                    var pathToRenameToken = new SyntaxPath(renameTokenOpt.Value);
                    var latestDocument = workspace.CurrentSolution.GetDocument(documentId);
                    var latestRoot = latestDocument.GetSyntaxRootSynchronously(cancellationToken);

                    SyntaxNodeOrToken resolvedRenameToken;
                    if (pathToRenameToken.TryResolve(latestRoot, out resolvedRenameToken) &&
                        resolvedRenameToken.IsToken)
                    {
                        var editorWorkspace = workspace;
                        var navigationService = editorWorkspace.Services.GetService<IDocumentNavigationService>();
                        if (navigationService.TryNavigateToSpan(editorWorkspace, documentId, resolvedRenameToken.Span))
                        {
                            var openDocument = workspace.CurrentSolution.GetDocument(documentId);
                            var openRoot = openDocument.GetSyntaxRootSynchronously(cancellationToken);

                            // NOTE: We need to resolve the syntax path again in case VB line commit kicked in
                            // due to the navigation.

                            // TODO(DustinCa): We still have a potential problem here with VB line commit,
                            // because it can insert tokens and all sorts of other business, which could
                            // wind up with us not being able to resolve the token.
                            if (pathToRenameToken.TryResolve(openRoot, out resolvedRenameToken) &&
                                resolvedRenameToken.IsToken)
                            {
                                var snapshot = openDocument.GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken).FindCorrespondingEditorTextSnapshot();
                                if (snapshot != null)
                                {
                                    _renameService.StartInlineSession(openDocument, resolvedRenameToken.AsToken().Span, cancellationToken);
                                }
                            }
                        }
                    }

                    return;
                }
            }
        }
Beispiel #46
0
        public void TestRoot2()
        {
            var text = SourceText.From(string.Empty);
            var tree = SyntaxFactory.ParseSyntaxTree(string.Empty);
            var root = tree.GetCompilationUnitRoot();
            var path = new SyntaxPath(root);

            var newText = text.WithChanges(new TextChange(new TextSpan(0, 0), "class C {}"));
            var newTree = tree.WithChangedText(newText);
            Assert.True(path.TryResolve(newTree, CancellationToken.None, out SyntaxNode node));
            Assert.Equal(SyntaxKind.CompilationUnit, node.Kind());
        }
                public WorkItem With(
                    InvocationReasons invocationReasons, SyntaxPath currentMember,
                    ImmutableHashSet<IIncrementalAnalyzer> analyzers, bool retry, IAsyncToken asyncToken)
                {
                    // dispose old one
                    this.AsyncToken.Dispose();

                    // create new work item
                    return new WorkItem(
                        this.DocumentId, this.ProjectId, this.Language,
                        InvocationReasons.With(invocationReasons),
                        IsLowPriority,
                        this.ActiveMember == currentMember ? currentMember : null,
                        Union(analyzers), this.IsRetry || retry,
                        asyncToken);
                }
        public static void LogWorkItemEnqueue(
            LogAggregator logAggregator, string language, DocumentId documentId, InvocationReasons reasons, bool lowPriority, SyntaxPath activeMember, bool added)
        {
            logAggregator.IncreaseCount(language);
            logAggregator.IncreaseCount(added ? NewWorkItem : UpdateWorkItem);

            if (documentId != null)
            {
                logAggregator.IncreaseCount(activeMember == null ? TopLevel : MemberLevel);

                if (lowPriority)
                {
                    logAggregator.IncreaseCount(LowerPriority);
                    logAggregator.IncreaseCount(ValueTuple.Create(LowerPriority, documentId.Id));
                }
            }

            foreach (var reason in reasons)
            {
                logAggregator.IncreaseCount(reason);
            }
        }
Beispiel #49
0
        public void TestAddFieldBefore()
        {
            var text =
@"namespace N {
    class C {
      void M1() {
        int i1;
      }
      bool M2() {
        int i2;
      }
    }
  }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)((CompilationUnitSyntax)tree.GetRoot()).Members[0];
            var classDecl = (TypeDeclarationSyntax)namespaceDecl.Members[0];

            var member1 = classDecl.Members[0];
            var member2 = classDecl.Members[1];

            var path1 = new SyntaxPath(member1);
            var path2 = new SyntaxPath(member2);

            tree = WithReplaceFirst(tree, "bool", "int field; bool");
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2));

            Assert.Equal(SyntaxKind.MethodDeclaration, n1.Kind());
            Assert.Equal("M1", ((MethodDeclarationSyntax)n1).Identifier.ValueText);

            Assert.Equal(SyntaxKind.MethodDeclaration, n2.Kind());
            Assert.Equal("M2", ((MethodDeclarationSyntax)n2).Identifier.ValueText);
        }
Beispiel #50
0
        public void TestRoot4()
        {
            var text = "class C {}";
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var root = tree.GetRoot();
            var path = new SyntaxPath(root);

            tree = WithReplaceFirst(tree, "C", "D");
            Assert.True(path.TryResolve(tree, CancellationToken.None, out SyntaxNode node));
            Assert.Equal(SyntaxKind.CompilationUnit, node.Kind());
        }
Beispiel #51
0
        public void TestPP1()
        {
            var text =
@"namespace N {
    class C {
    }
    struct D {
    }
  }";

            var text2 =
@"namespace N {
#if true
    class C {
    }
    struct D {
    }
#endif
  }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)((CompilationUnitSyntax)tree.GetRoot()).Members[0];
            var class1 = (TypeDeclarationSyntax)namespaceDecl.Members[0];
            var class2 = (TypeDeclarationSyntax)namespaceDecl.Members[1];

            var path1 = new SyntaxPath(class1);
            var path2 = new SyntaxPath(class2);

            tree = WithReplace(tree, 0, text.Length, text2);
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2));

            Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind());
            Assert.Equal("C", ((TypeDeclarationSyntax)n1).Identifier.ValueText);
            Assert.Equal(SyntaxKind.StructDeclaration, n2.Kind());
            Assert.Equal("D", ((TypeDeclarationSyntax)n2).Identifier.ValueText);
        }
Beispiel #52
0
        private void TryStartRenameSession(Workspace workspace, Solution oldSolution, Solution newSolution, CancellationToken cancellationToken)
        {
            var changedDocuments = newSolution.GetChangedDocuments(oldSolution);

            foreach (var documentId in changedDocuments)
            {
                var document = newSolution.GetDocument(documentId);
                if (!document.SupportsSyntaxTree)
                {
                    continue;
                }

                var root = document.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);

                var renameTokenOpt = root.GetAnnotatedNodesAndTokens(RenameAnnotation.Kind)
                                     .Where(s => s.IsToken)
                                     .Select(s => s.AsToken())
                                     .FirstOrNullable();

                if (renameTokenOpt.HasValue)
                {
                    // It's possible that the workspace's current solution is not the same as
                    // newSolution. This can happen if the workspace host performs other edits
                    // during ApplyChanges, such as in the Venus scenario where indentation and
                    // formatting can happen. To work around this, we create a SyntaxPath to the
                    // rename token in the newSolution and resolve it to the current solution.

                    var pathToRenameToken = new SyntaxPath(renameTokenOpt.Value);
                    var latestDocument    = workspace.CurrentSolution.GetDocument(documentId);
                    var latestRoot        = latestDocument.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);

                    SyntaxNodeOrToken resolvedRenameToken;
                    if (pathToRenameToken.TryResolve(latestRoot, out resolvedRenameToken) &&
                        resolvedRenameToken.IsToken)
                    {
                        var editorWorkspace   = workspace;
                        var navigationService = editorWorkspace.Services.GetService <IDocumentNavigationService>();
                        if (navigationService.TryNavigateToSpan(editorWorkspace, documentId, resolvedRenameToken.Span))
                        {
                            var openDocument = workspace.CurrentSolution.GetDocument(documentId);
                            var openRoot     = openDocument.GetSyntaxRootAsync(cancellationToken).WaitAndGetResult(cancellationToken);

                            // NOTE: We need to resolve the syntax path again in case VB line commit kicked in
                            // due to the navigation.

                            // TODO(DustinCa): We still have a potential problem here with VB line commit,
                            // because it can insert tokens and all sorts of other business, which could
                            // wind up with us not being able to resolve the token.
                            if (pathToRenameToken.TryResolve(openRoot, out resolvedRenameToken) &&
                                resolvedRenameToken.IsToken)
                            {
                                var snapshot = openDocument.GetTextAsync(cancellationToken).WaitAndGetResult(cancellationToken).FindCorrespondingEditorTextSnapshot();
                                if (snapshot != null)
                                {
                                    _renameService.StartInlineSession(openDocument, resolvedRenameToken.AsToken().Span, cancellationToken);
                                }
                            }
                        }
                    }

                    return;
                }
            }
        }
                private static SyntaxNode GetMemberNode(ISyntaxFactsService service, SyntaxNode root, SyntaxPath memberPath)
                {
                    if (root == null || memberPath == null)
                    {
                        return(null);
                    }

                    SyntaxNode memberNode;

                    if (!memberPath.TryResolve(root, out memberNode))
                    {
                        return(null);
                    }

                    return(service.IsMethodLevelMember(memberNode) ? memberNode : null);
                }
        public void TestRoot3()
        {
            var text = SourceText.From("class C {}");
            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var root = tree.GetRoot();
            var path = new SyntaxPath(root);

            var newText = text.WithChanges(new TextChange(new TextSpan(0, text.Length), ""));
            var newTree = tree.WithChangedText(newText);

            SyntaxNode node;
            Assert.True(path.TryResolve(newTree, CancellationToken.None, out node));
            Assert.Equal(SyntaxKind.CompilationUnit, node.CSharpKind());
        }
Beispiel #55
0
        public EnvDTE.CodeParameter AddParameter(string name, object type, object position)
        {
            return FileCodeModel.EnsureEditor(() =>
            {
                // The parameters are part of the node key, so we need to update it
                // after adding a parameter.
                var node = LookupNode();
                var nodePath = new SyntaxPath(node);

                var parameter = FileCodeModel.AddParameter(this, node, name, type, position);

                ReaquireNodeKey(nodePath, CancellationToken.None);

                return parameter;
            });
        }
Beispiel #56
0
        public void TestAddBase()
        {
            var text =
@"namespace N {
    class C {
    }
    class D {
    }
  }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)(tree.GetRoot() as CompilationUnitSyntax).Members[0];
            var class1 = (TypeDeclarationSyntax)namespaceDecl.Members[0];
            var class2 = (TypeDeclarationSyntax)namespaceDecl.Members[1];

            var path1 = new SyntaxPath(class1);
            var path2 = new SyntaxPath(class2);

            tree = WithReplaceFirst(tree, "C {", "C : Foo {");
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2));

            Assert.Equal(SyntaxKind.ClassDeclaration, n1.Kind());
            Assert.Equal("C", ((TypeDeclarationSyntax)n1).Identifier.ValueText);
            Assert.Equal(SyntaxKind.ClassDeclaration, n2.Kind());
            Assert.Equal("D", ((TypeDeclarationSyntax)n2).Identifier.ValueText);
        }
Beispiel #57
0
        public void TestMethodBodyChange()
        {
            var text =
@"namespace N {
    class C {
      void M1() {
        int i1;
      }
      void M2() {
        int i2;
      }
      void M3() {
        int i3;
      }
    }
  }";

            var tree = SyntaxFactory.ParseSyntaxTree(text);
            var namespaceDecl = (NamespaceDeclarationSyntax)(tree.GetRoot() as CompilationUnitSyntax).Members[0];
            var classDecl = (TypeDeclarationSyntax)namespaceDecl.Members[0];

            var member1 = classDecl.Members[0];
            var member2 = classDecl.Members[1];
            var member3 = classDecl.Members[2];

            var path1 = new SyntaxPath(member1);
            var path2 = new SyntaxPath(member2);
            var path3 = new SyntaxPath(member3);

            tree = WithReplaceFirst(WithReplaceFirst(WithReplaceFirst(tree, "i1", "j1"), "i2", "j2"), "i3", "j3");
            Assert.True(path1.TryResolve(tree, CancellationToken.None, out SyntaxNode n1));
            Assert.True(path2.TryResolve(tree, CancellationToken.None, out SyntaxNode n2));
            Assert.True(path3.TryResolve(tree, CancellationToken.None, out SyntaxNode n3));

            Assert.Equal(SyntaxKind.MethodDeclaration, n1.Kind());
            Assert.Equal("M1", ((MethodDeclarationSyntax)n1).Identifier.ValueText);

            Assert.Equal(SyntaxKind.MethodDeclaration, n2.Kind());
            Assert.Equal("M2", ((MethodDeclarationSyntax)n2).Identifier.ValueText);

            Assert.Equal(SyntaxKind.MethodDeclaration, n3.Kind());
            Assert.Equal("M3", ((MethodDeclarationSyntax)n3).Identifier.ValueText);
        }