File: Syntax\SyntaxNodeFactories.vb
Web Access
Project: src\src\Compilers\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.vbproj (Microsoft.CodeAnalysis.VisualBasic)
' Licensed to the .NET Foundation under one or more agreements.
' The .NET Foundation licenses this file to you under the MIT license.
' See the LICENSE file in the project root for more information.
 
'-----------------------------------------------------------------------------------------------------------
' Contains hand-written factories for the SyntaxNodes. Most factories are
' code-generated into SyntaxNodes.vb, but some are easier to hand-write.
'-----------------------------------------------------------------------------------------------------------
 
Imports System.Threading
Imports System.Text
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.VisualBasic.SyntaxFacts
Imports InternalSyntax = Microsoft.CodeAnalysis.VisualBasic.Syntax.InternalSyntax
Imports Microsoft.CodeAnalysis.Syntax
Imports System.Collections.Immutable
Imports System.ComponentModel
 
Namespace Microsoft.CodeAnalysis.VisualBasic
 
    Partial Public Class SyntaxFactory
 
#Region "ParseMethods"
 
        ' direct access to parsing for common grammar areas
 
        ''' <summary>
        ''' Create a new syntax tree from a syntax node.
        ''' </summary>
        Public Shared Function SyntaxTree(
            root As SyntaxNode,
            Optional options As ParseOptions = Nothing,
            Optional path As String = "",
            Optional encoding As Encoding = Nothing) As SyntaxTree
 
            Return VisualBasicSyntaxTree.Create(DirectCast(root, VisualBasicSyntaxNode), If(DirectCast(options, VisualBasicParseOptions), VisualBasicParseOptions.Default), path, encoding, SourceHashAlgorithm.Sha1)
        End Function
 
        ''' <summary>
        ''' Produces a syntax tree by parsing the source text.
        ''' </summary>
        Public Shared Function ParseSyntaxTree(
            text As String,
            options As ParseOptions,
            path As String,
            encoding As Encoding,
            cancellationToken As CancellationToken) As SyntaxTree
 
            Return ParseSyntaxTree(SourceText.From(text, encoding, SourceHashAlgorithm.Sha1), options, path, cancellationToken)
        End Function
 
        ''' <summary>
        ''' Produces a syntax tree by parsing the source text.
        ''' </summary>
        Public Shared Function ParseSyntaxTree(
            text As SourceText,
            options As ParseOptions,
            path As String,
            cancellationToken As CancellationToken) As SyntaxTree
 
            Return VisualBasicSyntaxTree.ParseText(text, DirectCast(options, VisualBasicParseOptions), path, cancellationToken)
        End Function
 
#Disable Warning RS0026 ' Do not add multiple public overloads with optional parameters.
#Disable Warning RS0027 ' Public API with optional parameter(s) should have the most parameters amongst its public overloads.
 
        ''' <summary>
        ''' Produces a syntax tree by parsing the source text.
        ''' </summary>
        Public Shared Function ParseSyntaxTree(
            text As String,
            Optional options As ParseOptions = Nothing,
            Optional path As String = "",
            Optional encoding As Encoding = Nothing,
            Optional diagnosticOptions As ImmutableDictionary(Of String, ReportDiagnostic) = Nothing,
            Optional cancellationToken As CancellationToken = Nothing) As SyntaxTree
 
            Return ParseSyntaxTree(SourceText.From(text, encoding), options, path, diagnosticOptions, cancellationToken)
        End Function
 
        ''' <summary>
        ''' Produces a syntax tree by parsing the source text.
        ''' </summary>
        Public Shared Function ParseSyntaxTree(
            text As SourceText,
            Optional options As ParseOptions = Nothing,
            Optional path As String = "",
            Optional diagnosticOptions As ImmutableDictionary(Of String, ReportDiagnostic) = Nothing,
            Optional cancellationToken As CancellationToken = Nothing) As SyntaxTree
 
            Return VisualBasicSyntaxTree.ParseText(text, DirectCast(options, VisualBasicParseOptions), path, diagnosticOptions, cancellationToken)
        End Function
 
#Enable Warning RS0026 ' Do not add multiple public overloads with optional parameters.
#Enable Warning RS0027 ' Public API with optional parameter(s) should have the most parameters amongst its public overloads.
 
        ''' <summary>
        '''Parse the input for leading trivia.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseLeadingTrivia(text As String, Optional offset As Integer = 0) As SyntaxTriviaList
            Dim s = New InternalSyntax.Scanner(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
            Using s
                Return New SyntaxTriviaList(Nothing, s.ScanMultilineTrivia().Node, 0, 0)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse the input for trailing trivia.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseTrailingTrivia(text As String, Optional offset As Integer = 0) As SyntaxTriviaList
            Dim s = New InternalSyntax.Scanner(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
            Using s
                Return New SyntaxTriviaList(Nothing, s.ScanSingleLineTrivia().Node, 0, 0)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse one token.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        ''' <param name="startStatement">Scan using rules for the start of a statement</param>
        Public Shared Function ParseToken(text As String, Optional offset As Integer = 0, Optional startStatement As Boolean = False) As SyntaxToken
            Dim s = New InternalSyntax.Scanner(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
            Using s
                Dim state = If(startStatement,
                               InternalSyntax.ScannerState.VBAllowLeadingMultilineTrivia,
                               InternalSyntax.ScannerState.VB)
                s.GetNextTokenInState(state)
                Return New SyntaxToken(Nothing, s.GetCurrentToken, 0, 0)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse tokens in the input.
        ''' Since this API does not create a <see cref="SyntaxNode"/> that owns all produced tokens,
        ''' the <see cref="SyntaxToken.GetLocation"/> API may yield surprising results for
        ''' the produced tokens and its behavior is generally unspecified.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        ''' <param name="initialTokenPosition">The position of the first token</param>
        Public Shared Iterator Function ParseTokens(text As String,
                                                    Optional offset As Integer = 0,
                                                    Optional initialTokenPosition As Integer = 0,
                                                    Optional options As VisualBasicParseOptions = Nothing) As IEnumerable(Of SyntaxToken)
 
            Using parser = New InternalSyntax.Parser(MakeSourceText(text, offset), If(options, VisualBasicParseOptions.Default))
                Dim state = InternalSyntax.ScannerState.VBAllowLeadingMultilineTrivia
                Dim curTk As InternalSyntax.SyntaxToken
 
                Do
                    parser.GetNextToken(state)
                    curTk = parser.CurrentToken
 
                    Yield New SyntaxToken(Nothing, curTk, initialTokenPosition, 0)
 
                    initialTokenPosition += curTk.FullWidth
                    state = If(curTk.Kind = SyntaxKind.StatementTerminatorToken,
                               InternalSyntax.ScannerState.VBAllowLeadingMultilineTrivia,
                               InternalSyntax.ScannerState.VB)
 
                Loop While curTk.Kind <> SyntaxKind.EndOfFileToken
            End Using
        End Function
 
        ''' <summary>
        ''' Parse a name.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseName(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As NameSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
                p.GetNextToken()
                ' "allow everything" arguments
                Dim node = p.ParseName(
                        requireQualification:=False,
                        allowGlobalNameSpace:=True,
                        allowGenericArguments:=True,
                        allowGenericsWithoutOf:=False,
                        disallowGenericArgumentsOnLastQualifiedName:=False,
                        allowEmptyGenericArguments:=True,
                        allowedEmptyGenericArguments:=True)
                Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), NameSyntax)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse a type name.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseTypeName(text As String, Optional offset As Integer = 0, Optional options As ParseOptions = Nothing, Optional consumeFullText As Boolean = True) As TypeSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), If(DirectCast(options, VisualBasicParseOptions), VisualBasicParseOptions.Default))
                p.GetNextToken()
                Dim node = p.ParseGeneralType()
                Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), TypeSyntax)
            End Using
        End Function
 
        '' Backcompat overload, do not touch
        ''' <summary>
        ''' Parse a type name.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        <EditorBrowsable(EditorBrowsableState.Never)>
        Public Shared Function ParseTypeName(text As String, offset As Integer, consumeFullText As Boolean) As TypeSyntax
            Return ParseTypeName(text, offset, options:=Nothing, consumeFullText)
        End Function
 
        ''' <summary>
        ''' Parse an expression.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseExpression(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As ExpressionSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
                p.GetNextToken()
                Dim node = p.ParseExpression()
                Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), ExpressionSyntax)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse an executable statement.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseExecutableStatement(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As StatementSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
                Dim node = p.ParseExecutableStatement()
                Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), StatementSyntax)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse a compilation unit (a single source file).
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseCompilationUnit(text As String, Optional offset As Integer = 0, Optional options As VisualBasicParseOptions = Nothing) As CompilationUnitSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), If(options, VisualBasicParseOptions.Default))
                Return DirectCast(p.ParseCompilationUnit().CreateRed(Nothing, 0), CompilationUnitSyntax)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse a parameter list.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseParameterList(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As ParameterListSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
                p.GetNextToken()
                Dim node = p.ParseParameterList()
                Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), ParameterListSyntax)
            End Using
        End Function
 
        ''' <summary>
        ''' Parse an argument list.
        ''' </summary>
        ''' <param name="text">The input string</param>
        ''' <param name="offset">The starting offset in the string</param>
        Public Shared Function ParseArgumentList(text As String, Optional offset As Integer = 0, Optional consumeFullText As Boolean = True) As ArgumentListSyntax
            Using p = New InternalSyntax.Parser(MakeSourceText(text, offset), VisualBasicParseOptions.Default)
                p.GetNextToken()
                Dim node = p.ParseParenthesizedArguments()
                Return DirectCast(If(consumeFullText, p.ConsumeUnexpectedTokens(node), node).CreateRed(Nothing, 0), ArgumentListSyntax)
            End Using
        End Function
 
        ''' <summary>
        ''' Helper method for wrapping a string and offset in a SourceText.
        ''' </summary>
        Friend Shared Function MakeSourceText(text As String, offset As Integer) As SourceText
            Return SourceText.From(text, Encoding.UTF8).GetSubText(offset)
        End Function
 
        ''' <summary>
        ''' Try parse the attribute represented as a stand-alone string like [cref="A.B"] and recognize 
        ''' 'cref' and 'name' attributes like in documentation-comment mode. This method should only be
        '''  used internally from code handling documentation comment includes.
        ''' </summary>
        Friend Shared Function ParseDocCommentAttributeAsStandAloneEntity(text As String, parentElementName As String) As BaseXmlAttributeSyntax
            Using scanner As New InternalSyntax.Scanner(MakeSourceText(text, 0), VisualBasicParseOptions.Default) ' NOTE: Default options should be enough
                scanner.ForceScanningXmlDocMode()
 
                Dim parser = New InternalSyntax.Parser(scanner)
                parser.GetNextToken(InternalSyntax.ScannerState.Element)
 
                Dim xmlName = InternalSyntax.SyntaxFactory.XmlName(
                    Nothing, InternalSyntax.SyntaxFactory.XmlNameToken(parentElementName, SyntaxKind.XmlNameToken, Nothing, Nothing))
 
                Return DirectCast(
                    parser.ParseXmlAttribute(
                        requireLeadingWhitespace:=False,
                        AllowNameAsExpression:=False,
                        xmlElementName:=xmlName).CreateRed(Nothing, 0), BaseXmlAttributeSyntax)
            End Using
        End Function
 
#End Region
 
#Region "TokenFactories"
        Public Shared Function IntegerLiteralToken(text As String, base As LiteralBase, typeSuffix As TypeCharacter, value As ULong) As SyntaxToken
            Return IntegerLiteralToken(SyntaxFactory.TriviaList(ElasticMarker), text, base, typeSuffix, value, SyntaxFactory.TriviaList(ElasticMarker))
        End Function
 
        Public Shared Function IntegerLiteralToken(leadingTrivia As SyntaxTriviaList, text As String, base As LiteralBase, typeSuffix As TypeCharacter, value As ULong, trailingTrivia As SyntaxTriviaList) As SyntaxToken
            If text Is Nothing Then
                Throw New ArgumentNullException(NameOf(text))
            End If
 
            Return New SyntaxToken(Nothing, InternalSyntax.SyntaxFactory.IntegerLiteralToken(text, base, typeSuffix, value, leadingTrivia.Node, trailingTrivia.Node), 0, 0)
        End Function
 
        Public Shared Function FloatingLiteralToken(text As String, typeSuffix As TypeCharacter, value As Double) As SyntaxToken
            Return FloatingLiteralToken(SyntaxFactory.TriviaList(ElasticMarker), text, typeSuffix, value, SyntaxFactory.TriviaList(ElasticMarker))
        End Function
 
        Public Shared Function FloatingLiteralToken(leadingTrivia As SyntaxTriviaList, text As String, typeSuffix As TypeCharacter, value As Double, trailingTrivia As SyntaxTriviaList) As SyntaxToken
            If text Is Nothing Then
                Throw New ArgumentNullException(NameOf(text))
            End If
 
            Return New SyntaxToken(Nothing, InternalSyntax.SyntaxFactory.FloatingLiteralToken(text, typeSuffix, value, leadingTrivia.Node, trailingTrivia.Node), 0, 0)
        End Function
 
        Public Shared Function Identifier(text As String, isBracketed As Boolean, identifierText As String, typeCharacter As TypeCharacter) As SyntaxToken
            Return Identifier(SyntaxFactory.TriviaList(ElasticMarker), text, isBracketed, identifierText, typeCharacter, SyntaxFactory.TriviaList(ElasticMarker))
        End Function
 
        Friend Shared Function Identifier(leadingTrivia As SyntaxTrivia, text As String, isBracketed As Boolean, identifierText As String, typeCharacter As TypeCharacter, trailingTrivia As SyntaxTrivia) As SyntaxToken
            Return Identifier(SyntaxTriviaList.Create(leadingTrivia), text, isBracketed, identifierText, typeCharacter, SyntaxTriviaList.Create(trailingTrivia))
        End Function
 
        Public Shared Function Identifier(leadingTrivia As SyntaxTriviaList, text As String, isBracketed As Boolean, identifierText As String, typeCharacter As TypeCharacter, trailingTrivia As SyntaxTriviaList) As SyntaxToken
            If text Is Nothing Then
                Throw New ArgumentException(NameOf(text))
            End If
 
            Return New SyntaxToken(Nothing, New InternalSyntax.ComplexIdentifierSyntax(SyntaxKind.IdentifierToken, Nothing, Nothing, text, leadingTrivia.Node, trailingTrivia.Node, SyntaxKind.IdentifierToken, isBracketed, identifierText, typeCharacter), 0, 0)
        End Function
 
        Public Shared Function Identifier(text As String) As SyntaxToken
            Return Identifier(SyntaxFactory.TriviaList(ElasticMarker), text, SyntaxFactory.TriviaList(ElasticMarker))
        End Function
 
        Friend Shared Function Identifier(leadingTrivia As SyntaxTrivia, text As String, trailingTrivia As SyntaxTrivia) As SyntaxToken
            Return Identifier(SyntaxTriviaList.Create(leadingTrivia), text, SyntaxTriviaList.Create(trailingTrivia))
        End Function
 
        Public Shared Function Identifier(leadingTrivia As SyntaxTriviaList, text As String, trailingTrivia As SyntaxTriviaList) As SyntaxToken
            If text Is Nothing Then
                Throw New ArgumentException(NameOf(text))
            End If
 
            Return New SyntaxToken(Nothing, New InternalSyntax.ComplexIdentifierSyntax(SyntaxKind.IdentifierToken, Nothing, Nothing, text, leadingTrivia.Node, trailingTrivia.Node, SyntaxKind.IdentifierToken, False, text, TypeCharacter.None), 0, 0)
        End Function
 
        ''' <summary>
        ''' Create a bracketed identifier.
        ''' </summary>
        Public Shared Function BracketedIdentifier(text As String) As SyntaxToken
            Return BracketedIdentifier(SyntaxFactory.TriviaList(ElasticMarker), text, SyntaxFactory.TriviaList(ElasticMarker))
        End Function
 
        ''' <summary>
        ''' Create a bracketed identifier.
        ''' </summary>
        Public Shared Function BracketedIdentifier(leadingTrivia As SyntaxTriviaList, text As String, trailingTrivia As SyntaxTriviaList) As SyntaxToken
            If text Is Nothing Then
                Throw New ArgumentException(NameOf(text))
            End If
 
            If MakeHalfWidthIdentifier(text.First) = "[" AndAlso MakeHalfWidthIdentifier(text.Last) = "]" Then
                Throw New ArgumentException(NameOf(text))
            End If
 
            Return New SyntaxToken(Nothing, New InternalSyntax.ComplexIdentifierSyntax(SyntaxKind.IdentifierToken, Nothing, Nothing, "[" + text + "]", leadingTrivia.Node, trailingTrivia.Node, SyntaxKind.IdentifierToken, True, text, TypeCharacter.None), 0, 0)
        End Function
 
        ''' <summary>
        ''' Create a missing identifier.
        ''' </summary>
        Friend Shared Function MissingIdentifier() As SyntaxToken
            Return New SyntaxToken(Nothing, New InternalSyntax.SimpleIdentifierSyntax(SyntaxKind.IdentifierToken, Nothing, Nothing, "",
                    ElasticMarker.UnderlyingNode, ElasticMarker.UnderlyingNode), 0, 0)
        End Function
 
        ''' <summary>
        ''' Create a missing contextual keyword.
        ''' </summary>
        Friend Shared Function MissingIdentifier(kind As SyntaxKind) As SyntaxToken
            Return New SyntaxToken(Nothing, New InternalSyntax.ComplexIdentifierSyntax(SyntaxKind.IdentifierToken, Nothing, Nothing, "",
                    ElasticMarker.UnderlyingNode, ElasticMarker.UnderlyingNode,
                    kind, False, "", TypeCharacter.None), 0, 0)
        End Function
 
        ''' <summary>
        ''' Create a missing keyword.
        ''' </summary>
        Friend Shared Function MissingKeyword(kind As SyntaxKind) As SyntaxToken
            Return New SyntaxToken(Nothing, New InternalSyntax.KeywordSyntax(kind, "",
                    ElasticMarker.UnderlyingNode, ElasticMarker.UnderlyingNode), 0, 0)
        End Function
 
        ''' <summary>
        ''' Create a missing punctuation mark.
        ''' </summary>
        Friend Shared Function MissingPunctuation(kind As SyntaxKind) As SyntaxToken
            Return New SyntaxToken(Nothing, New InternalSyntax.PunctuationSyntax(kind, "",
                    ElasticMarker.UnderlyingNode, ElasticMarker.UnderlyingNode), 0, 0)
        End Function
 
        ''' <summary>
        ''' Create a missing string literal.
        ''' </summary>
        Friend Shared Function MissingStringLiteral() As SyntaxToken
            Return SyntaxFactory.StringLiteralToken("", "")
        End Function
 
        ''' <summary>
        ''' Create a missing character literal.
        ''' </summary>
        Friend Shared Function MissingCharacterLiteralToken() As SyntaxToken
            Return CharacterLiteralToken("", Nothing)
        End Function
 
        ''' <summary>
        ''' Create a missing integer literal.
        ''' </summary>
        Friend Shared Function MissingIntegerLiteralToken() As SyntaxToken
            Return IntegerLiteralToken(SyntaxFactory.TriviaList(ElasticMarker), "", LiteralBase.Decimal, TypeCharacter.None, Nothing, SyntaxFactory.TriviaList(ElasticMarker))
        End Function
 
        ''' <summary>
        ''' Creates a copy of a token.
        ''' <para name="err"></para>
        ''' <para name="trivia"></para>
        ''' </summary>
        ''' <returns>The new token</returns>
        Friend Shared Function MissingToken(kind As SyntaxKind) As SyntaxToken
            Dim t As SyntaxToken
 
            Select Case kind
                Case SyntaxKind.StatementTerminatorToken
                    t = SyntaxFactory.Token(SyntaxKind.StatementTerminatorToken)
 
                Case SyntaxKind.EndOfFileToken
                    t = SyntaxFactory.Token(SyntaxKind.EndOfFileToken)
 
                Case SyntaxKind.AddHandlerKeyword,
                SyntaxKind.AddressOfKeyword,
                SyntaxKind.AliasKeyword,
                SyntaxKind.AndKeyword,
                SyntaxKind.AndAlsoKeyword,
                SyntaxKind.AsKeyword,
                SyntaxKind.BooleanKeyword,
                SyntaxKind.ByRefKeyword,
                SyntaxKind.ByteKeyword,
                SyntaxKind.ByValKeyword,
                SyntaxKind.CallKeyword,
                SyntaxKind.CaseKeyword,
                SyntaxKind.CatchKeyword,
                SyntaxKind.CBoolKeyword,
                SyntaxKind.CByteKeyword,
                SyntaxKind.CCharKeyword,
                SyntaxKind.CDateKeyword,
                SyntaxKind.CDecKeyword,
                SyntaxKind.CDblKeyword,
                SyntaxKind.CharKeyword,
                SyntaxKind.CIntKeyword,
                SyntaxKind.ClassKeyword,
                SyntaxKind.CLngKeyword,
                SyntaxKind.CObjKeyword,
                SyntaxKind.ConstKeyword,
                SyntaxKind.ContinueKeyword,
                SyntaxKind.CSByteKeyword,
                SyntaxKind.CShortKeyword,
                SyntaxKind.CSngKeyword,
                SyntaxKind.CStrKeyword,
                SyntaxKind.CTypeKeyword,
                SyntaxKind.CUIntKeyword,
                SyntaxKind.CULngKeyword,
                SyntaxKind.CUShortKeyword,
                SyntaxKind.DateKeyword,
                SyntaxKind.DecimalKeyword,
                SyntaxKind.DeclareKeyword,
                SyntaxKind.DefaultKeyword,
                SyntaxKind.DelegateKeyword,
                SyntaxKind.DimKeyword,
                SyntaxKind.DirectCastKeyword,
                SyntaxKind.DoKeyword,
                SyntaxKind.DoubleKeyword,
                SyntaxKind.EachKeyword,
                SyntaxKind.ElseKeyword,
                SyntaxKind.ElseIfKeyword,
                SyntaxKind.EndKeyword,
                SyntaxKind.EnumKeyword,
                SyntaxKind.EraseKeyword,
                SyntaxKind.ErrorKeyword,
                SyntaxKind.EventKeyword,
                SyntaxKind.ExitKeyword,
                SyntaxKind.FalseKeyword,
                SyntaxKind.FinallyKeyword,
                SyntaxKind.ForKeyword,
                SyntaxKind.FriendKeyword,
                SyntaxKind.FunctionKeyword,
                SyntaxKind.GetKeyword,
                SyntaxKind.GetTypeKeyword,
                SyntaxKind.GetXmlNamespaceKeyword,
                SyntaxKind.GlobalKeyword,
                SyntaxKind.GoToKeyword,
                SyntaxKind.HandlesKeyword,
                SyntaxKind.IfKeyword,
                SyntaxKind.ImplementsKeyword,
                SyntaxKind.ImportsKeyword,
                SyntaxKind.InKeyword,
                SyntaxKind.InheritsKeyword,
                SyntaxKind.IntegerKeyword,
                SyntaxKind.InterfaceKeyword,
                SyntaxKind.IsKeyword,
                SyntaxKind.IsNotKeyword,
                SyntaxKind.LetKeyword,
                SyntaxKind.LibKeyword,
                SyntaxKind.LikeKeyword,
                SyntaxKind.LongKeyword,
                SyntaxKind.LoopKeyword,
                SyntaxKind.MeKeyword,
                SyntaxKind.ModKeyword,
                SyntaxKind.ModuleKeyword,
                SyntaxKind.MustInheritKeyword,
                SyntaxKind.MustOverrideKeyword,
                SyntaxKind.MyBaseKeyword,
                SyntaxKind.MyClassKeyword,
                SyntaxKind.NameOfKeyword,
                SyntaxKind.NamespaceKeyword,
                SyntaxKind.NarrowingKeyword,
                SyntaxKind.NextKeyword,
                SyntaxKind.NewKeyword,
                SyntaxKind.NotKeyword,
                SyntaxKind.NothingKeyword,
                SyntaxKind.NotInheritableKeyword,
                SyntaxKind.NotOverridableKeyword,
                SyntaxKind.ObjectKeyword,
                SyntaxKind.OfKeyword,
                SyntaxKind.OnKeyword,
                SyntaxKind.OperatorKeyword,
                SyntaxKind.OptionKeyword,
                SyntaxKind.OptionalKeyword,
                SyntaxKind.OrKeyword,
                SyntaxKind.OrElseKeyword,
                SyntaxKind.OverloadsKeyword,
                SyntaxKind.OverridableKeyword,
                SyntaxKind.OverridesKeyword,
                SyntaxKind.ParamArrayKeyword,
                SyntaxKind.PartialKeyword,
                SyntaxKind.PrivateKeyword,
                SyntaxKind.PropertyKeyword,
                SyntaxKind.ProtectedKeyword,
                SyntaxKind.PublicKeyword,
                SyntaxKind.RaiseEventKeyword,
                SyntaxKind.ReadOnlyKeyword,
                SyntaxKind.ReDimKeyword,
                SyntaxKind.ReferenceKeyword,
                SyntaxKind.REMKeyword,
                SyntaxKind.RemoveHandlerKeyword,
                SyntaxKind.ResumeKeyword,
                SyntaxKind.ReturnKeyword,
                SyntaxKind.SByteKeyword,
                SyntaxKind.SelectKeyword,
                SyntaxKind.SetKeyword,
                SyntaxKind.ShadowsKeyword,
                SyntaxKind.SharedKeyword,
                SyntaxKind.ShortKeyword,
                SyntaxKind.SingleKeyword,
                SyntaxKind.StaticKeyword,
                SyntaxKind.StepKeyword,
                SyntaxKind.StopKeyword,
                SyntaxKind.StringKeyword,
                SyntaxKind.StructureKeyword,
                SyntaxKind.SubKeyword,
                SyntaxKind.SyncLockKeyword,
                SyntaxKind.ThenKeyword,
                SyntaxKind.ThrowKeyword,
                SyntaxKind.ToKeyword,
                SyntaxKind.TrueKeyword,
                SyntaxKind.TryKeyword,
                SyntaxKind.TryCastKeyword,
                SyntaxKind.TypeOfKeyword,
                SyntaxKind.UIntegerKeyword,
                SyntaxKind.ULongKeyword,
                SyntaxKind.UShortKeyword,
                SyntaxKind.UsingKeyword,
                SyntaxKind.WhenKeyword,
                SyntaxKind.WhileKeyword,
                SyntaxKind.WideningKeyword,
                SyntaxKind.WithKeyword,
                SyntaxKind.WithEventsKeyword,
                SyntaxKind.WriteOnlyKeyword,
                SyntaxKind.XorKeyword,
                SyntaxKind.EndIfKeyword,
                SyntaxKind.GosubKeyword,
                SyntaxKind.VariantKeyword,
                SyntaxKind.WendKeyword,
                SyntaxKind.OutKeyword
                    t = SyntaxFactory.MissingKeyword(kind)
 
                Case SyntaxKind.AggregateKeyword,
                SyntaxKind.AllKeyword,
                SyntaxKind.AnsiKeyword,
                SyntaxKind.AscendingKeyword,
                SyntaxKind.AssemblyKeyword,
                SyntaxKind.AutoKeyword,
                SyntaxKind.BinaryKeyword,
                SyntaxKind.ByKeyword,
                SyntaxKind.CompareKeyword,
                SyntaxKind.CustomKeyword,
                SyntaxKind.DescendingKeyword,
                SyntaxKind.DisableKeyword,
                SyntaxKind.DistinctKeyword,
                SyntaxKind.EnableKeyword,
                SyntaxKind.EqualsKeyword,
                SyntaxKind.ExplicitKeyword,
                SyntaxKind.ExternalSourceKeyword,
                SyntaxKind.ExternalChecksumKeyword,
                SyntaxKind.FromKeyword,
                SyntaxKind.GroupKeyword,
                SyntaxKind.InferKeyword,
                SyntaxKind.IntoKeyword,
                SyntaxKind.IsFalseKeyword,
                SyntaxKind.IsTrueKeyword,
                SyntaxKind.JoinKeyword,
                SyntaxKind.KeyKeyword,
                SyntaxKind.MidKeyword,
                SyntaxKind.OffKeyword,
                SyntaxKind.OrderKeyword,
                SyntaxKind.PreserveKeyword,
                SyntaxKind.RegionKeyword,
                SyntaxKind.SkipKeyword,
                SyntaxKind.StrictKeyword,
                SyntaxKind.TextKeyword,
                SyntaxKind.TakeKeyword,
                SyntaxKind.UnicodeKeyword,
                SyntaxKind.UntilKeyword,
                SyntaxKind.WarningKeyword,
                SyntaxKind.WhereKeyword
                    ' These are identifiers that have a contextual kind
                    Return SyntaxFactory.MissingIdentifier(kind)
 
                Case SyntaxKind.ExclamationToken,
                    SyntaxKind.CommaToken,
                    SyntaxKind.HashToken,
                    SyntaxKind.AmpersandToken,
                    SyntaxKind.SingleQuoteToken,
                    SyntaxKind.OpenParenToken,
                    SyntaxKind.CloseParenToken,
                    SyntaxKind.OpenBraceToken,
                    SyntaxKind.CloseBraceToken,
                    SyntaxKind.DoubleQuoteToken,
                    SyntaxKind.SemicolonToken,
                    SyntaxKind.AsteriskToken,
                    SyntaxKind.PlusToken,
                    SyntaxKind.MinusToken,
                    SyntaxKind.DotToken,
                    SyntaxKind.SlashToken,
                    SyntaxKind.ColonToken,
                    SyntaxKind.LessThanToken,
                    SyntaxKind.LessThanEqualsToken,
                    SyntaxKind.LessThanGreaterThanToken,
                    SyntaxKind.EqualsToken,
                    SyntaxKind.GreaterThanToken,
                    SyntaxKind.GreaterThanEqualsToken,
                    SyntaxKind.BackslashToken,
                    SyntaxKind.CaretToken,
                    SyntaxKind.ColonEqualsToken,
                    SyntaxKind.AmpersandEqualsToken,
                    SyntaxKind.AsteriskEqualsToken,
                    SyntaxKind.PlusEqualsToken,
                    SyntaxKind.MinusEqualsToken,
                    SyntaxKind.SlashEqualsToken,
                    SyntaxKind.BackslashEqualsToken,
                    SyntaxKind.CaretEqualsToken,
                    SyntaxKind.LessThanLessThanToken,
                    SyntaxKind.GreaterThanGreaterThanToken,
                    SyntaxKind.LessThanLessThanEqualsToken,
                    SyntaxKind.GreaterThanGreaterThanEqualsToken,
                    SyntaxKind.QuestionToken
                    t = SyntaxFactory.MissingPunctuation(kind)
 
                Case SyntaxKind.FloatingLiteralToken
                    t = SyntaxFactory.FloatingLiteralToken("", TypeCharacter.None, Nothing)
 
                Case SyntaxKind.DecimalLiteralToken
                    t = SyntaxFactory.DecimalLiteralToken("", TypeCharacter.None, Nothing)
 
                Case SyntaxKind.DateLiteralToken
                    t = SyntaxFactory.DateLiteralToken("", Nothing)
 
                Case SyntaxKind.XmlNameToken
                    t = SyntaxFactory.XmlNameToken("", SyntaxKind.XmlNameToken)
 
                Case SyntaxKind.XmlTextLiteralToken
                    t = SyntaxFactory.XmlTextLiteralToken("", "")
 
                Case SyntaxKind.SlashGreaterThanToken,
                    SyntaxKind.LessThanSlashToken,
                    SyntaxKind.LessThanExclamationMinusMinusToken,
                    SyntaxKind.MinusMinusGreaterThanToken,
                    SyntaxKind.LessThanQuestionToken,
                    SyntaxKind.QuestionGreaterThanToken,
                    SyntaxKind.LessThanPercentEqualsToken,
                    SyntaxKind.PercentGreaterThanToken,
                    SyntaxKind.BeginCDataToken,
                    SyntaxKind.EndCDataToken
                    t = SyntaxFactory.MissingPunctuation(kind)
 
                Case SyntaxKind.IdentifierToken
                    t = SyntaxFactory.MissingIdentifier()
 
                Case SyntaxKind.IntegerLiteralToken
                    t = MissingIntegerLiteralToken()
 
                Case SyntaxKind.StringLiteralToken
                    t = SyntaxFactory.MissingStringLiteral()
 
                Case SyntaxKind.CharacterLiteralToken
                    t = SyntaxFactory.MissingCharacterLiteralToken()
 
                Case Else
                    Throw ExceptionUtilities.UnexpectedValue(kind)
            End Select
            Return t
        End Function
 
        Public Shared Function BadToken(text As String) As SyntaxToken
            Return BadToken(Nothing, text, Nothing)
        End Function
 
        Public Shared Function BadToken(leadingTrivia As SyntaxTriviaList, text As String, trailingTrivia As SyntaxTriviaList) As SyntaxToken
            If text Is Nothing Then
                Throw New ArgumentException(NameOf(text))
            End If
            Return New SyntaxToken(Nothing, New InternalSyntax.BadTokenSyntax(SyntaxKind.BadToken, InternalSyntax.SyntaxSubKind.None, Nothing, Nothing, text,
                    leadingTrivia.Node, trailingTrivia.Node), 0, 0)
        End Function
 
