' Copyright (c) Microsoft Open Technologies, Inc. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. Imports System.Globalization Imports System.Linq Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports Roslyn.Test.Utilities Namespace Microsoft.CodeAnalysis.VisualBasic.UnitTests Public Class TestSyntaxNodes Dim spaceTrivia As SyntaxTrivia = SyntaxFactory.WhitespaceTrivia(" ") Dim NewlineTrivia As SyntaxTriviaList = SyntaxTriviaListBuilder.Create.Add(SyntaxFactory.WhitespaceTrivia(Environment.NewLine)).ToList Private Function CreateIntegerLiteral(value As ULong) As LiteralExpressionSyntax Return SyntaxFactory.NumericLiteralExpression(SyntaxFactory.IntegerLiteralToken(value.ToString(), LiteralBase.Decimal, TypeCharacter.None, value)) End Function ' Creates "1- X( 3, 4+ 8, 9)" Private Function CreateSimpleTree() As BinaryExpressionSyntax Dim operandsx() As ArgumentSyntax = {SyntaxFactory.SimpleArgument(CreateIntegerLiteral(3)), SyntaxFactory.SimpleArgument(SyntaxFactory.AddExpression(CreateIntegerLiteral(4), SyntaxFactory.Token(SyntaxKind.PlusToken, trailing:=spaceTrivia), CreateIntegerLiteral(8))), SyntaxFactory.SimpleArgument(CreateIntegerLiteral(9))} 'Dim operands = New SeparatedSyntaxListBuilder(Of ArgumentSyntax)(8) 'operands.Add(Syntax.SimpleArgument(CreateIntegerLiteral(3))) 'operands.AddSeparator(Syntax.Token(SyntaxKind.CommaToken,spaceTrivia)) 'operands.Add(Syntax.SimpleArgument(Syntax.AddExpression(CreateIntegerLiteral(4), 'Syntax.Token(SyntaxKind.PlusToken,spaceTrivia), CreateIntegerLiteral(8)))) 'operands.AddSeparator(Syntax.Token(SyntaxKind.CommaToken,spaceTrivia)) 'operands.Add(Syntax.SimpleArgument(CreateIntegerLiteral(9))) ' Use Syntax.Separatlist factory method instead of builder Dim operands = SyntaxFactory.SeparatedList(Of ArgumentSyntax)({SyntaxFactory.SimpleArgument(CreateIntegerLiteral(3)), SyntaxFactory.SimpleArgument(SyntaxFactory.AddExpression(CreateIntegerLiteral(4), SyntaxFactory.Token(SyntaxKind.PlusToken, trailing:=spaceTrivia), CreateIntegerLiteral(8))), SyntaxFactory.SimpleArgument(CreateIntegerLiteral(9))}, {SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia) }) Return SyntaxFactory.SubtractExpression(CreateIntegerLiteral(1), SyntaxFactory.Token(SyntaxKind.MinusToken, trailing:=spaceTrivia), SyntaxFactory.InvocationExpression(SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("X")), SyntaxFactory.ArgumentList(SyntaxFactory.Token(SyntaxKind.OpenParenToken, trailing:=spaceTrivia), operands, SyntaxFactory.Token(SyntaxKind.CloseParenToken, trailing:=spaceTrivia)))) End Function Public Sub TestParents() Dim simpleTree = CreateSimpleTree() Assert.Null(simpleTree.Parent) Assert.Equal(simpleTree, CType(simpleTree, BinaryExpressionSyntax).Left.Parent) Assert.Equal(simpleTree, CType(simpleTree, BinaryExpressionSyntax).Right.Parent) Dim x As InvocationExpressionSyntax = CType(CType(simpleTree, BinaryExpressionSyntax).Right, InvocationExpressionSyntax) Dim argList As ArgumentListSyntax = x.ArgumentList Assert.Equal(argList, argList.Arguments(0).Parent) Assert.Equal(argList, argList.Arguments(1).Parent) Assert.Equal(argList, argList.Arguments.GetWithSeparators(1).Parent) Assert.Equal(argList, argList.Arguments.GetWithSeparators(3).Parent) End Sub Public Sub TestChildren() Dim simpleTree = CreateSimpleTree() Dim invocation As InvocationExpressionSyntax = CType(CType(simpleTree, BinaryExpressionSyntax).Right, InvocationExpressionSyntax) Dim argList As ArgumentListSyntax = invocation.ArgumentList Dim children = argList.ChildNodesAndTokens() Assert.Equal(7, children.Count) Assert.Equal(children(0), argList.OpenParenToken) Assert.Equal(children(1), argList.Arguments(0)) Assert.Equal(children(2), argList.Arguments.GetWithSeparators(1)) Assert.Equal(children(3), argList.Arguments(1)) Assert.Equal(children(4), argList.Arguments.GetWithSeparators(3)) Assert.Equal(children(5), argList.Arguments(2)) Assert.Equal(children(6), argList.CloseParenToken) children = simpleTree.ChildNodesAndTokens() Dim binop = DirectCast(simpleTree, BinaryExpressionSyntax) Assert.Equal(3, children.Count) Assert.Equal(children(0), binop.Left) Assert.Equal(children(1), binop.OperatorToken) Assert.Equal(children(2), binop.Right) Dim ItemList As New List(Of String) Dim ItemListRev As New List(Of String) Dim VB1 = children.GetEnumerator Do While VB1.MoveNext ItemList.Add(VB1.Current.ToString) Loop Dim i As SyntaxNodeOrToken For Each i In children.Reverse ItemListRev.Add(i.ToString) Next Assert.Equal(ItemList.Count, ItemListRev.Count) If (ItemList.Count > 0) Then Dim L0 As Integer = (ItemList.Count - 1) Dim I0 As Integer = 0 Do While (I0 <= L0) Assert.Equal(ItemList.Item(I0), ItemListRev.Item(((ItemList.Count - 1) - I0))) I0 += 1 Loop End If Assert.NotEqual(0, children.GetHashCode) Assert.NotEqual(0, children.Reverse.GetHashCode) Dim b1 As Integer = 0 Dim enumerator = children.GetEnumerator enumerator.Reset() Do While enumerator.MoveNext Dim item1 As SyntaxNodeOrToken = enumerator.Current b1 += 1 Loop Dim b2 As Integer = 0 Dim enumeratorr = children.Reverse.GetEnumerator enumeratorr.Reset() Do While enumeratorr.MoveNext Dim item1 As SyntaxNodeOrToken = enumeratorr.Current b2 += 1 Loop Assert.Equal(b1, b2) Assert.Throws(Of ArgumentOutOfRangeException)((Sub() Dim i1 As SyntaxNodeOrToken = children.Item(-1) End Sub )) Assert.Equal(ItemList.Item((ItemList.Count - 1)), children.Last.ToString) Assert.Equal(ItemList.Item(0), Enumerable.First(Of SyntaxNodeOrToken)(DirectCast(children, IEnumerable(Of SyntaxNodeOrToken))).ToString) 'Comparison operators = and <> Dim xc As ChildSyntaxList = children Assert.Equal(xc, children) Assert.NotEqual(xc, New ChildSyntaxList) 'Explicitly calling the <> operator as a double negative Assert.False(xc <> children, "Verifying <> operator for ChildSyntaxList items - This should return false as xc was assigned from Children") End Sub ' Verify spans within a list of consecutive nodes are all consistent. Private Sub VerifyListSpans(Of T As VisualBasicSyntaxNode)(list As SyntaxList(Of T), expectedFullSpan As TextSpan) If list.Count > 0 Then ' List should fill up the full span. Assert.Equal(expectedFullSpan.Start, list(0).FullSpan.Start) Assert.Equal(expectedFullSpan.End, list(list.Count - 1).FullSpan.End) For i = 0 To list.Count - 1 ' Make sure children's full spans are adjacent If i > 0 Then Assert.Equal(list(i - 1).FullSpan.End, list(i).FullSpan.Start) End If If i < list.Count - 1 Then Assert.Equal(list(i).FullSpan.End, list(i + 1).FullSpan.Start) End If ' Recursively verify VerifyAllSpans(list(i)) Next End If End Sub ' Verify spans within a list of consecutive nodes are all consistent. Private Sub VerifyListSpans(list As ChildSyntaxList, expectedFullSpan As TextSpan) If list.Count > 0 Then ' List should fill up the full span. Assert.Equal(expectedFullSpan.Start, list(0).FullSpan.Start) Assert.Equal(expectedFullSpan.End, list(list.Count - 1).FullSpan.End) For i = 0 To list.Count - 2 ' Make sure children's full spans are adjacent Assert.Equal(list(i).FullSpan.End, list(i + 1).FullSpan.Start) ' Recursively verify Dim node = list(i) If node.IsNode Then VerifyAllSpans(node.AsNode) End If Next End If End Sub ' Verify spans within a list of consecutive nodes are all consistent. Private Sub VerifyListSpans(list As SyntaxNodeOrTokenList, expectedFullSpan As TextSpan) If list.Count > 0 Then ' List should fill up the full span. Assert.Equal(expectedFullSpan.Start, list(0).FullSpan.Start) Assert.Equal(expectedFullSpan.End, list(list.Count - 1).FullSpan.End) For i = 0 To list.Count - 1 ' Make sure children's full spans are adjacent If i > 0 Then Assert.Equal(list(i - 1).FullSpan.End, list(i).FullSpan.Start) End If If i < list.Count - 1 Then Assert.Equal(list(i).FullSpan.End, list(i + 1).FullSpan.Start) End If ' Recursively verify If list(i).IsNode Then VerifyAllSpans(list(i).AsNode) End If Next End If End Sub ' Verify spans within a list of consecutive nodes are all consistent. Private Sub VerifyListSpans(list As SyntaxTokenList, expectedFullSpan As TextSpan) If list.Count > 0 Then ' List should fill up the full span. Assert.Equal(expectedFullSpan.Start, list(0).FullSpan.Start) Assert.Equal(expectedFullSpan.End, list(list.Count - 1).FullSpan.End) For i = 0 To list.Count - 1 ' Make sure children's full spans are adjacent If i > 0 Then Assert.Equal(list(i - 1).FullSpan.End, list(i).FullSpan.Start) End If If i < list.Count - 1 Then Assert.Equal(list(i).FullSpan.End, list(i + 1).FullSpan.Start) End If Next End If End Sub ' Verify spans within a list of consecutive nodes are all consistent. Private Sub VerifyListSpans(list As SyntaxTriviaList, expectedFullSpan As TextSpan) If list.Count > 0 Then ' List should fill up the full span. Assert.Equal(expectedFullSpan.Start, list(0).FullSpan.Start) Assert.Equal(expectedFullSpan.End, list(list.Count - 1).FullSpan.End) For i = 0 To list.Count - 2 ' Make sure children's full spans are adjacent Assert.Equal(list(i).FullSpan.End, list(i + 1).FullSpan.Start) Next End If End Sub ' Check that spans within a given tree are all consistent. Makes sure the children's spans all ' line up correctly. Private Sub VerifyAllSpans(tree As SyntaxNode) Assert.True(tree.FullSpan.Contains(tree.Span)) If tree.IsStructuredTrivia Then ' For trivia, the full span and regular span must be equal. Assert.Equal(tree.Span, tree.FullSpan) Else ' For tokens and non-terminals, validate the trivia spans. Dim precedingTrivia = tree.GetLeadingTrivia(), followingTrivia = tree.GetTrailingTrivia() If precedingTrivia.Count = 0 Then Assert.Equal(tree.SpanStart, tree.FullSpan.Start) Else VerifyListSpans(precedingTrivia, New TextSpan(tree.FullSpan.Start, (tree.SpanStart - tree.FullSpan.Start))) End If If followingTrivia.Count = 0 Then Assert.Equal(tree.Span.End, tree.FullSpan.End) Else VerifyListSpans(followingTrivia, New TextSpan(tree.Span.End, (tree.FullSpan.End - tree.Span.End))) End If End If ' Validate the children. VerifyListSpans(tree.ChildNodesAndTokens(), tree.FullSpan) End Sub ' Check that spans within a given tree are all consistent. Makes sure the children's spans all ' line up correctly. Private Sub VerifyAllSpans(tree As SyntaxToken) Assert.True(tree.FullSpan.Contains(tree.Span)) ' For tokens and non-terminals, validate the trivia spans. Dim precedingTrivia = tree.LeadingTrivia(), followingTrivia = tree.TrailingTrivia() If precedingTrivia.Count = 0 Then Assert.Equal(tree.SpanStart, tree.FullSpan.Start) Else VerifyListSpans(precedingTrivia, New TextSpan(tree.FullSpan.Start, (tree.SpanStart - tree.FullSpan.Start))) End If If followingTrivia.Count = 0 Then Assert.Equal(tree.Span.End, tree.FullSpan.End) Else VerifyListSpans(followingTrivia, New TextSpan(tree.Span.End, (tree.FullSpan.End - tree.Span.End))) End If End Sub Public Sub TestSpans() Dim dig1 = CreateIntegerLiteral(3) Assert.Equal(New TextSpan(0, 1), dig1.Span) Assert.Equal(New TextSpan(0, 1), dig1.FullSpan) Dim binop = SyntaxFactory.AddExpression( CreateIntegerLiteral(4), SyntaxFactory.Token(SyntaxKind.PlusToken, trailing:=spaceTrivia), CreateIntegerLiteral(8)) Assert.Equal(New TextSpan(0, 4), binop.Span) Assert.Equal(New TextSpan(1, 1), binop.OperatorToken.Span) Assert.Equal(New TextSpan(1, 2), binop.OperatorToken.FullSpan) Assert.Equal(New TextSpan(3, 1), binop.Right.Span) Assert.Equal(New TextSpan(3, 1), binop.Right.FullSpan) Dim simpleTree = CreateSimpleTree() Assert.Equal(New TextSpan(0, 17), simpleTree.Span) Assert.Equal(New TextSpan(0, 18), simpleTree.FullSpan) Assert.Equal(New TextSpan(3, 14), DirectCast(simpleTree, BinaryExpressionSyntax).Right.Span) Dim argList = DirectCast(DirectCast(simpleTree, BinaryExpressionSyntax).Right, InvocationExpressionSyntax).ArgumentList Assert.Equal(New TextSpan(6, 1), argList.Arguments(0).Span) Assert.Equal(New TextSpan(7, 1), argList.Arguments.GetWithSeparators(1).Span) Assert.Equal(New TextSpan(9, 4), argList.Arguments(1).Span) Assert.Equal(New TextSpan(13, 1), argList.Arguments.GetWithSeparators(3).Span) Assert.Equal(New TextSpan(15, 1), argList.Arguments(2).Span) End Sub Public Sub TestSpans2() Dim stmt1 = SyntaxFactory.ReturnStatement(SyntaxFactory.Token(SyntaxKind.ReturnKeyword, trailing:=spaceTrivia), CreateIntegerLiteral(5)) Dim stmt2 = SyntaxFactory.ReturnStatement(SyntaxFactory.Token(SyntaxKind.ReturnKeyword, trailing:=spaceTrivia), CreateIntegerLiteral(178)) Dim listBldr = SyntaxNodeOrTokenListBuilder.Create() listBldr.Add(stmt1) listBldr.Add(SyntaxFactory.Token(SyntaxKind.StatementTerminatorToken)) listBldr.Add(stmt2) listBldr.Add(SyntaxFactory.Token(SyntaxKind.StatementTerminatorToken)) Dim statements = listBldr.ToList VerifyListSpans(statements, TextSpan.FromBounds(statements(0).FullSpan.Start, statements(statements.Count - 1).FullSpan.End)) Dim item1 = SyntaxFactory.HandlesClauseItem(SyntaxFactory.KeywordEventContainer(SyntaxFactory.Token(SyntaxKind.MeKeyword, trailing:=spaceTrivia)), SyntaxFactory.Token(SyntaxKind.DotToken, trailing:=spaceTrivia), SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia))) Dim item2 = SyntaxFactory.HandlesClauseItem(SyntaxFactory.KeywordEventContainer(SyntaxFactory.Token(SyntaxKind.MeKeyword, trailing:=spaceTrivia)), SyntaxFactory.Token(SyntaxKind.DotToken, trailing:=spaceTrivia), SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "banana", spaceTrivia))) listBldr.Clear() listBldr.Add(item1) listBldr.Add(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia)) listBldr.Add(item2) Dim handlesClause = SyntaxFactory.HandlesClause(SyntaxFactory.Token(SyntaxKind.HandlesKeyword, trailing:=spaceTrivia), New SeparatedSyntaxList(Of HandlesClauseItemSyntax)(listBldr.ToList)) VerifyAllSpans(handlesClause) Dim modifiedIdent1 = SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, SyntaxFactory.SingletonList(SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.Token(SyntaxKind.OpenParenToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(SyntaxKind.CloseParenToken, trailing:=spaceTrivia)))) Dim modifiedIdent2 = SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "banana", spaceTrivia), Nothing, Nothing, SyntaxFactory.SingletonList(SyntaxFactory.ArrayRankSpecifier(SyntaxFactory.Token(SyntaxKind.OpenParenToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(SyntaxKind.CloseParenToken, trailing:=spaceTrivia)))) listBldr.Clear() listBldr.Add(modifiedIdent1) listBldr.Add(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia)) listBldr.Add(modifiedIdent2) Dim declarator = SyntaxFactory.VariableDeclarator(New SeparatedSyntaxList(Of ModifiedIdentifierSyntax)(listBldr.ToList), Nothing, Nothing) VerifyAllSpans(declarator) End Sub Public Sub TestSpans2_Invalid() ' Validate the exceptions being generated when Invalid arguments are used for a TextSpan Constructor Assert.Throws(Of ArgumentOutOfRangeException)(Sub() Dim x As New TextSpan(-1, 0) End Sub) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() Dim x As New TextSpan(0, -1) End Sub) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() Dim x As New TextSpan(-1, -1) End Sub) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() Dim x As New TextSpan(2, -4) End Sub) End Sub ' Test that a list with 0 items works correctly. Public Sub TestEmptyList() Dim l = New SyntaxTokenList Assert.Equal(0, l.Count) Dim attrBlock = SyntaxFactory.AttributeList(SyntaxFactory.Token(SyntaxKind.LessThanToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(SyntaxKind.GreaterThanToken, trailing:=spaceTrivia)) Dim param = SyntaxFactory.Parameter(SyntaxFactory.SingletonList(attrBlock), l, SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) Assert.NotNull(param.Modifiers) Assert.Equal(0, param.Modifiers.Count) param = SyntaxFactory.Parameter(SyntaxFactory.SingletonList(attrBlock), Nothing, SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) Assert.NotNull(param.Modifiers) Assert.Equal(0, param.Modifiers.Count) End Sub ' Test that list with 1 item works correctly. Public Sub TestSingletonList() Dim l = New SyntaxTokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)) Assert.NotNull(l) Assert.Equal(1, l.Count) Assert.Equal("ByVal", l(0).ToString()) Assert.Equal(0, l(0).SpanStart) Assert.Equal(5, l(0).Span.End) VerifyListSpans(l, New TextSpan(0, 6)) Dim attrBlock = SyntaxFactory.AttributeList(SyntaxFactory.Token(SyntaxKind.LessThanToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(SyntaxKind.GreaterThanToken, trailing:=spaceTrivia)) Dim param = SyntaxFactory.Parameter(SyntaxFactory.SingletonList(attrBlock), l, SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) Assert.NotNull(param.Modifiers) Assert.Equal(1, param.Modifiers.Count) Assert.Equal("ByVal", l(0).ToString()) Assert.Equal(4, param.Modifiers(0).SpanStart) Assert.Equal(9, param.Modifiers(0).Span.End) VerifyAllSpans(param) param = SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) Assert.NotNull(param.Modifiers) Assert.Equal(1, param.Modifiers.Count) Assert.Equal("ByVal", l(0).ToString()) Assert.Equal(0, param.Modifiers(0).SpanStart) Assert.Equal(5, param.Modifiers(0).Span.End) VerifyAllSpans(param) End Sub ' Test list with 3 items. Public Sub TestList() Dim bldr = New SyntaxTokenListBuilder(8) bldr.Add(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)) bldr.Add(SyntaxFactory.Token(SyntaxKind.OptionalKeyword, trailing:=spaceTrivia)) bldr.Add(SyntaxFactory.Token(SyntaxKind.ByRefKeyword, trailing:=spaceTrivia)) Dim l = bldr.ToList Assert.NotNull(l) Assert.Equal(3, l.Count) Assert.Equal("ByVal", l(0).ToString()) Assert.Equal("Optional", l(1).ToString()) Assert.Equal("ByRef", l(2).ToString()) Assert.Equal(0, l(0).SpanStart) Assert.Equal(5, l(0).Span.End) Assert.Equal(6, l(1).SpanStart) Assert.Equal(14, l(1).Span.End) Assert.Equal(15, l(2).SpanStart) Assert.Equal(20, l(2).Span.End) VerifyListSpans(l, New TextSpan(0, 21)) Dim attrBlock = SyntaxFactory.AttributeList(SyntaxFactory.Token(SyntaxKind.LessThanToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(SyntaxKind.GreaterThanToken, trailing:=spaceTrivia)) Dim param = SyntaxFactory.Parameter(SyntaxFactory.SingletonList(attrBlock), l, SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) Assert.NotNull(param.Modifiers) Assert.Equal(3, param.Modifiers.Count) Assert.Equal("ByVal", param.Modifiers(0).ToString()) Assert.Equal("Optional", param.Modifiers(1).ToString()) Assert.Equal("ByRef", param.Modifiers(2).ToString()) Assert.Equal(4, param.Modifiers(0).SpanStart) Assert.Equal(9, param.Modifiers(0).Span.End) Assert.Equal(10, param.Modifiers(1).SpanStart) Assert.Equal(18, param.Modifiers(1).Span.End) Assert.Equal(19, param.Modifiers(2).SpanStart) Assert.Equal(24, param.Modifiers(2).Span.End) VerifyAllSpans(param) param = SyntaxFactory.Parameter(SyntaxFactory.SingletonList(attrBlock), SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.OptionalKeyword, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.ByRefKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) Assert.NotNull(param.Modifiers) Assert.Equal(3, param.Modifiers.Count) Assert.Equal("ByVal", param.Modifiers(0).ToString()) Assert.Equal("Optional", param.Modifiers(1).ToString()) Assert.Equal("ByRef", param.Modifiers(2).ToString()) Assert.Equal(4, param.Modifiers(0).SpanStart) Assert.Equal(9, param.Modifiers(0).Span.End) Assert.Equal(10, param.Modifiers(1).SpanStart) Assert.Equal(18, param.Modifiers(1).Span.End) Assert.Equal(19, param.Modifiers(2).SpanStart) Assert.Equal(24, param.Modifiers(2).Span.End) VerifyAllSpans(param) param = SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.OptionalKeyword, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.ByRefKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "foo", spaceTrivia), Nothing, Nothing, Nothing), Nothing, Nothing) VerifyAllSpans(param) End Sub ' Helper to create a type name from a simple string. Private Function CreateSimpleTypeName(id As String) As TypeSyntax Return SyntaxFactory.IdentifierName(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, id, SyntaxFactory.WhitespaceTrivia(" "))) End Function 'helper to check an empty separated list Private Sub CheckEmptySeparatedList(seplist As SeparatedSyntaxList(Of TypeSyntax)) Assert.Equal(0, seplist.Count) Assert.Equal(0, seplist.SeparatorCount) End Sub ' Check that empty separated list works. Public Sub TestEmptySeparatedList() CheckEmptySeparatedList(New SeparatedSyntaxList(Of TypeSyntax)(DirectCast(Nothing, VisualBasicSyntaxNode), 0)) Dim statement = SyntaxFactory.InheritsStatement(SyntaxFactory.Token(SyntaxKind.InheritsKeyword, trailing:=spaceTrivia), (New SeparatedSyntaxListBuilder(Of TypeSyntax)).ToList) CheckEmptySeparatedList(statement.Types) Dim arglist = SyntaxFactory.ArgumentList(SyntaxFactory.Token(SyntaxKind.OpenParenToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(SyntaxKind.CloseParenToken, trailing:=spaceTrivia)) Assert.NotNull(arglist.Arguments) Assert.Equal(0, arglist.Arguments.Count) Assert.Equal(0, arglist.Arguments.SeparatorCount) Assert.Equal("( )", arglist.ToString) Assert.Equal("( ) ", arglist.ToFullString) End Sub 'helper to check an singleton separated list of one type name "foo" Private Sub CheckSingletonSeparatedList(seplist As SeparatedSyntaxList(Of TypeSyntax), start As Integer) Assert.NotNull(seplist) Assert.Equal(1, seplist.Count) Assert.Equal("foo", seplist(0).ToString) Assert.Equal("foo ", seplist(0).ToFullString) Assert.Equal(start, seplist(0).SpanStart) Assert.Equal(start, seplist(0).FullSpan.Start) Assert.Equal(start + 3, seplist(0).Span.End) Assert.Equal(start + 4, seplist(0).FullSpan.End) Assert.Equal(0, seplist.SeparatorCount) End Sub ' Check that singleton separated list works Public Sub TestSingletonSeparatedList() CheckSingletonSeparatedList(New SeparatedSyntaxList(Of TypeSyntax)(New SyntaxNodeOrTokenList(CreateSimpleTypeName("foo"), 0)), 0) Dim bldr = SeparatedSyntaxListBuilder(Of TypeSyntax).Create() bldr.Add(CreateSimpleTypeName("foo")) Dim statement = SyntaxFactory.InheritsStatement(SyntaxFactory.Token(SyntaxKind.InheritsKeyword, trailing:=spaceTrivia), bldr.ToList) CheckSingletonSeparatedList(statement.Types, 9) Assert.Equal("Inherits foo", statement.ToString) Assert.Equal("Inherits foo ", statement.ToFullString) End Sub ' CHeck that separated list with separators in it works. Public Sub TestSeparatedList() Dim bldr = SeparatedSyntaxListBuilder(Of TypeSyntax).Create() bldr.Add(CreateSimpleTypeName("aaa")) bldr.AddSeparator(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia)) bldr.Add(CreateSimpleTypeName("bbb")) bldr.AddSeparator(SyntaxFactory.Token(SyntaxKind.SemicolonToken, trailing:=spaceTrivia)) bldr.Add(CreateSimpleTypeName("cc")) Dim sepList = bldr.ToList Assert.Equal(3, sepList.Count) Assert.Equal(2, sepList.SeparatorCount) Assert.Null(sepList(1).Parent) Assert.Null(sepList.GetWithSeparators(3).Parent) Assert.Equal("aaa", sepList(0).ToString) Assert.Equal("bbb", sepList(1).ToString) Assert.Equal("cc", sepList(2).ToString) Assert.Equal(",", sepList.GetWithSeparators(1).ToString) Assert.Equal(";", sepList.GetWithSeparators(3).ToString) Assert.Equal(0, sepList(0).SpanStart) Assert.Equal(4, sepList.GetWithSeparators(1).SpanStart) Assert.Equal(6, sepList(1).SpanStart) Assert.Equal(10, sepList.GetWithSeparators(3).SpanStart) Assert.Equal(12, sepList(2).SpanStart) Dim statement = SyntaxFactory.InheritsStatement(SyntaxFactory.Token(SyntaxKind.InheritsKeyword, trailing:=spaceTrivia), sepList) Assert.Equal("Inherits aaa , bbb ; cc", statement.ToString) Assert.Equal("Inherits aaa , bbb ; cc ", statement.ToFullString) VerifyAllSpans(statement) sepList = statement.Types Assert.Equal(statement, sepList(1).Parent) Assert.Equal(statement, sepList.GetWithSeparators(3).Parent) Assert.Equal(3, sepList.Count) Assert.Equal(2, sepList.SeparatorCount) Assert.Equal("aaa", sepList(0).ToString) Assert.Equal("bbb", sepList(1).ToString) Assert.Equal("cc", sepList(2).ToString) Assert.Equal(",", sepList.GetWithSeparators(1).ToString) Assert.Equal(";", sepList.GetWithSeparators(3).ToString) Assert.Equal(9 + 0, sepList(0).SpanStart) Assert.Equal(9 + 4, sepList.GetWithSeparators(1).SpanStart) Assert.Equal(9 + 6, sepList(1).SpanStart) Assert.Equal(9 + 10, sepList.GetWithSeparators(3).SpanStart) Assert.Equal(9 + 12, sepList(2).SpanStart) End Sub ' Check that trivia seems to work. ' Note that whitespace constructor allows any text, so we leverage that in this test for simplicity. Public Sub TestTrivia() Dim white_a = SyntaxFactory.WhitespaceTrivia("AAA") Dim white_b = SyntaxFactory.WhitespaceTrivia("B") Dim white_c = SyntaxFactory.WhitespaceTrivia("CCCC") Dim white_d = SyntaxFactory.WhitespaceTrivia("DD") Dim tok = SyntaxFactory.Token(SyntaxKind.PlusToken) Dim precTrivia = tok.LeadingTrivia() Dim follTrivia = tok.TrailingTrivia() Assert.NotNull(precTrivia) Assert.Equal(1, precTrivia.Count) Assert.NotNull(follTrivia) Assert.Equal(1, follTrivia.Count) Assert.Equal(0, tok.FullSpan.Start) Assert.Equal(0, tok.SpanStart) Assert.Equal(1, tok.FullSpan.End) Assert.Equal(1, tok.Span.End) VerifyAllSpans(tok) Dim bldr = SyntaxTriviaListBuilder.Create() bldr.Add(white_a) bldr.Add(white_b) tok = SyntaxFactory.Token(Nothing, SyntaxKind.PlusToken, trailing:=bldr.ToList) precTrivia = tok.LeadingTrivia() follTrivia = tok.TrailingTrivia() Assert.NotNull(precTrivia) Assert.Equal(0, precTrivia.Count) Assert.NotNull(follTrivia) Assert.Equal(2, follTrivia.Count) Assert.Equal(0, tok.FullSpan.Start) Assert.Equal(0, tok.SpanStart) Assert.Equal(5, tok.FullSpan.End) Assert.Equal(1, tok.Span.End) Assert.Equal("+AAAB", tok.ToFullString()) Assert.Equal("AAA", follTrivia(0).ToString()) Assert.Equal("AAA", follTrivia(0).ToFullString) Assert.Equal(1, follTrivia(0).SpanStart) Assert.Equal(1, follTrivia(0).FullSpan.Start) Assert.Equal(4, follTrivia(0).Span.End) Assert.Equal(4, follTrivia(0).FullSpan.End) Assert.Equal("B", follTrivia(1).ToString()) Assert.Equal("B", follTrivia(1).ToFullString) Assert.Equal(4, follTrivia(1).SpanStart) Assert.Equal(4, follTrivia(1).FullSpan.Start) Assert.Equal(5, follTrivia(1).Span.End) Assert.Equal(5, follTrivia(1).FullSpan.End) VerifyAllSpans(tok) bldr.Clear() bldr.Add(white_c) bldr.Add(white_d) bldr.Add(white_a) Dim leading = bldr.ToList tok = SyntaxFactory.Token(bldr.ToList, SyntaxKind.PlusToken, trailing:=SyntaxTriviaList.Create(white_b)) precTrivia = tok.LeadingTrivia() follTrivia = tok.TrailingTrivia() Assert.Equal(0, tok.FullSpan.Start) Assert.Equal(11, tok.FullSpan.End) Assert.Equal(9, tok.SpanStart) Assert.Equal(10, tok.Span.End) Assert.Equal("CCCCDDAAA+B", tok.ToFullString()) VerifyAllSpans(tok) Assert.NotNull(precTrivia) Assert.Equal(3, precTrivia.Count) Assert.Equal("CCCC", precTrivia(0).ToString()) Assert.Equal("CCCC", precTrivia(0).ToFullString) Assert.Equal(0, precTrivia(0).SpanStart) Assert.Equal(0, precTrivia(0).FullSpan.Start) Assert.Equal(4, precTrivia(0).Span.End) Assert.Equal(4, precTrivia(0).FullSpan.End) Assert.Equal("DD", precTrivia(1).ToString()) Assert.Equal("DD", precTrivia(1).ToFullString) Assert.Equal(4, precTrivia(1).SpanStart) Assert.Equal(4, precTrivia(1).FullSpan.Start) Assert.Equal(6, precTrivia(1).Span.End) Assert.Equal(6, precTrivia(1).FullSpan.End) Assert.Equal("AAA", precTrivia(2).ToString()) Assert.Equal("AAA", precTrivia(2).ToFullString) Assert.Equal(6, precTrivia(2).SpanStart) Assert.Equal(6, precTrivia(2).FullSpan.Start) Assert.Equal(9, precTrivia(2).Span.End) Assert.Equal(9, precTrivia(2).FullSpan.End) Assert.NotNull(follTrivia) Assert.Equal(1, follTrivia.Count) Assert.Equal("B", follTrivia(0).ToString()) Assert.Equal("B", follTrivia(0).ToFullString) Assert.Equal(10, follTrivia(0).SpanStart) Assert.Equal(10, follTrivia(0).FullSpan.Start) Assert.Equal(11, follTrivia(0).Span.End) Assert.Equal(11, follTrivia(0).FullSpan.End) End Sub Public Sub TestKeywordFactoryMethods() ' Check simple factory for keyword. Dim keyword = SyntaxFactory.Token(SyntaxKind.AliasKeyword, trailing:=spaceTrivia) Assert.Equal("Alias", keyword.ToString()) Assert.Equal(5, keyword.Span.Length) Assert.Equal(6, keyword.FullSpan.Length) Assert.Equal(1, keyword.LeadingTrivia().Count) Assert.Equal(1, keyword.TrailingTrivia().Count) Assert.Equal(" ", keyword.TrailingTrivia()(0).ToString) ' Check full factory for keyword Dim bldr = SyntaxTriviaListBuilder.Create() bldr.Add(SyntaxFactory.WhitespaceTrivia(" ")) bldr.Add(SyntaxFactory.CommentTrivia("'foo")) keyword = SyntaxFactory.Token(bldr.ToList, SyntaxKind.AliasKeyword, Nothing, "ALIAs") Assert.Equal("ALIAs", keyword.ToString()) Assert.Equal(5, keyword.Span.Length) Assert.Equal(12, keyword.FullSpan.Length) Assert.Equal(2, keyword.LeadingTrivia().Count) Assert.Equal(" ", keyword.LeadingTrivia()(0).ToString) Assert.Equal(0, keyword.TrailingTrivia().Count) ' Check factory methods giving the node kind keyword = SyntaxFactory.Token(Nothing, SyntaxKind.AndAlsoKeyword, spaceTrivia, "ANDALSO") Assert.Equal("ANDALSO", keyword.ToString()) Assert.Equal(7, keyword.Span.Length) Assert.Equal(8, keyword.FullSpan.Length) Assert.Equal(0, keyword.LeadingTrivia().Count) Assert.Equal(1, keyword.TrailingTrivia().Count) Assert.Equal(" ", keyword.TrailingTrivia()(0).ToString) bldr.Clear() bldr.Add(SyntaxFactory.WhitespaceTrivia(" ")) bldr.Add(SyntaxFactory.CommentTrivia("'foo")) keyword = SyntaxFactory.Token(bldr.ToList, SyntaxKind.AndAlsoKeyword, SyntaxTriviaList.Create(SyntaxFactory.WhitespaceTrivia(" ")), "andalso") Assert.Equal("andalso", keyword.ToString()) Assert.Equal(7, keyword.Span.Length) Assert.Equal(16, keyword.FullSpan.Length) Assert.Equal(2, keyword.LeadingTrivia().Count) Assert.Equal(1, keyword.TrailingTrivia().Count) Assert.Equal(" ", keyword.TrailingTrivia()(0).ToString) Assert.Equal("'foo", keyword.LeadingTrivia()(1).ToString) End Sub Public Sub TestNonTerminalFactoryMethods() Dim endTry As EndBlockStatementSyntax endTry = SyntaxFactory.EndTryStatement(SyntaxFactory.Token(SyntaxKind.EndKeyword, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.TryKeyword, trailing:=spaceTrivia)) Assert.Equal(7, endTry.Span.Length) Assert.Equal(8, endTry.FullSpan.Length) Assert.Equal(SyntaxKind.EndKeyword, endTry.EndKeyword.VisualBasicKind) Assert.Equal("End", endTry.EndKeyword.ToString()) Assert.Equal(SyntaxKind.TryKeyword, endTry.BlockKeyword.VisualBasicKind) Assert.Equal("Try", endTry.BlockKeyword.ToString()) Assert.Equal(1, endTry.GetTrailingTrivia().Count) Assert.Equal(" ", endTry.GetTrailingTrivia()(0).ToString) End Sub ' Check that IsToken, IsTrivia, IsTerminal properties returns correct thing. Public Sub TestTokenTriviaClassification() Dim endIfStmt = SyntaxFactory.EndIfStatement(SyntaxFactory.Token(SyntaxKind.EndKeyword, trailing:=spaceTrivia), SyntaxFactory.Token(SyntaxKind.IfKeyword, trailing:=spaceTrivia)) Dim plusToken = SyntaxFactory.Token(SyntaxKind.PlusToken, trailing:=spaceTrivia) Dim comment = SyntaxFactory.CommentTrivia("'hello") Assert.True(plusToken.Node.IsToken) Assert.False(comment.UnderlyingNode.IsToken) Assert.False(endIfStmt.IsStructuredTrivia) Assert.Equal(SyntaxKind.CommentTrivia, comment.VisualBasicKind) End Sub ' Check that ToString, ToFullString, and ValueText are correct on a token. Public Sub TestTokenText() ' keyword without trivia Dim keyword = SyntaxFactory.Token(SyntaxKind.PartialKeyword, "ParTIAL") Assert.Equal("ParTIAL", keyword.ToString()) Assert.Equal("ParTIAL", keyword.ToFullString()) Assert.Equal("ParTIAL", keyword.ValueText()) ' identifier with trivia Dim identifier = SyntaxFactory.Identifier(SyntaxFactory.WhitespaceTrivia(" "), "[foo]", True, "foo", TypeCharacter.None, SyntaxFactory.CommentTrivia("'hi")) Assert.Equal("[foo]", identifier.ToString()) Assert.Equal(" [foo]'hi", identifier.ToFullString()) Assert.Equal("foo", identifier.ValueText) End Sub ' Create a sample method statement. Private Function CreateMethodStatement() As MethodStatementSyntax Dim bldr = SyntaxNodeOrTokenListBuilder.Create() bldr.Add(SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "Param1", False, "Param1", TypeCharacter.None, spaceTrivia), Nothing, Nothing, Nothing), SyntaxFactory.SimpleAsClause(SyntaxFactory.Token(SyntaxKind.AsKeyword, trailing:=spaceTrivia), Nothing, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntegerKeyword, trailing:=spaceTrivia))), Nothing)) bldr.Add(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia)) bldr.Add(SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "Param2", False, "Param2", TypeCharacter.None, spaceTrivia), Nothing, Nothing, Nothing), SyntaxFactory.SimpleAsClause(SyntaxFactory.Token(SyntaxKind.AsKeyword, trailing:=spaceTrivia), Nothing, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword, trailing:=spaceTrivia))), Nothing)) bldr.Add(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia)) bldr.Add(SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByRefKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "Param3", False, "Param3", TypeCharacter.None, spaceTrivia), Nothing, Nothing, Nothing), SyntaxFactory.SimpleAsClause(SyntaxFactory.Token(SyntaxKind.AsKeyword, trailing:=spaceTrivia), Nothing, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DoubleKeyword, trailing:=spaceTrivia))), Nothing)) Return SyntaxFactory.SubStatement(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxFactory.WhitespaceTrivia(" "), SyntaxKind.PublicKeyword, SyntaxFactory.WhitespaceTrivia(" "), "public"), SyntaxFactory.Token(SyntaxKind.OverloadsKeyword, trailing:=spaceTrivia)), SyntaxFactory.Token(SyntaxFactory.WhitespaceTrivia(" "), SyntaxKind.SubKeyword, SyntaxFactory.WhitespaceTrivia(" "), "SUB"), SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "MySub", False, "MySub", TypeCharacter.None, spaceTrivia), Nothing, SyntaxFactory.ParameterList(SyntaxFactory.Token(SyntaxKind.OpenParenToken, trailing:=spaceTrivia), New SeparatedSyntaxList(Of ParameterSyntax)(bldr.ToList()), SyntaxFactory.Token(SyntaxKind.CloseParenToken, trailing:=spaceTrivia)), Nothing, Nothing, Nothing) End Function Public Sub TestSpansOnMethodStatement() VerifyAllSpans(CreateMethodStatement()) End Sub ' Check that the ToString and ToFullString are correct on a non-terminal that includes ' a list and a separated list. Public Sub TestNonTerminalText() Dim methodStatement = CreateMethodStatement() Assert.Equal("public Overloads SUB MySub ( ByVal Param1 As Integer , ByVal Param2 As String , ByRef Param3 As Double )", methodStatement.ToString()) Assert.Equal(" public Overloads SUB MySub ( ByVal Param1 As Integer , ByVal Param2 As String , ByRef Param3 As Double ) ", methodStatement.ToFullString) End Sub ' Check that IsMissing seems to do the right thing. Public Sub IsMissing() Dim ident = SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "hello", spaceTrivia) Assert.False(ident.IsMissing) ident = SyntaxFactory.MissingIdentifier() Assert.True(ident.IsMissing) Dim punc = SyntaxFactory.Token(SyntaxKind.PlusToken, trailing:=spaceTrivia) Assert.False(punc.IsMissing) punc = SyntaxFactory.MissingPunctuation(SyntaxKind.PlusToken) Assert.True(punc.IsMissing) Dim kw = SyntaxFactory.Token(SyntaxKind.EndKeyword, trailing:=spaceTrivia) Assert.False(kw.IsMissing) kw = SyntaxFactory.MissingKeyword(SyntaxKind.EndKeyword) Assert.True(kw.IsMissing) Dim eof = SyntaxFactory.Token(SyntaxKind.EndOfFileToken) Assert.False(eof.IsMissing) ' end of text token is never missing, even though it is zero length. Assert.Equal(0, eof.Span.Length) Dim endIfStmt = SyntaxFactory.EndIfStatement(SyntaxFactory.MissingKeyword(SyntaxKind.EndKeyword), SyntaxFactory.MissingKeyword(SyntaxKind.IfKeyword)) Assert.True(endIfStmt.IsMissing) Assert.Equal(0, endIfStmt.Span.Length) VerifyAllSpans(endIfStmt) End Sub Private Function CompareDiagnostics(err1 As Diagnostic, err2 As Diagnostic) As Integer Dim span1 = err1.Location.SourceSpan Dim span2 = err2.Location.SourceSpan Dim i = span1.Start.CompareTo(span2.Start) If i = 0 Then Return err1.Code.CompareTo(err2.Code) End If Return i End Function ' Check that a given list of errors on a node matches the given set. Private Sub CheckErrorList(node As VisualBasicSyntaxNode, expectedErrorCodes As Integer(), expectedSpans As TextSpan()) Dim errorList As New List(Of Diagnostic) errorList.AddRange(node.GetSyntaxErrorsNoTree()) errorList.Sort(AddressOf CompareDiagnostics) For i = 0 To errorList.Count - 1 Assert.True(expectedSpans(i) = errorList(i).Location.SourceSpan, "Error " & i & " have different spans") Assert.True(expectedErrorCodes(i) = errorList(i).Code, "Error " & i & " have different codes") Next Assert.Equal(expectedErrorCodes.Length, errorList.Count) ' Has errors property should match expected errors. If expectedErrorCodes.Length > 0 Then Assert.True(node.ContainsDiagnostics) Else Assert.False(node.ContainsDiagnostics) End If End Sub ' Check that a given list of errors on a node matches the given set. Private Sub CheckErrorList(node As SyntaxToken, expectedErrorCodes As Integer(), expectedSpans As TextSpan()) Dim errorList As New List(Of Diagnostic) errorList.AddRange(node.GetSyntaxErrorsNoTree()) errorList.Sort(AddressOf CompareDiagnostics) For i = 0 To errorList.Count - 1 Assert.True(expectedSpans(i) = errorList(i).Location.SourceSpan, "Error " & i & " have different spans") Assert.True(expectedErrorCodes(i) = errorList(i).Code, "Error " & i & " have different codes") Next Assert.Equal(expectedErrorCodes.Length, errorList.Count) ' Has errors property should match expected errors. If expectedErrorCodes.Length > 0 Then Assert.True(node.Node.ContainsDiagnostics) Else Assert.False(node.Node.ContainsDiagnostics) End If End Sub ' Test simple errors on a token and its associated trivia. Public Sub SimpleTokenErrors() Dim kwModule = SyntaxFactory.Token(SyntaxKind.ModuleKeyword, trailing:=spaceTrivia) CheckErrorList(kwModule, {}, {}) Assert.Equal(6, kwModule.Span.Length) Assert.Equal(7, kwModule.FullSpan.Length) ' Add an error. kwModule = New SyntaxToken(Nothing, CType(kwModule.Node.AddError(CreateDiagnosticInfo(17)), InternalSyntax.KeywordSyntax), 0, 0) CheckErrorList(kwModule, {17}, {New TextSpan(0, 6)}) Assert.Equal(6, kwModule.Span.Length) Assert.Equal(7, kwModule.FullSpan.Length) ' Add another error. kwModule = New SyntaxToken(Nothing, CType(kwModule.Node.AddError(CreateDiagnosticInfo(42)), InternalSyntax.KeywordSyntax), 0, 0) CheckErrorList(kwModule, {17, 42}, {New TextSpan(0, 6), New TextSpan(0, 6)}) ' Add another token and put together. Make sure the spans work. Dim trailing = New SyntaxTrivia(Nothing, CType(SyntaxFactory.WhitespaceTrivia(" ").UnderlyingNode.AddError(CreateDiagnosticInfo(101)), InternalSyntax.SyntaxTrivia), 0, 0) Dim kwEnd = SyntaxFactory.Token(Nothing, SyntaxKind.EndKeyword, trailing, "End") Dim endModule = SyntaxFactory.EndModuleStatement(kwEnd, kwModule) CheckErrorList(endModule, {101, 17, 42}, {New TextSpan(3, 3), New TextSpan(6, 6), New TextSpan(6, 6)}) ' add error to the whole statement endModule = CType(endModule.AddError(CreateDiagnosticInfo(1)), EndBlockStatementSyntax) Assert.Equal("End Module ", endModule.ToFullString) CheckErrorList(endModule, {1, 101, 17, 42}, {New TextSpan(0, 12), New TextSpan(3, 3), New TextSpan(6, 6), New TextSpan(6, 6)}) End Sub ' Test a complex case with a few errors in it. Public Sub ComplexErrors() Dim bldr = SyntaxNodeOrTokenListBuilder.Create() bldr.Add(SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "Param1", False, "Param1", TypeCharacter.None, spaceTrivia), Nothing, Nothing, Nothing), SyntaxFactory.SimpleAsClause(SyntaxFactory.Token(SyntaxKind.AsKeyword, trailing:=spaceTrivia), Nothing, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntegerKeyword, trailing:=spaceTrivia))), Nothing)) bldr.Add(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia)) bldr.Add(SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ByValKeyword, trailing:=spaceTrivia)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "Param2", False, "Param2", TypeCharacter.None, spaceTrivia), Nothing, Nothing, Nothing), SyntaxFactory.SimpleAsClause(SyntaxFactory.Token(SyntaxKind.AsKeyword, trailing:=spaceTrivia), Nothing, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword, trailing:=spaceTrivia))), Nothing).AddError(CreateDiagnosticInfo(101))) bldr.Add(DirectCast(SyntaxFactory.Token(SyntaxKind.CommaToken, trailing:=spaceTrivia).Node.AddError(CreateDiagnosticInfo(33)), InternalSyntax.VisualBasicSyntaxNode)) bldr.Add(SyntaxFactory.Parameter(Nothing, SyntaxFactory.TokenList(New SyntaxToken(Nothing, CType(SyntaxFactory.Token(SyntaxKind.ByRefKeyword, trailing:=spaceTrivia).Node.AddError(CreateDiagnosticInfo(44)), InternalSyntax.KeywordSyntax), 0, 0)), SyntaxFactory.ModifiedIdentifier(SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "Param3", False, "Param3", TypeCharacter.None, spaceTrivia), Nothing, Nothing, Nothing), SyntaxFactory.SimpleAsClause(SyntaxFactory.Token(SyntaxKind.AsKeyword, trailing:=spaceTrivia), Nothing, SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DoubleKeyword, trailing:=spaceTrivia))), Nothing)) Dim methodDecl As MethodStatementSyntax = SyntaxFactory.SubStatement(Nothing, SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxFactory.WhitespaceTrivia(" "), SyntaxKind.PublicKeyword, SyntaxFactory.WhitespaceTrivia(" "), "public"), SyntaxFactory.Token(SyntaxKind.OverloadsKeyword, trailing:=spaceTrivia)), SyntaxFactory.Token(New SyntaxTrivia(Nothing, CType(SyntaxFactory.WhitespaceTrivia(" ").UnderlyingNode.AddError(CreateDiagnosticInfo(22)).AddError(CreateDiagnosticInfo(23)), InternalSyntax.SyntaxTrivia), 0, 0), SyntaxKind.SubKeyword, SyntaxFactory.WhitespaceTrivia(" "), "SUB"), SyntaxFactory.Identifier(SyntaxFactory.ElasticMarker, "MySub", False, "MySyb", TypeCharacter.None, spaceTrivia), Nothing, SyntaxFactory.ParameterList(SyntaxFactory.Token(SyntaxKind.OpenParenToken, trailing:=spaceTrivia), New SeparatedSyntaxList(Of ParameterSyntax)(bldr.ToList), SyntaxFactory.Token(SyntaxKind.CloseParenToken, trailing:=spaceTrivia)), Nothing, Nothing, Nothing) Assert.Equal(" public Overloads SUB MySub ( ByVal Param1 As Integer , ByVal Param2 As String , ByRef Param3 As Double ) ", methodDecl.ToFullString) CheckErrorList(methodDecl, {22, 23, 101, 33, 44}, {New TextSpan(26, 5), New TextSpan(26, 5), New TextSpan(71, 22), New TextSpan(94, 1), New TextSpan(96, 5)}) End Sub Shared _messageProvider As New MockMessageProvider() Private Function CreateDiagnosticInfo(code As Integer) As DiagnosticInfo Return New DiagnosticInfo(_messageProvider, code) End Function ' A mock message provider Private Class MockMessageProvider Inherits TestMessageProvider Public Overrides ReadOnly Property CodePrefix As String Get Return "MOCK" End Get End Property Public Overrides Function GetSeverity(code As Integer) As DiagnosticSeverity Return DiagnosticSeverity.Error End Function Public Overrides Function LoadMessage(code As Integer, language As CultureInfo) As String Return String.Format("Error {0}", code) End Function Public Overrides Function GetWarningLevel(code As Integer) As Integer Return 0 End Function End Class ' A test rewriting visitor Private Class TestVisitor Inherits VisualBasicSyntaxRewriter ' Optional to control which rewritings we do Public IncrementInts As Boolean = False Public CapitalizeKeywords As Boolean = False Public CapitalizeIdentifiers As Boolean = False Public SwapParameters As Boolean = False Public Overrides Function VisitToken(token As SyntaxToken) As SyntaxToken Select Case token.VisualBasicKind Case SyntaxKind.IntegerLiteralToken If IncrementInts Then Dim node = DirectCast(token.Node, InternalSyntax.IntegerLiteralTokenSyntax) Dim value = CULng(node.ObjectValue) value = CULng(value + 1) Return SyntaxFactory.IntegerLiteralToken(token.LeadingTrivia, value.ToString(), LiteralBase.Decimal, node.TypeSuffix, value, token.TrailingTrivia()) End If Case SyntaxKind.IdentifierToken If CapitalizeIdentifiers Then Dim node = DirectCast(token.Node, InternalSyntax.IdentifierTokenSyntax) Return SyntaxFactory.Identifier(token.LeadingTrivia(), node.Text.ToUpperInvariant(), node.IsBracketed, node.IdentifierText.ToUpperInvariant(), node.TypeCharacter, token.TrailingTrivia()) End If Case Else If SyntaxFacts.IsKeywordKind(token.VisualBasicKind) Then If CapitalizeKeywords Then Dim node = DirectCast(token.Node, InternalSyntax.KeywordSyntax) Return SyntaxFactory.Token(token.LeadingTrivia(), node.Kind, token.TrailingTrivia(), node.Text.ToUpperInvariant()) End If End If End Select Return MyBase.VisitToken(token) End Function Public Overrides Function VisitMethodStatement(node As MethodStatementSyntax) As SyntaxNode If SwapParameters Then node = CType(MyBase.VisitMethodStatement(node), MethodStatementSyntax) Return SyntaxFactory.MethodStatement(node.Kind, node.AttributeLists, node.Modifiers, node.Keyword, node.Identifier, node.TypeParameterList, SyntaxFactory.ParameterList( node.ParameterList.OpenParenToken, SwitchParameters(node.ParameterList.Parameters), node.ParameterList.CloseParenToken), node.AsClause, node.HandlesClause, node.ImplementsClause) Else Return MyBase.VisitMethodStatement(node) End If End Function Private Function SwitchParameters(params As SeparatedSyntaxList(Of ParameterSyntax)) As SeparatedSyntaxList(Of ParameterSyntax) If params.Count >= 2 Then Dim bldr = SeparatedSyntaxListBuilder(Of ParameterSyntax).Create() bldr.Add(params(1)) bldr.AddSeparator(params.GetSeparator(0)) bldr.Add(params(0)) bldr.AddSeparator(params.GetSeparator(1)) For i As Integer = 2 To params.Count - 1 bldr.Add(params(i)) If i < params.SeparatorCount Then bldr.AddSeparator(params.GetSeparator(i)) End If Next Return bldr.ToList Else Return params End If End Function End Class Public Sub TestRewritingVisitor() Dim rewriter As VisualBasicSyntaxRewriter Dim simpleTree = CreateSimpleTree() Assert.Equal(simpleTree.ToString, "1- X( 3, 4+ 8, 9)") ' null rewriting should return exact same node. rewriter = New TestVisitor() Dim newTree = rewriter.Visit(simpleTree) Assert.Same(simpleTree, newTree) ' incremental all integers rewriter = New TestVisitor() With {.IncrementInts = True} newTree = rewriter.Visit(simpleTree) Assert.Equal(newTree.ToString, "2- X( 4, 5+ 9, 10)") Dim methodStmt = CreateMethodStatement() Assert.Equal("public Overloads SUB MySub ( ByVal Param1 As Integer , ByVal Param2 As String , ByRef Param3 As Double )", methodStmt.ToString) ' null rewriting should return exact same node. rewriter = New TestVisitor() Dim newMethod = rewriter.Visit(methodStmt) Assert.Same(methodStmt, newMethod) ' capitalize all keywords. rewriter = New TestVisitor() With {.CapitalizeKeywords = True} newMethod = rewriter.Visit(methodStmt) Assert.Equal("PUBLIC OVERLOADS SUB MySub ( BYVAL Param1 AS INTEGER , BYVAL Param2 AS STRING , BYREF Param3 AS DOUBLE )", newMethod.ToString) ' capitalize all identifiers. rewriter = New TestVisitor() With {.CapitalizeIdentifiers = True} newMethod = rewriter.Visit(methodStmt) Assert.Equal("public Overloads SUB MYSUB ( ByVal PARAM1 As Integer , ByVal PARAM2 As String , ByRef PARAM3 As Double )", newMethod.ToString) ' reorder parameters. rewriter = New TestVisitor() With {.SwapParameters = True} newMethod = rewriter.Visit(methodStmt) Assert.Equal("public Overloads SUB MySub ( ByVal Param2 As String , ByVal Param1 As Integer , ByRef Param3 As Double )", newMethod.ToString) 'all 3 rewriter = New TestVisitor() With {.SwapParameters = True, .CapitalizeIdentifiers = True, .CapitalizeKeywords = True} newMethod = rewriter.Visit(methodStmt) Assert.Equal("PUBLIC OVERLOADS SUB MYSUB ( BYVAL PARAM2 AS STRING , BYVAL PARAM1 AS INTEGER , BYREF PARAM3 AS DOUBLE )", newMethod.ToString) End Sub Public Sub TestReplacer() Dim simpleTree = CreateSimpleTree() Assert.Equal("1- X( 3, 4+ 8, 9)", simpleTree.ToString) Dim firstOper = simpleTree.Left simpleTree = simpleTree.ReplaceNode(firstOper, SyntaxFactory.StringLiteralExpression(SyntaxFactory.StringLiteralToken("""Hi""", "Hi"))) Assert.Equal("""Hi""- X( 3, 4+ 8, 9)", simpleTree.ToString) ' if first arg is not in tree then returns same instance simpleTree = simpleTree.ReplaceNode(firstOper, SyntaxFactory.StringLiteralExpression(SyntaxFactory.StringLiteralToken("""ha""", "ha"))) Assert.Equal("""Hi""- X( 3, 4+ 8, 9)", simpleTree.ToString) Dim secondOper = simpleTree.Right simpleTree = simpleTree.ReplaceNode(secondOper, SyntaxFactory.StringLiteralExpression(SyntaxFactory.MissingStringLiteral())) Assert.Equal("""Hi""- ", simpleTree.ToFullString) Dim newSecondOper = simpleTree.Right simpleTree = simpleTree.ReplaceNode(newSecondOper, SyntaxFactory.StringLiteralExpression(SyntaxFactory.StringLiteralToken("""Bye""", "Bye"))) Assert.Equal("""Hi""- ""Bye""", simpleTree.ToFullString) Dim op = simpleTree.OperatorToken simpleTree = simpleTree.ReplaceToken(op, SyntaxFactory.MissingPunctuation(SyntaxKind.MinusToken)) Assert.Equal("""Hi""""Bye""", simpleTree.ToFullString) op = simpleTree.OperatorToken simpleTree = simpleTree.ReplaceToken(op, SyntaxFactory.Token(SyntaxKind.EqualsToken, trailing:=spaceTrivia)) Assert.Equal("""Hi""= ""Bye""", simpleTree.ToFullString) End Sub Public Sub TestReplaceNode() Dim expr = SyntaxFactory.ParseExpression("a + b") Dim bex = DirectCast(expr, BinaryExpressionSyntax) Dim expr2 = expr.ReplaceNode(bex.Right, SyntaxFactory.ParseExpression("c")) Assert.Equal("a + c", expr2.ToFullString()) End Sub Public Sub TestReplaceNodes() Dim expr = SyntaxFactory.ParseExpression("a + b + c + d") ' replace each expression with a parenthesized expression Dim replaced = expr.ReplaceNodes( expr.DescendantNodes().OfType(Of ExpressionSyntax)(), Function(node, rewritten) SyntaxFactory.ParenthesizedExpression(rewritten)) Dim replacedText = replaced.ToFullString() Assert.Equal("(((a )+ (b ))+ (c ))+ (d)", replacedText) End Sub Public Sub TestReplaceNodesInListWithMultiple() Dim invocation = DirectCast(SyntaxFactory.ParseExpression("m(a, b)"), InvocationExpressionSyntax) Dim argC = SyntaxFactory.SimpleArgument(SyntaxFactory.ParseExpression("c")) Dim argD = SyntaxFactory.SimpleArgument(SyntaxFactory.ParseExpression("d")) ' replace first with multiple Dim newNode = invocation.ReplaceNode(invocation.ArgumentList.Arguments(0), {argC, argD}) Assert.Equal("m(c,d, b)", newNode.ToFullString()) ' replace last with multiple newNode = invocation.ReplaceNode(invocation.ArgumentList.Arguments(1), {argC, argD}) Assert.Equal("m(a, c,d)", newNode.ToFullString()) ' replace first with empty list newNode = invocation.ReplaceNode(invocation.ArgumentList.Arguments(0), New SyntaxNode() {}) Assert.Equal("m(b)", newNode.ToFullString()) ' replace last with empty list newNode = invocation.ReplaceNode(invocation.ArgumentList.Arguments(1), New SyntaxNode() {}) Assert.Equal("m(a)", newNode.ToFullString()) End Sub Public Sub TestReplaceNonListNodeWithList() Dim invocation = DirectCast(SyntaxFactory.ParseExpression("m(a, b)"), InvocationExpressionSyntax) Dim expA = invocation.DescendantNodes().OfType(Of ExpressionSyntax).First(Function(n) n.ToString() = "a") Dim expC = SyntaxFactory.ParseExpression("c") Dim expD = SyntaxFactory.ParseExpression("d") ' cannot replace a node that is not in a list with mulitple nodes Assert.Throws(Of InvalidOperationException)(Function() invocation.ReplaceNode(expA, {expC, expD})) ' cannot replace a node that is not in a list with and empty list of nodes Assert.Throws(Of InvalidOperationException)(Function() invocation.ReplaceNode(expA, New ExpressionSyntax() {})) End Sub Public Sub TestInsertNodesInList() Dim invocation = DirectCast(SyntaxFactory.ParseExpression("m(a, b)"), InvocationExpressionSyntax) Dim argC = SyntaxFactory.SimpleArgument(SyntaxFactory.ParseExpression("c")) Dim argD = SyntaxFactory.SimpleArgument(SyntaxFactory.ParseExpression("d")) ' insert before first Dim newNode = invocation.InsertNodesBefore(invocation.ArgumentList.Arguments(0), {argC, argD}) Assert.Equal("m(c,d,a, b)", newNode.ToFullString()) '' insert after first newNode = invocation.InsertNodesAfter(invocation.ArgumentList.Arguments(0), {argC, argD}) Assert.Equal("m(a,c,d, b)", newNode.ToFullString()) ' insert before last newNode = invocation.InsertNodesBefore(invocation.ArgumentList.Arguments(1), {argC, argD}) Assert.Equal("m(a,c,d, b)", newNode.ToFullString()) ' insert after last newNode = invocation.InsertNodesAfter(invocation.ArgumentList.Arguments(1), {argC, argD}) Assert.Equal("m(a, b,c,d)", newNode.ToFullString()) End Sub Public Sub TestInsertNodesRelativeToNonListNode() Dim invocation = DirectCast(SyntaxFactory.ParseExpression("m(a, b)"), InvocationExpressionSyntax) Dim expA = invocation.DescendantNodes().OfType(Of ExpressionSyntax).First(Function(n) n.ToString() = "a") Dim expC = SyntaxFactory.ParseExpression("c") Dim expD = SyntaxFactory.ParseExpression("d") ' cannot replace a node that is not in a list with mulitple nodes Assert.Throws(Of InvalidOperationException)(Function() invocation.InsertNodesBefore(expA, {expC, expD})) ' cannot replace a node that is not in a list with and empty list of nodes Assert.Throws(Of InvalidOperationException)(Function() invocation.InsertNodesAfter(expA, {expC, expD})) End Sub Public Sub TestReplaceStatementInListWithMultiple() Dim ifBlock = DirectCast(SyntaxFactory.ParseExecutableStatement( If a != b Then Dim x = 10 Dim y = 20 End If.Value), MultiLineIfBlockSyntax) Dim stmt1 = SyntaxFactory.ParseExecutableStatement( Dim z = 30 .Value) Dim stmt2 = SyntaxFactory.ParseExecutableStatement( Dim q = 40 .Value) '' replace first with multiple Dim newBlock = ifBlock.ReplaceNode(ifBlock.IfPart.Statements(0), {stmt1, stmt2}) Assert.Equal( If a != b Then Dim z = 30 Dim q = 40 Dim y = 20 End If.Value, newBlock.ToFullString()) '' replace second with multiple newBlock = ifBlock.ReplaceNode(ifBlock.IfPart.Statements(1), {stmt1, stmt2}) Assert.Equal( If a != b Then Dim x = 10 Dim z = 30 Dim q = 40 End If.Value, newBlock.ToFullString()) ' replace first with empty list newBlock = ifBlock.ReplaceNode(ifBlock.IfPart.Statements(0), New SyntaxNode() {}) Assert.Equal( If a != b Then Dim y = 20 End If.Value, newBlock.ToFullString()) ' replace second with empty list newBlock = ifBlock.ReplaceNode(ifBlock.IfPart.Statements(1), New SyntaxNode() {}) Assert.Equal( If a != b Then Dim x = 10 End If.Value, newBlock.ToFullString()) End Sub Public Sub TestInsertStatementsInList() Dim ifBlock = DirectCast(SyntaxFactory.ParseExecutableStatement( If a != b Then Dim x = 10 Dim y = 20 End If.Value), MultiLineIfBlockSyntax) Dim stmt1 = SyntaxFactory.ParseExecutableStatement( Dim z = 30 .Value) Dim stmt2 = SyntaxFactory.ParseExecutableStatement( Dim q = 40 .Value) ' insert before first Dim newBlock = ifBlock.InsertNodesBefore(ifBlock.IfPart.Statements(0), {stmt1, stmt2}) Assert.Equal( If a != b Then Dim z = 30 Dim q = 40 Dim x = 10 Dim y = 20 End If.Value, newBlock.ToFullString()) ' insert after first newBlock = ifBlock.InsertNodesAfter(ifBlock.IfPart.Statements(0), {stmt1, stmt2}) Assert.Equal( If a != b Then Dim x = 10 Dim z = 30 Dim q = 40 Dim y = 20 End If.Value, newBlock.ToFullString()) ' insert before last newBlock = ifBlock.InsertNodesBefore(ifBlock.IfPart.Statements(1), {stmt1, stmt2}) Assert.Equal( If a != b Then Dim x = 10 Dim z = 30 Dim q = 40 Dim y = 20 End If.Value, newBlock.ToFullString()) ' insert after last newBlock = ifBlock.InsertNodesAfter(ifBlock.IfPart.Statements(1), {stmt1, stmt2}) Assert.Equal( If a != b Then Dim x = 10 Dim y = 20 Dim z = 30 Dim q = 40 End If.Value, newBlock.ToFullString()) End Sub Public Sub TestReplaceToken() Dim expr = SyntaxFactory.ParseExpression("a + b") Dim bToken = expr.DescendantTokens().First(Function(t) t.Text = "b") Dim expr2 = expr.ReplaceToken(bToken, SyntaxFactory.ParseToken("c")) Assert.Equal("a + c", expr2.ToString()) End Sub Public Sub TestReplaceMultipleTokens() Dim expr = SyntaxFactory.ParseExpression("a + b + c") Dim d = SyntaxFactory.ParseToken("d ") Dim tokens = expr.DescendantTokens().Where(Function(t) t.IsKind(SyntaxKind.IdentifierToken)).ToList() Dim replaced = expr.ReplaceTokens(tokens, Function(tok, tok2) d) Assert.Equal("d + d + d ", replaced.ToFullString()) End Sub Public Sub TestReplaceTokenWithMultipleTokens() Dim cu = SyntaxFactory.ParseCompilationUnit( Private Class C End Class.Value) Dim privateToken = DirectCast(cu.Members(0), ClassBlockSyntax).Begin.Modifiers(0) Dim publicToken = SyntaxFactory.ParseToken("Public ") Dim partialToken = SyntaxFactory.ParseToken("Partial ") Dim cu1 = cu.ReplaceToken(privateToken, publicToken) Assert.Equal( Public Class C End Class.Value, cu1.ToFullString()) Dim cu2 = cu.ReplaceToken(privateToken, {publicToken, partialToken}) Assert.Equal( Public Partial Class C End Class.Value, cu2.ToFullString()) Dim cu3 = cu.ReplaceToken(privateToken, New SyntaxToken() {}) Assert.Equal( Class C End Class.Value, cu3.ToFullString()) End Sub Public Sub TestReplaceNonListTokenWithMultipleTokensFails() Dim cu = SyntaxFactory.ParseCompilationUnit( Private Class C End Class.Value) Dim identifierC = cu.DescendantTokens().First(Function(t) t.Text = "C") Dim identifierA = SyntaxFactory.ParseToken("A") Dim identifierB = SyntaxFactory.ParseToken("B") ' you cannot replace a token that Is a single token member with multiple tokens Assert.Throws(Of InvalidOperationException)(Function() cu.ReplaceToken(identifierC, {identifierA, identifierB})) ' you cannot replace a token that Is a single token member with an empty list of tokens Assert.Throws(Of InvalidOperationException)(Function() cu.ReplaceToken(identifierC, New SyntaxToken() {})) End Sub Public Sub TestInsertTokensInList() Dim cu = SyntaxFactory.ParseCompilationUnit( Public Class C End Class.Value) Dim publicToken = DirectCast(cu.Members(0), ClassBlockSyntax).Begin.Modifiers(0) Dim partialToken = SyntaxFactory.ParseToken("Partial ") Dim sharedToken = SyntaxFactory.ParseToken("Shared ") Dim cu1 = cu.InsertTokensBefore(publicToken, {sharedToken}) Assert.Equal( Shared Public Class C End Class.Value, cu1.ToFullString()) Dim cu2 = cu.InsertTokensAfter(publicToken, {sharedToken}) Assert.Equal( Public Shared Class C End Class.Value, cu2.ToFullString()) End Sub Public Sub TestInsertTokensRelativeToNonListToken() Dim cu = SyntaxFactory.ParseCompilationUnit( Private Class C End Class.Value) Dim identifierC = cu.DescendantTokens().First(Function(t) t.Text = "C") Dim identifierA = SyntaxFactory.ParseToken("A") Dim identifierB = SyntaxFactory.ParseToken("B") ' you cannot insert tokens before/after a token that is not part of a list Assert.Throws(Of InvalidOperationException)(Function() cu.InsertTokensBefore(identifierC, {identifierA, identifierB})) ' you cannot insert tokens before/after a token that is not part of a list Assert.Throws(Of InvalidOperationException)(Function() cu.InsertTokensAfter(identifierC, New SyntaxToken() {})) End Sub Public Sub TestReplaceSingleTriviaInNode() Dim expr = SyntaxFactory.ParseExpression("a + b") Dim trivia = expr.DescendantTokens().First(Function(t) t.Text = "a").TrailingTrivia(0) Dim twoSpaces = SyntaxFactory.Whitespace(" ") Dim expr2 = expr.ReplaceTrivia(trivia, twoSpaces) Assert.Equal("a + b", expr2.ToFullString()) End Sub Public Sub TestReplaceMultipleTriviaInNode() Dim expr = SyntaxFactory.ParseExpression("a + b") Dim twoSpaces = SyntaxFactory.Whitespace(" ") Dim trivia = expr.DescendantTrivia().Where(Function(tr) tr.IsKind(SyntaxKind.WhitespaceTrivia)).ToList() Dim replaced = expr.ReplaceTrivia(trivia, Function(tr, tr2) twoSpaces) Assert.Equal("a + b", replaced.ToFullString()) End Sub Public Sub TestReplaceSingleTriviaWithMultipleTriviaInNode() Dim ex = SyntaxFactory.ParseExpression("identifier 'c") Dim trivia = ex.GetTrailingTrivia() Assert.Equal(2, trivia.Count) Dim comment1 = trivia(1) Assert.Equal(SyntaxKind.CommentTrivia, comment1.VisualBasicKind()) Dim newComment1 = SyntaxFactory.ParseTrailingTrivia("'a")(0) Dim newComment2 = SyntaxFactory.ParseTrailingTrivia("'b")(0) Dim ex1 = ex.ReplaceTrivia(comment1, newComment1) Assert.Equal("identifier 'a", ex1.ToFullString()) Dim ex2 = ex.ReplaceTrivia(comment1, {newComment1, newComment2}) Assert.Equal("identifier 'a'b", ex2.ToFullString()) Dim ex3 = ex.ReplaceTrivia(comment1, New SyntaxTrivia() {}) Assert.Equal("identifier ", ex3.ToFullString()) End Sub Public Sub TestInsertTriviaInNode() Dim ex = SyntaxFactory.ParseExpression("identifier 'c") Dim trivia = ex.GetTrailingTrivia() Assert.Equal(2, trivia.Count) Dim comment1 = trivia(1) Assert.Equal(SyntaxKind.CommentTrivia, comment1.VisualBasicKind()) Dim newComment1 = SyntaxFactory.ParseTrailingTrivia("'a")(0) Dim newComment2 = SyntaxFactory.ParseTrailingTrivia("'b")(0) Dim ex1 = ex.InsertTriviaBefore(comment1, {newComment1, newComment2}) Assert.Equal("identifier 'a'b'c", ex1.ToFullString()) Dim ex2 = ex.InsertTriviaAfter(comment1, {newComment1, newComment2}) Assert.Equal("identifier 'c'a'b", ex2.ToFullString()) End Sub Public Sub TestReplaceSingleTriviaInToken() Dim id = SyntaxFactory.ParseToken("a ") Dim trivia = id.TrailingTrivia(0) Dim twoSpace = SyntaxFactory.Whitespace(" ") Dim id2 = id.ReplaceTrivia(trivia, twoSpace) Assert.Equal("a ", id2.ToFullString()) End Sub Public Sub TestReplaceMultipleTriviaInToken() Dim id = SyntaxFactory.ParseToken( a 'foo .Value) ' replace each trivia with a single space Dim id2 = id.ReplaceTrivia(id.GetAllTrivia(), Function(tr, tr2) SyntaxFactory.Space) ' should be 3 spaces (one for original space, comment and end-of-line) Assert.Equal("a ", id2.ToFullString()) End Sub Public Sub TestTriviaExtensions() Dim simpleTree = CreateSimpleTree() Assert.Equal("1- X( 3, 4+ 8, 9) ", simpleTree.ToFullString()) Dim tk = simpleTree.GetLastToken(includeZeroWidth:=True) Assert.Equal(") ", tk.ToFullString()) tk = simpleTree.GetFirstToken(includeZeroWidth:=True) Assert.Equal("1", tk.ToFullString()) tk = tk.WithLeadingTrivia(SyntaxFactory.WhitespaceTrivia(" ")) Assert.Equal(" 1", tk.ToFullString()) tk = tk.WithLeadingTrivia(SyntaxFactory.WhitespaceTrivia(" ")) tk = tk.WithTrailingTrivia(SyntaxFactory.WhitespaceTrivia(" ")) Assert.Equal(" 1 ", tk.ToFullString()) End Sub Public Sub TestCommonSyntaxNode() 'Dim node As SyntaxNode = ParseAndVerify(" Module M1" & vbCrLf & "End Module") 'Assert.False(node.Errors.Any()) 'Assert.Equal(0, node.GetTrailingTrivia.Count) 'Assert.Equal(1, node.GetLeadingTrivia.Count) 'Assert.False(node.IsTerminal) 'Assert.Equal(3, node.ChildNodesAndTokens().Count) 'Assert.Equal(1, node.SpanStart) 'Assert.Equal(22, node.Span.End) 'Assert.Equal(0, node.FullSpan.Start) 'Assert.Equal(22, node.FullSpan.End) 'Assert.Null(node.Parent) ' ' When this breaks, uncomment above Dim tree As SyntaxTree = VisualBasicSyntaxTree.ParseText(SourceText.From(" Module M1" & vbCrLf & "End Module")) Dim node As SyntaxNode = tree.GetRoot() Assert.Equal(False, tree.GetDiagnostics(node).Any) Assert.Equal(0, tree.GetRoot().FindToken(node.FullSpan.Length - 1).TrailingTrivia.Count) Assert.Equal(1, tree.GetRoot().FindToken(0).LeadingTrivia.Count) Assert.Equal(False, node.ChildNodesAndTokens().Count = 0) Assert.Equal(2, node.ChildNodesAndTokens().Count) 'Assert.Equal(1, tree.GetSpan(node).Start) 'Assert.Equal(22, tree.GetSpan(node).End) 'Assert.Equal(0, tree.GetFullSpan(node).Start) 'Assert.Equal(22, tree.GetFullSpan(node).End) 'Assert.Equal(Nothing, tree.GetParent(node)) End Sub Public Sub TestDiagnostic() 'Dim node As SyntaxNode = ' ParseAndVerify( ' "Module M1" & vbCrLf & "End", ' ' ' ' ) 'Assert.True(node.Errors.Any) 'Assert.Equal(2, node.Errors.Count) 'Assert.Equal(DiagnosticSeverity.Error, node.Errors(0).Severity) 'Assert.Contains(30678, From d In node.Errors Select d.Code) ' ' When this breaks, uncomment above Dim tree As SyntaxTree = VisualBasicSyntaxTree.ParseText(SourceText.From("Module M1" & vbCrLf & "End")) Dim node As SyntaxNode = tree.GetRoot() Assert.Equal(True, tree.GetDiagnostics(node).Any) Assert.Equal(2, tree.GetDiagnostics(node).Count) Assert.Equal(DiagnosticSeverity.Error, tree.GetDiagnostics(node)(0).Severity) Assert.Equal(30625, tree.GetDiagnostics(node)(0).Code) Assert.Equal(30678, tree.GetDiagnostics(node)(1).Code) End Sub Public Sub TestStructuredTrivia() Dim xmlStartElement = SyntaxFactory.XmlElementStartTag( SyntaxFactory.Token(spaceTrivia, SyntaxKind.LessThanToken, trailing:=Nothing), SyntaxFactory.XmlName(Nothing, SyntaxFactory.XmlNameToken("foo", SyntaxKind.XmlNameToken)), Nothing, SyntaxFactory.Token(SyntaxKind.GreaterThanToken, trailing:=spaceTrivia)) Dim xmlEndElement = SyntaxFactory.XmlElementEndTag( SyntaxFactory.Token(SyntaxKind.LessThanSlashToken, trailing:=spaceTrivia), Nothing, SyntaxFactory.Token(Nothing, SyntaxKind.GreaterThanToken, trailing:=SyntaxTriviaList.Create(spaceTrivia).Concat(spaceTrivia).ToSyntaxTriviaList())) Dim xmlElement = SyntaxFactory.XmlElement(xmlStartElement, Nothing, xmlEndElement) Assert.Equal(" ", xmlElement.ToFullString) Assert.Equal(" ", xmlElement.ToString) Dim docComment = SyntaxFactory.DocumentationCommentTrivia(SyntaxFactory.SingletonList(Of XmlNodeSyntax)(xmlElement)) Assert.Equal(" ", docComment.ToFullString) Assert.Equal(" ", docComment.ToString) Assert.Equal(" ", docComment.Content(0).ToFullString) Assert.Equal(" ", docComment.Content(0).ToString) Assert.Equal(" ", DirectCast(docComment.Content(0), XmlElementSyntax).StartTag.ToFullString) Assert.Equal("", DirectCast(docComment.Content(0), XmlElementSyntax).StartTag.ToString) Dim sTrivia = SyntaxFactory.Trivia(docComment) Dim ident = SyntaxFactory.Identifier(sTrivia, "banana", spaceTrivia) Assert.Equal(" banana ", ident.ToFullString()) Assert.Equal("banana", ident.ToString()) Assert.Equal(" ", ident.LeadingTrivia()(0).ToFullString) Assert.Equal(" ", ident.LeadingTrivia()(0).ToString()) Dim identExpr = SyntaxFactory.IdentifierName(ident) ' make sure FindLeaf digs into the structured trivia. Dim result = identExpr.FindToken(3, True) Assert.Equal(SyntaxKind.XmlNameToken, result.VisualBasicKind) Assert.Equal("foo", result.ToString()) Dim trResult = identExpr.FindTrivia(6, True) Assert.Equal(SyntaxKind.WhitespaceTrivia, trResult.VisualBasicKind) Assert.Equal(" ", trResult.ToString()) Dim foundDocComment = result.Parent.Parent.Parent.Parent Assert.Equal(Nothing, foundDocComment.Parent) Dim identTrivia = identExpr.GetLeadingTrivia(0) Dim foundTrivia = DirectCast(foundDocComment, DocumentationCommentTriviaSyntax).ParentTrivia Assert.Equal(identTrivia, foundTrivia) ' make sure FindLeafNodesOverlappingWithSpan does not dig into the structured trivia. Dim resultList = identExpr.DescendantTokens(New TextSpan(3, 18)) Assert.Equal(1, resultList.Count) End Sub ' Check that the children list preserved identity. Public Sub ChildrenListObjectIdentity() Dim tree = CreateSimpleTree() Dim children1 = tree.ChildNodesAndTokens() Dim children2 = tree.ChildNodesAndTokens() Assert.Equal(children1, children2) Dim child2_1 = tree.ChildNodesAndTokens()(1) Dim child2_2 = tree.ChildNodesAndTokens()(1) Assert.Equal(child2_1, child2_2) End Sub Private Function CreateNamespaceBlock() As NamespaceBlockSyntax Dim statementBuilder = SyntaxListBuilder(Of StatementSyntax).Create() statementBuilder.Add(SyntaxFactory.EmptyStatement(SyntaxFactory.Token(SyntaxKind.EmptyToken))) statementBuilder.Add(SyntaxFactory.EmptyStatement(SyntaxFactory.Token(SyntaxKind.EmptyToken))) statementBuilder.Add(SyntaxFactory.EmptyStatement(SyntaxFactory.Token(SyntaxKind.EmptyToken))) Return SyntaxFactory.NamespaceBlock(SyntaxFactory.NamespaceStatement( SyntaxFactory.Token(SyntaxKind.NamespaceKeyword, trailing:=spaceTrivia), SyntaxFactory.IdentifierName(SyntaxFactory.Identifier("foo"))), statementBuilder.ToList, SyntaxFactory.EndNamespaceStatement(SyntaxFactory.Token(SyntaxKind.EndKeyword), SyntaxFactory.Token(SyntaxKind.NamespaceKeyword))) End Function ' Check that specific children accessors preserve object identifier Public Sub ChildAccessorObjectIdentity() Dim tree = CreateSimpleTree() Dim left1 = tree.Left Dim left2 = tree.Left Assert.Same(left1, left2) Dim nsBlock = CreateNamespaceBlock() Dim membs1 = nsBlock.Members Dim membs2 = nsBlock.Members Assert.Same(membs1.Node, membs2.Node) Dim begin1 = nsBlock.NamespaceStatement Dim begin2 = nsBlock.NamespaceStatement Assert.Same(begin1, begin2) Dim firstMember1 = nsBlock.Members(0) Dim firstMember2 = nsBlock.Members(0) Dim firstMember3 = nsBlock.ChildNodesAndTokens()(1) Assert.Same(firstMember1, firstMember2) Assert.Same(firstMember1, firstMember3.AsNode) nsBlock = CreateNamespaceBlock() firstMember3 = nsBlock.ChildNodesAndTokens()(1) firstMember1 = nsBlock.Members(0) firstMember2 = nsBlock.Members(0) Assert.Same(firstMember1, firstMember2) Assert.Same(firstMember1, firstMember3.AsNode) End Sub ' Check that specific children accessors preserve object identifier Public Sub TestTreeIterator() Dim tree = CreateSimpleTree() Dim txt As String = "" Dim terminals = tree.DescendantTokens(tree.FullSpan) For Each n In terminals txt &= n.ToFullString() Next Assert.Equal(tree.ToFullString, txt) Assert.Equal(12, terminals.Count) Dim op = tree.Right Dim newOp = SyntaxFactory.StringLiteralExpression(SyntaxFactory.StringLiteralToken("""Hi""", "Hi")) tree = tree.ReplaceNode(op, newOp) terminals = tree.DescendantTokens(tree.FullSpan) txt = "" For Each n In terminals txt &= n.ToFullString() Next Assert.Equal(tree.ToFullString, txt) Assert.Equal(3, terminals.Count) End Sub Public Sub TestGetNextToken() Dim prog = ParseAndVerify() Dim tk0 = prog.GetRoot().FindToken(25) Assert.Equal("xxxx", tk0.ToString) Dim colons = tk0.TrailingTrivia().Where(Function(t) t.VisualBasicKind = SyntaxKind.ColonTrivia).ToArray() Assert.Equal(colons.Length, 2) For Each colon In colons Assert.Equal(":", colon.ToString) Next Dim tk_nonzero1 = tk0.GetNextToken Assert.Equal("Dim", tk_nonzero1.ToString) Dim tk_nonzero2 = tk_nonzero1.GetNextToken Assert.Equal("yyyy", tk_nonzero2.ToString) Dim tk_zero1 = tk_nonzero1.GetNextToken(includeZeroWidth:=True) Assert.Equal("yyyy", tk_zero1.ToString) Dim newline = tk_zero1.TrailingTrivia.Where(Function(t) t.VisualBasicKind = SyntaxKind.EndOfLineTrivia).First Assert.Equal(vbLf, newline.ToString) End Sub Public Sub TestGetPreviousToken() Dim prog = ParseAndVerify() Dim tk0 = prog.GetRoot().FindToken(32) Assert.Equal("Dim", tk0.ToString) Dim tk_nonzero1 = tk0.GetPreviousToken Assert.Equal("xxxx", tk_nonzero1.ToString) Dim trivia = tk_nonzero1.TrailingTrivia Assert.Equal(" ::", trivia.ToString) Dim tk_nonzero3 = tk_nonzero1.GetPreviousToken Assert.Equal("dim", tk_nonzero3.ToString) Dim tk_zero1 = tk_nonzero1.GetPreviousToken(includeZeroWidth:=True) Assert.Equal("dim", tk_zero1.ToString) Dim tk_zero2 = tk_zero1.GetPreviousToken(includeZeroWidth:=True) Assert.Equal("Module1", tk_zero2.ToString) Dim tk_zero3 = tk_zero2.GetPreviousToken(includeZeroWidth:=True) Assert.Equal(vbLf, tk_zero3.LeadingTrivia.ToString) End Sub Public Sub TestCommonSyntaxTokenGetPreviousToken() Dim text = "Class C(Of T)" & vbCrLf & " Dim l As List(Of T)" & "End Class" Dim tree = VisualBasicSyntaxTree.ParseText(text) Dim location = text.IndexOf("List(Of T)") Dim openParenToken = CType(tree.GetRoot().FindToken(location + "List".Length), SyntaxToken) Assert.Equal(SyntaxKind.OpenParenToken, openParenToken.VisualBasicKind) Dim listToken = CType(openParenToken.GetPreviousToken(), SyntaxToken) Assert.Equal(SyntaxKind.IdentifierToken, listToken.VisualBasicKind) End Sub Public Sub TestGetNextSibling() Dim prog = ParseAndVerify() Dim trivia = prog.GetRoot().FindToken(28).TrailingTrivia Assert.Equal(" :::", trivia.ToString) Dim tk_nonzero1 = CType(trivia.First().Token.Parent.Parent.Parent, SyntaxNodeOrToken).GetNextSibling() Assert.Equal("Dim yyyy", tk_nonzero1.ToString) Dim tk_nonzero2 = tk_nonzero1.GetNextSibling Assert.Equal("End Module", tk_nonzero2.ToString) End Sub Public Sub TestGetPreviousSibling() Dim prog = ParseAndVerify() Dim tk0 As SyntaxNodeOrToken = prog.GetRoot().FindToken(31) Assert.Equal("Dim", tk0.ToString) Dim tk_nonzero1 = tk0.GetPreviousSibling Assert.Equal(Nothing, tk_nonzero1) tk0 = tk0.Parent tk_nonzero1 = tk0.GetPreviousSibling Assert.Equal("dim xxxx", tk_nonzero1.ToString) Dim trivia = tk_nonzero1.GetTrailingTrivia() Assert.Equal(" :::", trivia.ToString) End Sub Public Sub TestFirstLastDirective() Dim prog = ParseAndVerify() Dim tk0 As SyntaxNodeOrToken = prog.GetRoot().FindToken(35) Dim mDecl = tk0.Parent Dim fDir = mDecl.GetFirstDirective Assert.Equal("#const x =1", fDir.ToString) Dim lDir = mDecl.GetLastDirective Assert.Equal("#const y = 2", lDir.ToString) Dim fDir1 = mDecl.GetFirstDirective(Function(d) d.ToString = "#const y = 2") Assert.Equal("#const y = 2", fDir1.ToString) fDir1 = mDecl.GetFirstDirective(Function(d) d.ToString = "#const y = 42") Assert.Equal(Nothing, fDir1) Dim lDir1 = mDecl.GetLastDirective(Function(d) d.ToString = "#const x =1") Assert.Equal("#const x =1", lDir1.ToString) lDir1 = mDecl.GetLastDirective(Function(d) d.ToString = "#const x =42") Assert.Equal(Nothing, lDir1) End Sub Public Sub TestNextPrevDirective() Dim prog = ParseAndVerify() Dim tk0 As SyntaxNodeOrToken = prog.GetRoot().FindToken(35) Dim mDecl = tk0.Parent Dim fDir = mDecl.GetFirstDirective Dim fDir1 = fDir.GetNextDirective Assert.Equal("#const y = 2", fDir1.ToString) Dim lDir = mDecl.GetLastDirective Dim lDir1 = fDir.GetNextDirective Assert.Equal("#const y = 2", lDir1.ToString) Dim fDir2 = fDir1.GetNextDirective(Function(d) d.ToString = "#const y = 3") Assert.Equal("#const y = 3", fDir2.ToString) fDir2 = fDir1.GetNextDirective(Function(d) d.ToString = "#const y = 42") Assert.Equal(Nothing, fDir2) Dim lDir2 = lDir1.GetPreviousDirective(Function(d) d.ToString = "#const x =1") Assert.Equal("#const x =1", lDir2.ToString) lDir2 = lDir1.GetPreviousDirective(Function(d) d.ToString = "#const x =42") Assert.Equal(Nothing, lDir2) End Sub Public Sub TestNodeTokenConversion01() Dim prog = ParseAndVerify(, ) Dim sN As SyntaxNodeOrToken = prog.GetRoot() Dim cS As SyntaxNodeOrToken = sN Assert.Equal(sN.IsNode, cS.IsNode) Assert.Equal(sN.IsToken, cS.IsToken) Assert.Equal(sN.IsMissing, cS.IsMissing) Assert.Equal(sN.ContainsDiagnostics, cS.ContainsDiagnostics) Assert.Equal(sN.ContainsDirectives, cS.ContainsDirectives) Assert.Equal(sN.HasLeadingTrivia, cS.HasLeadingTrivia) Assert.Equal(sN.HasTrailingTrivia, cS.HasTrailingTrivia) Assert.Equal(sN.VisualBasicKind(), cS.VisualBasicKind()) Assert.Equal(sN.FullWidth, cS.FullSpan.Length) Assert.Equal(sN.Width, cS.Span.Length) End Sub Public Sub TestNodeTokenConversion02() Dim node As VisualBasicSyntaxNode = Nothing ' This should not throw - it should convert to a 'null' (default) struct Dim sn As SyntaxNodeOrToken = node Assert.True(sn.IsNode) End Sub Public Sub SyntaxTriviaDefaultIsDirective() Dim trivia As New SyntaxTrivia() Assert.False(trivia.IsDirective) End Sub Public Sub TestGetNextTokenCommon() Dim tree As SyntaxTree = VisualBasicSyntaxTree.ParseText("public class foo : end class") Dim tokens As List(Of SyntaxToken) = tree.GetRoot().DescendantTokens().ToList() Dim list As List(Of SyntaxToken) = New List(Of SyntaxToken)() Dim token As SyntaxToken = tree.GetRoot().GetFirstToken() While token.VisualBasicKind <> 0 list.Add(token) token = token.GetNextToken() End While ' Descendant nodes contain EOF Assert.Equal(tokens.Count - 1, list.Count) For i = 0 To list.Count - 1 Assert.Equal(list(i), tokens(i)) Next ' Verify that EOF is returned when calling with Any predicate. list.Clear() token = tree.GetRoot().GetFirstToken() While token.VisualBasicKind <> 0 list.Add(token) token = token.GetNextToken(includeZeroWidth:=True) End While Debug.Assert(list(list.Count - 1).VisualBasicKind = SyntaxKind.EndOfFileToken) Dim lastToken = tree.GetRoot().DescendantTokens().Last Debug.Assert(lastToken.VisualBasicKind = SyntaxKind.EndOfFileToken) End Sub Public Sub TestFindNode() Dim code = Class Foo End Class Class Bar End Class]]> .Value Dim tree = VisualBasicSyntaxTree.ParseText(code) Dim root = tree.GetRoot() Assert.Equal(root, root.FindNode(root.Span, findInsideTrivia:=False)) Assert.Equal(root, root.FindNode(root.Span, findInsideTrivia:=True)) Dim classDecl = DirectCast(root.ChildNodes().First(), TypeBlockSyntax) Dim classStatement = classDecl.Begin ' IdentifierNameSyntax in trivia. Dim identifier = root.DescendantNodes(descendIntoTrivia:=True).Single(Function(n) TypeOf n Is IdentifierNameSyntax) Dim position = identifier.Span.Start + 1 Assert.Equal(classStatement, root.FindNode(identifier.Span, findInsideTrivia:=False)) Assert.Equal(identifier, root.FindNode(identifier.Span, findInsideTrivia:=True)) ' Token span. Assert.Equal(classStatement, root.FindNode(classStatement.Identifier.Span, findInsideTrivia:=False)) Dim EOFSpan = New TextSpan(root.FullSpan.End, 0) Assert.Equal(root, root.FindNode(EOFSpan, findInsideTrivia:=False)) Assert.Equal(root, root.FindNode(EOFSpan, findInsideTrivia:=True)) ' EOF Invalid span for childnode Dim classDecl2 = DirectCast(root.ChildNodes().Last(), TypeBlockSyntax) Dim classStatement2 = classDecl2.Begin Assert.Throws(Of ArgumentOutOfRangeException)(Sub() classDecl2.FindNode(EOFSpan)) ' Check end position included in node span Dim nodeEndPositionSpan = New TextSpan(classDecl.FullSpan.End, 0) Assert.Equal(classStatement2, root.FindNode(nodeEndPositionSpan, findInsideTrivia:=False)) Assert.Equal(classStatement2, root.FindNode(nodeEndPositionSpan, findInsideTrivia:=True)) Assert.Equal(classStatement2, classDecl2.FindNode(nodeEndPositionSpan, findInsideTrivia:=False)) Assert.Equal(classStatement2, classDecl2.FindNode(nodeEndPositionSpan, findInsideTrivia:=True)) ' End position of node Assert.Throws(Of ArgumentOutOfRangeException)(Sub() classDecl.FindNode(nodeEndPositionSpan)) ' Invalid spans. Dim invalidSpan = New TextSpan(100, 100) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() root.FindNode(invalidSpan)) invalidSpan = New TextSpan(root.FullSpan.End - 1, 2) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() root.FindNode(invalidSpan)) invalidSpan = New TextSpan(classDecl2.FullSpan.Start - 1, root.FullSpan.End) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() classDecl2.FindNode(invalidSpan)) invalidSpan = new TextSpan(classDecl.FullSpan.End, root.FullSpan.End) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() classDecl2.FindNode(invalidSpan)) ' Parent node's span. Assert.Throws(Of ArgumentOutOfRangeException)(Sub() classDecl.FindNode(root.FullSpan)) End Sub Public Sub TestFindTrivaNoTriviaExistsAtPosition() Dim code = Class Foo Sub Bar() End Sub End Class.Value Dim tree = VisualBasicSyntaxTree.ParseText(code) Dim position = tree.GetText().Lines(1).End 'position points to the end of the line that has "Sub Bar()" 'There should be end of line trivia there. Dim trivia = tree.GetRoot().FindTrivia(position) Assert.Equal(SyntaxKind.EndOfLineTrivia, trivia.VisualBasicKind) Assert.Equal(23, trivia.SpanStart) Assert.Equal(24, trivia.Span.End) End Sub Public Sub TestChildNodes() Dim text = "m(a,b,c)" Dim expression = SyntaxFactory.ParseExpression(text) Dim nodes = expression.ChildNodes().ToList() Assert.Equal(2, nodes.Count) Assert.Equal(SyntaxKind.IdentifierName, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.ArgumentList, nodes(1).VisualBasicKind) End Sub Public Sub TestAncestors() Dim text = "a + (b - (c * (d / e)))" Dim expression = SyntaxFactory.ParseExpression(text) Dim e = expression.DescendantNodes().OfType(Of IdentifierNameSyntax)().First(Function(n) n.Identifier.ValueText = "e") Dim nodes = e.Ancestors().ToList() Assert.Equal(7, nodes.Count) Assert.Equal(SyntaxKind.DivideExpression, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.ParenthesizedExpression, nodes(1).VisualBasicKind) Assert.Equal(SyntaxKind.MultiplyExpression, nodes(2).VisualBasicKind) Assert.Equal(SyntaxKind.ParenthesizedExpression, nodes(3).VisualBasicKind) Assert.Equal(SyntaxKind.SubtractExpression, nodes(4).VisualBasicKind) Assert.Equal(SyntaxKind.ParenthesizedExpression, nodes(5).VisualBasicKind) Assert.Equal(SyntaxKind.AddExpression, nodes(6).VisualBasicKind) End Sub Public Sub TestAncestorsOrSelf() Dim text = "a + (b - (c * (d / e)))" Dim expression = SyntaxFactory.ParseExpression(text) Dim e = expression.DescendantNodes().OfType(Of IdentifierNameSyntax)().First(Function(n) n.Identifier.ValueText = "e") Dim nodes = e.AncestorsAndSelf().ToList() Assert.Equal(8, nodes.Count) Assert.Equal(SyntaxKind.IdentifierName, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.DivideExpression, nodes(1).VisualBasicKind) Assert.Equal(SyntaxKind.ParenthesizedExpression, nodes(2).VisualBasicKind) Assert.Equal(SyntaxKind.MultiplyExpression, nodes(3).VisualBasicKind) Assert.Equal(SyntaxKind.ParenthesizedExpression, nodes(4).VisualBasicKind) Assert.Equal(SyntaxKind.SubtractExpression, nodes(5).VisualBasicKind) Assert.Equal(SyntaxKind.ParenthesizedExpression, nodes(6).VisualBasicKind) Assert.Equal(SyntaxKind.AddExpression, nodes(7).VisualBasicKind) End Sub Public Sub TestDescendantNodes() Dim text = .Value Dim statement = SyntaxFactory.ParseExecutableStatement(text) Dim nodes = statement.DescendantNodes().ToList() Assert.Equal(1, nodes.Count) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(0).VisualBasicKind) nodes = statement.DescendantNodes(descendIntoTrivia:=True).ToList() Assert.Equal(4, nodes.Count) Assert.Equal(SyntaxKind.DocumentationCommentTrivia, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(1).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(2).VisualBasicKind) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(3).VisualBasicKind) ' again with spans nodes = statement.DescendantNodes(statement.FullSpan).ToList() Assert.Equal(1, nodes.Count) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(0).VisualBasicKind) nodes = statement.DescendantNodes(statement.FullSpan, descendIntoTrivia:=True).ToList() Assert.Equal(4, nodes.Count) Assert.Equal(SyntaxKind.DocumentationCommentTrivia, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(1).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(2).VisualBasicKind) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(3).VisualBasicKind) End Sub Public Sub TestDescendantNodesOrSelf() Dim text = .Value Dim statement = SyntaxFactory.ParseExecutableStatement(text) Dim nodes = statement.DescendantNodesAndSelf().ToList() Assert.Equal(2, nodes.Count) Assert.Equal(SyntaxKind.ReturnStatement, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(1).VisualBasicKind) nodes = statement.DescendantNodesAndSelf(descendIntoTrivia:=True).ToList() Assert.Equal(5, nodes.Count) Assert.Equal(SyntaxKind.ReturnStatement, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.DocumentationCommentTrivia, nodes(1).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(2).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(3).VisualBasicKind) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(4).VisualBasicKind) ' again with spans nodes = statement.DescendantNodesAndSelf(statement.FullSpan).ToList() Assert.Equal(2, nodes.Count) Assert.Equal(SyntaxKind.ReturnStatement, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(1).VisualBasicKind) nodes = statement.DescendantNodesAndSelf(statement.FullSpan, descendIntoTrivia:=True).ToList() Assert.Equal(5, nodes.Count) Assert.Equal(SyntaxKind.ReturnStatement, nodes(0).VisualBasicKind) Assert.Equal(SyntaxKind.DocumentationCommentTrivia, nodes(1).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(2).VisualBasicKind) Assert.Equal(SyntaxKind.XmlText, nodes(3).VisualBasicKind) Assert.Equal(SyntaxKind.TrueLiteralExpression, nodes(4).VisualBasicKind) End Sub Public Sub TestDescendantTrivia() Dim text = .Value Dim expr = SyntaxFactory.ParseExpression(text) Dim list = expr.DescendantTrivia().ToList() Assert.Equal(6, list.Count) Assert.Equal(SyntaxKind.CommentTrivia, list(0).VisualBasicKind) Assert.Equal(SyntaxKind.EndOfLineTrivia, list(1).VisualBasicKind) Assert.Equal(SyntaxKind.WhitespaceTrivia, list(2).VisualBasicKind) Assert.Equal(SyntaxKind.WhitespaceTrivia, list(3).VisualBasicKind) End Sub Public Sub TestDescendantTriviaIntoStructuredTrivia() Dim text = ''' a + b ]]>.Value Dim expr = SyntaxFactory.ParseExpression(text) Dim list = expr.DescendantTrivia(descendIntoTrivia:=True).ToList() Assert.Equal(9, list.Count) Assert.Equal(SyntaxKind.EndOfLineTrivia, list(0).VisualBasicKind) Assert.Equal(SyntaxKind.DocumentationCommentTrivia, list(1).VisualBasicKind) Assert.Equal(SyntaxKind.DocumentationCommentExteriorTrivia, list(2).VisualBasicKind) Assert.Equal(SyntaxKind.WhitespaceTrivia, list(3).VisualBasicKind) Assert.Equal(SyntaxKind.DocumentationCommentExteriorTrivia, list(4).VisualBasicKind) Assert.Equal(SyntaxKind.WhitespaceTrivia, list(5).VisualBasicKind) Assert.Equal(SyntaxKind.WhitespaceTrivia, list(6).VisualBasicKind) End Sub Public Sub SyntaxNodeToString() Dim text = "Imports System" Dim root = SyntaxFactory.ParseCompilationUnit(text) Dim children = root.DescendantNodesAndTokens() Dim nodeOrToken = children.First() 'Assert.Equal("SyntaxNodeOrToken ImportsStatement Imports System", nodeOrToken.DebuggerDisplay) Assert.Equal(text, nodeOrToken.ToString()) Dim node = children.First(Function(n) n.IsNode).AsNode() 'Assert.Equal("ImportsStatementSyntax ImportsStatement Imports System", node.DebuggerDisplay) Assert.Equal(text, node.ToString()) Dim token = children.First(Function(n) n.IsToken).AsToken() 'Assert.Equal("SyntaxToken ImportsKeyword Imports", token.DebuggerDisplay) Assert.Equal("Imports ", token.ToFullString()) Assert.Equal("Imports", token.ToString()) Dim trivia = root.DescendantTrivia().First() 'Assert.Equal("SyntaxTrivia WhitespaceTrivia ", trivia.DebuggerDisplay) Assert.Equal(" ", trivia.ToFullString()) End Sub Public Sub TestRemoveNodeInSeparatedList_KeepExteriorTrivia() Dim expr = SyntaxFactory.ParseExpression("m(a, b, c)") Dim b = expr.DescendantTokens().Where(Function(t) t.ToString() = "b").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ArgumentSyntax)()).FirstOrDefault() Assert.NotNull(b) Dim expr2 = expr.RemoveNode(b, SyntaxRemoveOptions.KeepExteriorTrivia) Dim text = expr2.ToFullString() Assert.Equal("m(a , c)", text) End Sub Public Sub TestRemoveNodeInSeparatedList_KeepNoTrivia() Dim expr = SyntaxFactory.ParseExpression("m(a, b, c)") Dim b = expr.DescendantTokens().Where(Function(t) t.ToString() = "b").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ArgumentSyntax)()).FirstOrDefault() Assert.NotNull(b) Dim expr2 = expr.RemoveNode(b, SyntaxRemoveOptions.KeepNoTrivia) Dim text = expr2.ToFullString() Assert.Equal("m(a, c)", text) End Sub Public Sub TestRemoveOnlyNodeInSeparatedList_KeepExteriorTrivia() Dim expr = SyntaxFactory.ParseExpression("m( a )") Dim n = expr.DescendantTokens().Where(Function(t) t.ToString() = "a").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ArgumentSyntax)()).FirstOrDefault() Assert.NotNull(n) Dim expr2 = expr.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia) Dim text = expr2.ToFullString() Assert.Equal("m( )", text) End Sub Public Sub TestRemoveFirstNodeInSeparatedList_KeepExteriorTrivia() Dim expr = SyntaxFactory.ParseExpression("m( a , b, c)") Dim n = expr.DescendantTokens().Where(Function(t) t.ToString() = "a").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ArgumentSyntax)()).FirstOrDefault() Assert.NotNull(n) Dim expr2 = expr.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia) Dim text = expr2.ToFullString() Assert.Equal("m( b, c)", text) End Sub Public Sub TestRemoveLastNodeInSeparatedList_KeepExteriorTrivia() Dim expr = SyntaxFactory.ParseExpression("m(a, b , c )") Dim n = expr.DescendantTokens().Where(Function(t) t.ToString() = "c").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ArgumentSyntax)()).FirstOrDefault() Assert.NotNull(n) Dim expr2 = expr.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia) Dim text = expr2.ToFullString() Assert.Equal("m(a, b )", text) End Sub Public Sub TestRemoveFirstNodeInList_KeepExteriorTrivia() Dim text = Class Foo End Class ]]>.Value.Replace(vbLf, vbCrLf) Dim expected = Class Foo End Class ]]>.Value.Replace(vbLf, vbCrLf) Dim cu = SyntaxFactory.ParseCompilationUnit(text) Dim n = cu.DescendantTokens().Where(Function(t) t.ToString() = "A").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of AttributeListSyntax)()).FirstOrDefault() Dim cu2 = cu.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia) Dim result = cu2.ToFullString() Assert.Equal(expected, result) End Sub Public Sub TestRemoveLastNodeInList_KeepExteriorTrivia() Dim text = Class Foo End Class ]]>.Value.Replace(vbLf, vbCrLf) Dim expected = Class Foo End Class ]]>.Value.Replace(vbLf, vbCrLf) Dim cu = SyntaxFactory.ParseCompilationUnit(text) Dim n = cu.DescendantTokens().Where(Function(t) t.ToString() = "C").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of AttributeListSyntax)()).FirstOrDefault() Dim cu2 = cu.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia) Dim result = cu2.ToFullString() Assert.Equal(expected, result) End Sub Public Sub TestMiddleLastNodeInList_KeepExteriorTrivia() Dim text = Class Foo End Class ]]>.Value.Replace(vbLf, vbCrLf) Dim expected = Class Foo End Class ]]>.Value.Replace(vbLf, vbCrLf) Dim cu = SyntaxFactory.ParseCompilationUnit(text) Dim n = cu.DescendantTokens().Where(Function(t) t.ToString() = "B").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of AttributeListSyntax)()).FirstOrDefault() Dim cu2 = cu.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia) Dim result = cu2.ToFullString() Assert.Equal(expected, result) End Sub Public Sub TestRemove_KeepUnbalancedDirectives() Dim text = .Value.Replace(vbLf, vbCrLf) Dim expected = .Value.Replace(vbLf, vbCrLf) Dim cu = SyntaxFactory.ParseCompilationUnit(text) Dim n = cu.DescendantTokens().Where(Function(t) t.ToString() = "Foo").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ClassBlockSyntax)()).FirstOrDefault() Dim cu2 = cu.RemoveNode(n, SyntaxRemoveOptions.KeepUnbalancedDirectives) Dim result = cu2.ToFullString() Assert.Equal(expected, result) End Sub Public Sub TestRemove_KeepExternalTrivia_KeepUnbalancedDirectives() Dim text = .Value.Replace(vbLf, vbCrLf) Dim expected = .Value.Replace(vbLf, vbCrLf) Dim cu = SyntaxFactory.ParseCompilationUnit(text) Dim n = cu.DescendantTokens().Where(Function(t) t.ToString() = "Foo").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ClassBlockSyntax)()).FirstOrDefault() Dim cu2 = cu.RemoveNode(n, SyntaxRemoveOptions.KeepExteriorTrivia Or SyntaxRemoveOptions.KeepUnbalancedDirectives) Dim result = cu2.ToFullString() Assert.Equal(expected, result) End Sub Public Sub TestRemove_KeepDirectives() Dim text = .Value.Replace(vbLf, vbCrLf) Dim expected = .Value.Replace(vbLf, vbCrLf) Dim cu = SyntaxFactory.ParseCompilationUnit(text) Dim n = cu.DescendantTokens().Where(Function(t) t.ToString() = "Foo").Select(Function(t) t.Parent.FirstAncestorOrSelf(Of ClassBlockSyntax)()).FirstOrDefault() Dim cu2 = cu.RemoveNode(n, SyntaxRemoveOptions.KeepDirectives) Dim result = cu2.ToFullString() Assert.Equal(expected, result) End Sub Public Sub Test_SyntaxTree_ParseFileInvalid() 'Invalid File argument Assert.Throws(Of ArgumentException)(Sub() Dim tree_Invalid_1 = VisualBasicSyntaxTree.ParseFile("") End Sub) Assert.Throws(Of ArgumentException)(Sub() Dim tree_Invalid_1 = VisualBasicSyntaxTree.ParseFile(Nothing) End Sub) End Sub Public Sub Test_SyntaxTree_ParseTextInvalid() Assert.Throws(Of ArgumentNullException)(Sub() Dim treeFromSourceWithPath_Invalid1 = VisualBasicSyntaxTree.ParseText("", path:=Nothing) End Sub) Assert.Throws(Of ArgumentNullException)(Sub() Dim st As SourceText = Nothing Dim treeFromSource_invalid = VisualBasicSyntaxTree.ParseText(st) End Sub) End Sub Public Sub TestSyntaxTree_GetChangesValid() ' Added for coverage on GetChanges and SyntaxDiffer Dim SourceText = Imports System Imports Microsoft.VisualBasic Imports System.Collections Module Module1 Sub Main Dim a as Integer = 1 Console.Writeline(a) End Sub End Module Dim tree = VisualBasicSyntaxTree.ParseText(SourceText.ToString) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) 'Get the Imports Clauses Dim FirstImportsClause As ImportsStatementSyntax = Root.Imports(0) Dim SecondImportsClause As ImportsStatementSyntax = Root.Imports(1) Dim ThirdImportsClause As ImportsStatementSyntax = Root.Imports(2) Dim ChangesForDifferentTrees = FirstImportsClause.SyntaxTree.GetChanges(SecondImportsClause.SyntaxTree) Assert.Equal(0, ChangesForDifferentTrees.Count) 'Do a transform to Replace and Existing Tree Dim name As NameSyntax = SyntaxFactory.QualifiedName(SyntaxFactory.IdentifierName("System"), SyntaxFactory.IdentifierName("Collections.Generic")) Dim oldImportClause As MembersImportsClauseSyntax = CType(ThirdImportsClause.ImportsClauses(0), MembersImportsClauseSyntax) Dim newImportsClause = oldImportClause.WithName(name) 'Replace Node with a different Imports Clause Root = Root.ReplaceNode(oldImportClause, newImportsClause) Dim ChangesFromTransform = ThirdImportsClause.SyntaxTree.GetChanges(newImportsClause.SyntaxTree) Assert.Equal(1, ChangesFromTransform.Count) 'Using the Common Syntax Changes Method as well for coverage Dim x As SyntaxTree = ThirdImportsClause.SyntaxTree Dim y As SyntaxTree = newImportsClause.SyntaxTree Dim changes2UsingCommonSyntax = x.GetChanges(y) Assert.Equal(1, changes2UsingCommonSyntax.Count) 'Verify Changes from VB Specific SyntaxTree and Common SyntaxTree are the same Assert.Equal(ChangesFromTransform, changes2UsingCommonSyntax) End Sub Public Sub TestSyntaxTree_GetChangesInValid() 'GetChanges with two Scenarios where either new or old tree is nothing Dim SourceText = Imports System Imports Microsoft.VisualBasic Module Module1 Sub Main End Sub End Module Dim tree = VisualBasicSyntaxTree.ParseText(SourceText.ToString) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) Dim FirstImportsClause As ImportsStatementSyntax = Root.Imports(0) Dim BlankTree As SyntaxTree = Nothing Dim BlankToSomethingChange = FirstImportsClause.SyntaxTree.GetChanges(BlankTree) Assert.Equal(1, BlankToSomethingChange.Count) Assert.Equal(New TextSpan(0, 0), BlankToSomethingChange(0).Span) Assert.Throws(Of NullReferenceException)(Sub() Dim SomethingToBlankChange = BlankTree.GetChanges(FirstImportsClause.SyntaxTree) End Sub) End Sub Public Sub TestSyntaxTree_GetChangeSpans() Dim oldTree = VisualBasicSyntaxTree.ParseText("class A : End Class") Dim newTree = oldTree.WithInsertAt(0, "class B : End Class") ' Valid operations Dim spans = newTree.GetChangedSpans(oldTree) Assert.Equal(1, spans.Count) 'Test Overload with COmmonSyntaxTree Dim span2 = CType(newTree, SyntaxTree).GetChangedSpans(CType(oldTree, SyntaxTree)) Assert.Equal(1, spans.Count) Assert.Equal(spans(0), span2(0)) ' Ensure Both spans from overloads returns same ' Invalid operations with a null tree Dim BlankTree As SyntaxTree = Nothing span2 = newTree.GetChangedSpans(BlankTree) span2 = CType(newTree, SyntaxTree).GetChangedSpans(CType(BlankTree, SyntaxTree)) Assert.Equal(1, span2.Count) Assert.Throws(Of ArgumentNullException)(Sub() Dim SomethingToBlankChnage = BlankTree.GetChangedSpans(CType(newTree, SyntaxTree)) End Sub) End Sub Public Sub TestSyntaxList_Failures() 'Validate the exceptions being generated when Invalid arguments are used for a TextSpan Constructor Dim SourceText = Imports System Imports Microsoft.VisualBasic Module Module1 Sub Main End Sub End Module 'Construct a SyntaxList and verify the bounds exceptions Dim tree = VisualBasicSyntaxTree.ParseText(SourceText.ToString) Dim x As New SyntaxList(Of SyntaxNode) For Each node In tree.GetRoot.ChildNodes x = x.Add(node) Next Assert.Equal(4, x.Count) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() Dim value1 = x(-1) End Sub) Assert.Throws(Of ArgumentOutOfRangeException)(Sub() Dim value1 = x(20) End Sub) End Sub Public Sub Test_CConst_CreateWithTypeCharacters() 'Added for Code Coverage Dim compilationDef = _ Imports System #Const char_a = "c"c #Const single_a = 1.2! #Const Date_a = #1/1/2000# Public Module Module1 #If char_a = "c"c Then Public Value_char As Boolean = True #Else Public Value_char As Boolean = False #End If #If Single_a = 1.2! Then Public Value_single As Boolean = True #Else Public Value_single As Boolean = False #End If #If Date_a = #1/1/2000# Then Public Value_Date As Boolean = True #Else Public Value_Date As Boolean = False #End If Sub main() Console.WriteLine(Value_char) Console.WriteLine(Value_single) Console.WriteLine(Value_Date) End Sub End Module Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(compilationDef) compilation.VerifyDiagnostics() End Sub Public Sub Test_UnaryOperators() Dim compilationDef = _ 'Type Types #If -1S Then 'Short #End If #If -1% Then 'Integer #End If #If -1@ Then 'Decimal #End If #If -1.0! Then 'Single #End If #If -1.0# Then 'Double #End If 'Forced Literal Types #If -1S Then 'Short #End If #If -1I Then 'Integer #End If #If -1L Then 'Long #End If #If -1.0F Then 'Single #End If #If -1D Then 'Double #End If #If -1UI Then 'unsigned Integer #End If #If -1UL Then 'unsigned Long #End If 'Type Types #If +1S Then 'Short #End If #If +1% Then 'Integer #End If #If +1@ Then 'Decimal #End If #If +1.0! Then 'Single #End If #If +1.0# Then 'Double #End If 'Forced Literal Types #If +1S Then 'Short #End If #If +1I Then 'Integer #End If #If +1L Then 'Long #End If #If +1.0F Then 'Single #End If #If +1D Then 'Double #End If #If +1UI Then 'unsigned Integer #End If #If +1UL Then 'unsigned Long #End If 'Type Types #If Not 1S Then 'Short #End If #If Not 1% Then 'Integer #End If #If Not 1@ Then 'Decimal #End If #If Not 1.0! Then 'Single #End If #If Not 1.0# Then 'Double #End If 'Forced Literal Types #If Not 1S Then 'Short #End If #If Not 1I Then 'Integer #End If #If Not 1L Then 'Long #End If #If Not 1.0F Then 'Single #End If #If Not 1D Then 'Double #End If #If Not 1UI Then 'unsigned Integer #End If #If Not 1UL Then 'unsigned Long #End If Module Module1 Sub main() End Sub End Module Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(compilationDef) compilation.VerifyDiagnostics() End Sub Public Sub Test_UnaryOperatorsInvalid() 'Added for Code Coverage Dim compilationDef = _ Imports System Imports Microsoft.VisualBasic #If -"1"c Then #End If #If +"1" Then #End If #If +" "c Then #End If #If +"test"$ Then #End If #If Not " "c Then #End If #If NOT "test"$ Then #End If #If - Then #End If #If + Then #End If #If NOT Then #End If Module Module1 Sub main() End Sub End Module Dim compilation = CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime(compilationDef) compilation.VerifyDiagnostics() 'TODO add the appropriate errors once bug is fixed End Sub Sub TestInvalidModuleScenario_AddingTreesWithImplementsAndInherits() 'Verifies we can hit the inheritable and implements slots on module blocks through usage of the AddInherits/AddImplements methods in the ModuleBlockSyntax. ' Although Modules do not support inheritance or Implements Dim SourceText = Module Module1 Sub Main End Sub End Module Module Module2 End Module Module Module3 End Module Interface IFoo End Interface Dim text = SourceText.Value 'Construct a SyntaxList and verify the bounds exceptions Dim tree = VisualBasicSyntaxTree.ParseText(text) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) 'We want to insert a Implements clause or Implements into Modules Dim Module1 = CType(Root.Members(0), ModuleBlockSyntax) Dim Module2 = CType(Root.Members(1), ModuleBlockSyntax) Dim Module3 = CType(Root.Members(2), ModuleBlockSyntax) Assert.Equal(0, Root.GetDiagnostics().Count) Dim bldr = SeparatedSyntaxListBuilder(Of TypeSyntax).Create() bldr.Add(CreateSimpleTypeName("aaa")) Dim sepList = bldr.ToList Dim statement = SyntaxFactory.InheritsStatement(SyntaxFactory.Token(SyntaxKind.InheritsKeyword, trailing:=spaceTrivia), sepList) Module2 = Module2.AddInherits(statement) Root = Root.ReplaceNode(Root.Members(1), Module2) Assert.Equal(0, Root.GetDiagnostics().Count) Dim bldr2 = SeparatedSyntaxListBuilder(Of TypeSyntax).Create() bldr2.Add(CreateSimpleTypeName("Ifoo")) Dim sepList2 = bldr2.ToList Dim statement2 = SyntaxFactory.ImplementsStatement(SyntaxFactory.Token(SyntaxKind.ImplementsKeyword, trailing:=spaceTrivia), sepList2) Module3 = Module3.AddImplements(statement2) Root = Root.ReplaceNode(Root.Members(2), Module3) Assert.Equal(0, Root.GetDiagnostics().Count) ' No updated diagnostics until the re-parsing '//Verify the syntax Tree contains strings Assert.True(Root.ToFullString.Contains("Inherits aaa")) Assert.True(Root.ToFullString.Contains("Implements Ifoo")) Dim compilationDef = _ <%= root.ToFullString %> 'Verify Compile Errors when try to use CompilationUtils.CreateCompilationWithMscorlibAndVBRuntime( compilationDef, New VisualBasicCompilationOptions(OutputKind.ConsoleApplication).WithOptionStrict(OptionStrict.Custom)).VerifyDiagnostics(BasicTestBase.Diagnostic(ERRID.ERR_ModuleCantInherit, "Inherits aaa"), BasicTestBase.Diagnostic(ERRID.ERR_ModuleCantImplement, "Implements Ifoo")) End Sub Sub TestSyntaxNode_GetDirectivesMultiplePresent() Dim SourceText = Imports System Imports Microsoft.VisualBasic Module Module1 Sub Main End Sub End Module #if True then Module Module2 End Module #End If #if False then Module Module3 End Module #End IF Dim text = SourceText.Value Dim tree = VisualBasicSyntaxTree.ParseText(text) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) Dim x = Root.GetDirectives() Assert.Equal(4, x.Count) Assert.Equal("#if True then", x(0).GetText.ToString.TrimEnd) Assert.Equal("Microsoft.CodeAnalysis.VisualBasic.Syntax.IfDirectiveTriviaSyntax", x(0).GetType.ToString) End Sub Sub TestSyntaxNode_GetDirectivesNonePresent() Dim SourceText = Imports System Imports Microsoft.VisualBasic Module Module1 Sub Main End Sub End Module Module Module2 End Module Module Module3 End Module Dim text = SourceText.Value Dim tree = VisualBasicSyntaxTree.ParseText(text) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) Dim x = Root.GetDirectives() Assert.Equal(0, x.Count) End Sub Sub TestSyntaxNode_GetDirectivesIncorrectUnbalanced() Dim SourceText = Imports System Imports Microsoft.VisualBasic Module Module1 Sub Main End Sub End Module #if True then Module Module2 End Module Module Module3 End Module Dim text = SourceText.Value Dim tree = VisualBasicSyntaxTree.ParseText(text) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) Dim x = Root.GetDirectives() Assert.Equal(1, x.Count) End Sub #Region "Equality Verifications" Sub Test_GlobalImportsEqual() Dim SourceText = Imports System Imports Microsoft.VisualBasic Module Module1 Sub Main End Sub End Module #if True then Module Module2 End Module Module Module3 End Module Dim text = SourceText.Value Dim tree = VisualBasicSyntaxTree.ParseText(text) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) Dim x = Root.GetDirectives() Assert.Equal(1, x.Count) End Sub Public Sub Test_GlobalImports_Equals() Dim SourceText = Imports System Module Module1 Sub Main Dim a as Integer = 1 Console.Writeline(a) End Sub End Module Dim tree = VisualBasicSyntaxTree.ParseText(SourceText.ToString) Dim Root As CompilationUnitSyntax = CType(tree.GetRoot(), CompilationUnitSyntax) Dim FirstImportsClause As ImportsStatementSyntax = Root.Imports(0) Dim Obj1 As New GlobalImport(FirstImportsClause.ImportsClauses(0), "ttt") Dim Obj2 As New GlobalImport(FirstImportsClause.ImportsClauses(0), "uuu") Dim obj3 As GlobalImport = Obj1 Assert.Equal(Obj1, obj3) Assert.NotEqual(Obj1, Obj2) If Obj1 = Obj2 Then Assert.True(False, "GlobalImports equal Failure") End If If Obj1 <> obj3 Then Assert.True(False, "GlobalImports Not equal Failure") End If End Sub Public Sub Test_CompilationOptions_Equals() Dim compilation = CreateCompilationWithMscorlibAndVBRuntime( Option Strict On Option Infer On Option Explicit On Option Compare Text , OptionsDll.WithOptionStrict(OptionStrict.Custom).WithOptionInfer(False).WithOptionExplicit(True).WithOptionCompareText(False)) Dim compilation2 = CreateCompilationWithMscorlibAndVBRuntime( Option Strict On Option Infer On Option Explicit On Option Compare Text , OptionsDll.WithOptionStrict(OptionStrict.Custom).WithOptionInfer(False).WithOptionExplicit(False).WithOptionCompareText(False)) Dim Compilation3 = CreateCompilationWithMscorlibAndVBRuntime( Option Strict On Option Infer On Option Explicit On Option Compare Text , OptionsDll.WithOptionStrict(OptionStrict.Custom).WithOptionInfer(False).WithOptionExplicit(True).WithOptionCompareText(False)) Dim vbpo1 = compilation.Options Dim vbpo2 = compilation2.Options Dim vbpo3 = Compilation3.Options Assert.Equal(vbpo1, vbpo1) Assert.Equal(vbpo1, vbpo3) Assert.NotEqual(vbpo1, vbpo2) Dim Objvbpo1 As Object = vbpo3 Assert.Equal(vbpo1, Objvbpo1) Dim compilation4 = CreateCompilationWithMscorlibAndVBRuntime( Option Strict Off Module Module1 Sub Main End Sub End Module , OptionsDll.WithOptionStrict(OptionStrict.Custom).WithOptionInfer(False).WithOptionExplicit(True).WithOptionCompareText(False)) vbpo1 = compilation4.Options Dim ObjCommonCompilationOptions As CompilationOptions = vbpo1 Dim RetValue = ObjCommonCompilationOptions.Equals(ObjectDisplay.NullLiteral) Assert.False(RetValue) End Sub Public Sub Test_ParseOptions_Equals() Dim po1 = New VisualBasicParseOptions(languageVersion:=LanguageVersion.VisualBasic10) Dim po2 = New VisualBasicParseOptions(languageVersion:=LanguageVersion.VisualBasic9) Dim po3 = New VisualBasicParseOptions(languageVersion:=LanguageVersion.VisualBasic10) Dim POcompilation1 = CompilationUtils.CreateCompilationWithMscorlib( , parseOptions:=po1) Assert.Equal(po1, po1) Assert.Equal(po1, po3) Assert.NotEqual(po1, po2) Dim Objpo1 As Object = po3 Assert.Equal(po1, Objpo1) End Sub #End Region #Region "SyntaxWalker Verification Tests For Specific Node Types" Public Sub SyntaxWalkerMethod_VerifyGroupByClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub main() Dim words = New String() {"blueberry", "chimpanzee", "abacus", "banana", "apple", "cheese"} Dim wordGroups = From w In words _ Group w By Key = w(0) Into Group _ Select FirstLetter = Key, WordGroup = Group End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.GroupByClause.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyCatchFilterClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub Main() Try Catch ex As Exception When TypeOf (ex) Is ArgumentException Catch ex As Exception End Try End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.CatchFilterClause.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyDistinctClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub Main() Dim q = From c In {1, 2, 3, 4, 5, 3, 2} Select c Distinct End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.DistinctClause.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyCaseRange() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub Main() Dim number As Integer = 8 Select Case number Case 1 To 5 Case Else End Select End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.RangeCaseClause.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyHandlesClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Public Class ContainerClass ' Module or class level declaration. WithEvents Obj As New Class1 Public Class Class1 ' Declare an event. Public Event Ev_Event() Sub CauseSomeEvent() ' Raise an event. RaiseEvent Ev_Event() End Sub End Class Sub EventHandler() Handles Obj.Ev_Event ' Handle the event. End Sub ' Call the TestEvents procedure from an instance of the ContainerClass ' class to test the Ev_Event event and the event handler. Public Sub TestEvents() Obj.CauseSomeEvent() End Sub End Class ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.HandlesClause.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.HandlesClauseItem.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.WithEventsEventContainer.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyKeywordEventContainerSyntax() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Module Module1 Sub Main() End Sub End Module Class ContainerClass WithEvents obj As New Class1 Public Class Class1 Public Event ev_events() Public Sub causeEvent() RaiseEvent ev_events() End Sub Sub EventHandlerInClass1() Handles Me.ev_events End Sub End Class End Class ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.KeywordEventContainer.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyOmmittedArgument() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Module Module1 Sub Main() foo(1, , 2) End Sub Sub foo(x As Integer, Optional y As Integer = 2, Optional z As Integer = 2) End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.OmittedArgument.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyMidExpressionClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub Main() Dim s As String = "abcdef" Mid(s, 2, 1) = "Z" Dim s2 As String = "" s2 = Mid(s, 2, 1) End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.MidExpression.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyAggregateClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub main() Dim words() = {"cherry", "apple", "blueberry", "cherry"} Dim ag1 = aggregate w in words where w = "cherry" into count End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.AggregateClause.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyDirectives() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Imports System.Collections.Generic Imports System.Linq #ExternalChecksum ("Test.vb", "{12345678-1234-1234-1234-123456789abc}", "1a2b3c4e5f617239a49b9a9c0391849d34950f923fab9484") Module Program #Const a = 1 Sub Main(args As String()) #ExternalSource ("test.txt", 1) #End ExternalSource #If a = 1 Then #ElseIf a = 2 Then #Else #End If End Sub #Region "Test" Sub Foo() End Sub #End Region End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier(SyntaxWalkerDepth.StructuredTrivia) collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.ConstDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.IfDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.ElseIfDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.ElseDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.ExternalSourceDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.EndExternalSourceDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.ExternalChecksumDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.RegionDirectiveTrivia.ToString)) Assert.Equal(1, collector.GetCount(SyntaxKind.EndRegionDirectiveTrivia.ToString)) End Sub Public Sub SyntaxWalkerMethod_VerifyPartitionClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub Main() Dim numbers() = {5, 4, 1, 3, 9, 8, 6, 7, 2, 0} Dim first3Numbers = from w in numbers Take(3) End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount("PartitionClauseSyntax")) End Sub Public Sub SyntaxWalkerMethod_VerifyPartitionWhileClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Module Module1 Sub Main() Dim numbers() = {5, 4, 1, 3, 9, 8, 6, 7, 2, 0} Dim laterNumbers = from n in numbers Take While(3) Select i End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount("PartitionWhileClauseSyntax")) End Sub Public Sub SyntaxWalkerMethod_VerifyRangeArgument() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Module Module1 Sub Main() ReDim myarray(0 to 10) ' Resize to 11 elements. End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.RangeArgument.ToString)) End Sub Public Sub SyntaxWalkerMehhod_VerifyXMLBracketName() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Module Module1 Sub Main() Dim x = <Foo> <Bar>1</Foo> </Foo> Dim y = x.<Foo>.<Bar>.Value End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(2, collector.GetCount(SyntaxKind.XmlBracketedName.ToString)) End Sub Public Sub SyntaxWalkerMehthod_VerifyImcompleteSyntaxClause() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( <Dim:clscompliant(true)> Module Module1 End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.IncompleteMember.ToString)) End Sub Public Sub SyntaxWalkerMehthod_VerifySkippedTokenTriva() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( OptImports System Module Module1 Sub main End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier(SyntaxWalkerDepth.StructuredTrivia) collector.Visit(root) Assert.Equal(1, collector.GetCount(SyntaxKind.SkippedTokensTrivia.ToString)) End Sub Public Sub SyntaxWalkerMehthod_VerifyInferredFieldName() Dim Compilation = CreateCompilationWithMscorlibAndVBRuntime( Imports System Module Module1 Sub Main() Dim productName As String = "paperclips" Dim productPrice As Double = 1.29 Dim anonProduct = New With {Key productName, Key productPrice} End Sub End Module ) Dim tree = Compilation.SyntaxTrees(0) Dim root = tree.GetCompilationUnitRoot() Dim collector = New SyntaxWalkerVerifier() collector.Visit(root) Assert.Equal(2, collector.GetCount(SyntaxKind.InferredFieldInitializer.ToString)) End Sub #End Region End Class End Namespace