#End Region
 
#Region "TriviaFactories"
 
        Public Shared Function Trivia(node As StructuredTriviaSyntax) As SyntaxTrivia
            Return New SyntaxTrivia(Nothing, node.Green, position:=0, index:=0)
        End Function
 
#End Region
 
#Region "ListFactories"
 
        ''' <summary>
        ''' Creates an empty list of syntax nodes.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        Public Shared Function List(Of TNode As SyntaxNode)() As SyntaxList(Of TNode)
            Return New SyntaxList(Of TNode)
        End Function
 
        ''' <summary>
        ''' Creates a singleton list of syntax nodes.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="node">The single element node.</param>
        Public Shared Function SingletonList(Of TNode As SyntaxNode)(node As TNode) As SyntaxList(Of TNode)
            Return New SyntaxList(Of TNode)(node)
        End Function
 
        ''' <summary>
        ''' Creates a list of syntax nodes.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="nodes">A sequence of element nodes.</param>
        Public Shared Function List(Of TNode As SyntaxNode)(nodes As IEnumerable(Of TNode)) As SyntaxList(Of TNode)
            Return New SyntaxList(Of TNode)(nodes)
        End Function
 
        ''' <summary>
        ''' Creates an empty list of tokens.
        ''' </summary>
        Public Shared Function TokenList() As SyntaxTokenList
            Return New SyntaxTokenList()
        End Function
 
        ''' <summary>
        ''' Creates a singleton list of tokens.
        ''' </summary>
        ''' <param name="token">The single token.</param>
        Public Shared Function TokenList(token As SyntaxToken) As SyntaxTokenList
            Return New SyntaxTokenList(token)
        End Function
 
        ''' <summary>
        ''' Creates a list of tokens.
        ''' </summary>
        ''' <param name="tokens">An array of tokens.</param>
        Public Shared Function TokenList(ParamArray tokens As SyntaxToken()) As SyntaxTokenList
            Return New SyntaxTokenList(tokens)
        End Function
 
        ''' <summary>
        ''' Creates a list of tokens.
        ''' </summary>
        ''' <param name="tokens"></param>
        Public Shared Function TokenList(tokens As IEnumerable(Of SyntaxToken)) As SyntaxTokenList
            Return New SyntaxTokenList(tokens)
        End Function
 
        ''' <summary>
        ''' Creates an empty list of trivia.
        ''' </summary>
        Public Shared Function TriviaList() As SyntaxTriviaList
            Return New SyntaxTriviaList()
        End Function
 
        ''' <summary>
        ''' Creates a singleton list of trivia.
        ''' </summary>
        ''' <param name="trivia">A single trivia.</param>
        Public Shared Function TriviaList(trivia As SyntaxTrivia) As SyntaxTriviaList
            Return New SyntaxTriviaList(Nothing, trivia.UnderlyingNode)
        End Function
 
        ''' <summary>
        ''' Creates a list of trivia.
        ''' </summary>
        ''' <param name="trivias">An array of trivia.</param>
        Public Shared Function TriviaList(ParamArray trivias As SyntaxTrivia()) As SyntaxTriviaList
            Return New SyntaxTriviaList(trivias)
        End Function
 
        ''' <summary>
        ''' Creates a list of trivia.
        ''' </summary>
        ''' <param name="trivias">A sequence of trivia.</param>
        Public Shared Function TriviaList(trivias As IEnumerable(Of SyntaxTrivia)) As SyntaxTriviaList
            Return New SyntaxTriviaList(trivias)
        End Function
 
        ''' <summary>
        ''' Creates an empty separated list.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        Public Shared Function SeparatedList(Of TNode As SyntaxNode)() As SeparatedSyntaxList(Of TNode)
            Return New SeparatedSyntaxList(Of TNode)
        End Function
 
        ''' <summary>
        ''' Creates a singleton separated list.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="node">A single node.</param>
        Public Shared Function SingletonSeparatedList(Of TNode As SyntaxNode)(node As TNode) As SeparatedSyntaxList(Of TNode)
            Return New SeparatedSyntaxList(Of TNode)(node, 0)
        End Function
 
        ''' <summary>
        ''' Creates a separated list of nodes from a sequence of nodes, synthesizing comma separators in between.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="nodes">A sequence of syntax nodes.</param>
        Public Shared Function SeparatedList(Of TNode As SyntaxNode)(nodes As IEnumerable(Of TNode)) As SeparatedSyntaxList(Of TNode)
            If nodes Is Nothing Then Return Nothing
 
            Dim collection = TryCast(nodes, ICollection(Of TNode))
 
            If collection IsNot Nothing AndAlso collection.Count = 0 Then Return Nothing
 
            Using enumerator = nodes.GetEnumerator()
                If Not enumerator.MoveNext() Then Return Nothing
 
                Dim firstNode = enumerator.Current
 
                If Not enumerator.MoveNext() Then Return SingletonSeparatedList(firstNode)
 
                Dim builder As New SeparatedSyntaxListBuilder(Of TNode)(If(collection IsNot Nothing, (collection.Count * 2) - 1, 3))
 
                builder.Add(firstNode)
 
                Dim commaToken = Token(SyntaxKind.CommaToken)
 
                Do
                    builder.AddSeparator(commaToken)
                    builder.Add(enumerator.Current)
                Loop While enumerator.MoveNext()
 
                Return builder.ToList()
            End Using
        End Function
 
        ''' <summary>
        ''' Creates a separated list of nodes from a sequence of nodes and a sequence of separator tokens.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="nodes">A sequence of syntax nodes.</param>
        ''' <param name="separators">A sequence of token to be interleaved between the nodes. The number of tokens must
        ''' be one less than the number of nodes.</param>
        Public Shared Function SeparatedList(Of TNode As SyntaxNode)(nodes As IEnumerable(Of TNode), separators As IEnumerable(Of SyntaxToken)) As SeparatedSyntaxList(Of TNode)
 
            If nodes IsNot Nothing Then
 
                Dim nodeEnum = nodes.GetEnumerator
                Dim builder = SeparatedSyntaxListBuilder(Of TNode).Create()
 
                If separators IsNot Nothing Then
 
                    For Each separator In separators
 
                        ' The number of nodes must be equal to or one greater than the number of separators
                        If nodeEnum.MoveNext() Then
                            builder.Add(nodeEnum.Current)
                        Else
                            Throw New ArgumentException()
                        End If
                        builder.AddSeparator(separator)
 
                    Next
 
                End If
 
                ' Check that there is zero or one node left in the enumerator
                If nodeEnum.MoveNext() Then
                    builder.Add(nodeEnum.Current)
 
                    If nodeEnum.MoveNext() Then
                        Throw New ArgumentException()
                    End If
                End If
 
                Return builder.ToList()
 
            ElseIf separators Is Nothing Then
                ' Both are nothing so return empty list
                Return New SeparatedSyntaxList(Of TNode)
            Else
                ' No nodes but have separators.  This is an argument error.
                Throw New ArgumentException()
            End If
 
        End Function
 
        ''' <summary>
        ''' Creates a separated list from a sequence of nodes or tokens.
        ''' The sequence must start with a node and alternate between nodes and separator tokens.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="nodesAndTokens">A alternating sequence of nodes and tokens.</param>
        Public Shared Function SeparatedList(Of TNode As SyntaxNode)(nodesAndTokens As IEnumerable(Of SyntaxNodeOrToken)) As SeparatedSyntaxList(Of TNode)
            Return SeparatedList(Of TNode)(NodeOrTokenList(nodesAndTokens))
        End Function
 
        ''' <summary>
        ''' Creates a separated list from a <see cref="SyntaxNodeOrTokenList"/>.
        ''' The <see cref="SyntaxNodeOrTokenList"/> must start with a node and alternate between nodes and separator tokens.
        ''' </summary>
        ''' <typeparam name="TNode">The specific type of the element nodes.</typeparam>
        ''' <param name="nodesAndTokens">An alternating list of nodes and tokens.</param>
        Public Shared Function SeparatedList(Of TNode As SyntaxNode)(nodesAndTokens As SyntaxNodeOrTokenList) As SeparatedSyntaxList(Of TNode)
            If Not HasSeparatedNodeTokenPattern(nodesAndTokens) Then
                Throw New ArgumentException(CodeAnalysisResources.NodeOrTokenOutOfSequence)
            End If
 
            If Not NodesAreCorrectType(Of TNode)(nodesAndTokens) Then
                Throw New ArgumentException(CodeAnalysisResources.UnexpectedTypeOfNodeInList)
            End If
 
            Return New SeparatedSyntaxList(Of TNode)(nodesAndTokens)
        End Function
 
        Private Shared Function NodesAreCorrectType(Of TNode)(list As SyntaxNodeOrTokenList) As Boolean
            Dim n = list.Count
            For i = 0 To n - 1
                Dim element = list(i)
                If element.IsNode AndAlso Not (TypeOf element.AsNode() Is TNode) Then
                    Return False
                End If
            Next
            Return True
        End Function
 
        Private Shared Function HasSeparatedNodeTokenPattern(list As SyntaxNodeOrTokenList) As Boolean
            For i = 0 To list.Count - 1
                Dim element = list(i)
                If element.IsToken = ((i And 1) = 0) Then
                    Return False
                End If
            Next
            Return True
        End Function
 
        ''' <summary>
        ''' Creates an empty <see cref="SyntaxNodeOrTokenList"/>.
        ''' </summary>
        Public Shared Function NodeOrTokenList() As SyntaxNodeOrTokenList
            Return Nothing
        End Function
 
        ''' <summary>
        ''' Creates a <see cref="SyntaxNodeOrTokenList"/> from a sequence of nodes and tokens.
        ''' </summary>
        ''' <param name="nodesAndTokens">A sequence of nodes and tokens.</param>
        Public Shared Function NodeOrTokenList(nodesAndTokens As IEnumerable(Of SyntaxNodeOrToken)) As SyntaxNodeOrTokenList
            Return New SyntaxNodeOrTokenList(nodesAndTokens)
        End Function
 
        ''' <summary>
        ''' Creates a <see cref="SyntaxNodeOrTokenList"/> from one or more nodes and tokens.
        ''' </summary>
        ''' <param name="nodesAndTokens">An array of nodes and tokens.</param>
        Public Shared Function NodeOrTokenList(ParamArray nodesAndTokens As SyntaxNodeOrToken()) As SyntaxNodeOrTokenList
            Return New SyntaxNodeOrTokenList(nodesAndTokens)
        End Function
 
#End Region
 
        Public Shared Function InvocationExpression(expression As ExpressionSyntax) As InvocationExpressionSyntax
            Return InvocationExpression(expression, Nothing)
        End Function
 
    End Class
End Namespace