/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Workspaces/VisualBasic/Portable/CodeGeneration/VisualBasicSyntaxGenerator.vb
3 652 строки
202 KB
Cyrus Najmabadi
Update tests to match new behaviot
20 сен 2025, 09:37
20 сен 2025, 09:37
036015e
Код
Авторство
О чём код?
' 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. Imports System.Collections.Immutable Imports System.Composition Imports System.Diagnostics.CodeAnalysis Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.Editing Imports Microsoft.CodeAnalysis.Host.Mef Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Simplification Imports Microsoft.CodeAnalysis.VisualBasic.LanguageService Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGeneration <ExportLanguageService(GetType(SyntaxGenerator), LanguageNames.VisualBasic), [Shared]> Friend NotInheritable Class VisualBasicSyntaxGenerator Inherits SyntaxGenerator Public Shared ReadOnly Instance As SyntaxGenerator = New VisualBasicSyntaxGenerator() <ImportingConstructor> <SuppressMessage("RoslynDiagnosticsReliability", "RS0033:Importing constructor should be [Obsolete]", Justification:="Incorrectly used in production code: https://github.com/dotnet/roslyn/issues/42839")> Public Sub New() End Sub Friend Overrides ReadOnly Property ElasticMarker As SyntaxTrivia = SyntaxFactory.ElasticMarker Friend Overrides ReadOnly Property SyntaxGeneratorInternal As SyntaxGeneratorInternal = VisualBasicSyntaxGeneratorInternal.Instance Friend Overrides Function Whitespace(text As String) As SyntaxTrivia Return SyntaxFactory.Whitespace(text) End Function Friend Overrides Function SeparatedList(Of TElement As SyntaxNode)(list As SyntaxNodeOrTokenList) As SeparatedSyntaxList(Of TElement) Return SyntaxFactory.SeparatedList(Of TElement)(list) End Function Friend Overrides Function CreateInterpolatedStringStartToken(isVerbatim As Boolean) As SyntaxToken Return SyntaxFactory.Token(SyntaxKind.DollarSignDoubleQuoteToken) End Function Friend Overrides Function CreateInterpolatedStringEndToken() As SyntaxToken Return SyntaxFactory.Token(SyntaxKind.DoubleQuoteToken) End Function Friend Overrides Function SeparatedList(Of TElement As SyntaxNode)(nodes As IEnumerable(Of TElement), separators As IEnumerable(Of SyntaxToken)) As SeparatedSyntaxList(Of TElement) Return SyntaxFactory.SeparatedList(nodes, separators) End Function Friend Overrides Function Trivia(node As SyntaxNode) As SyntaxTrivia Dim structuredTrivia = TryCast(node, StructuredTriviaSyntax) If structuredTrivia IsNot Nothing Then Return SyntaxFactory.Trivia(structuredTrivia) End If Throw ExceptionUtilities.UnexpectedValue(node.Kind()) End Function Friend Overrides Function DocumentationCommentTrivia(nodes As IEnumerable(Of SyntaxNode), trailingTrivia As SyntaxTriviaList, endOfLineString As String) As SyntaxNode Dim node = SyntaxFactory.DocumentationCommentTrivia(CType(SyntaxFactory.List(nodes), SyntaxList(Of XmlNodeSyntax))) node = node.WithLeadingTrivia(SyntaxFactory.DocumentationCommentExteriorTrivia("''' ")). WithTrailingTrivia(node.GetTrailingTrivia()) Return node.WithTrailingTrivia(SyntaxFactory.EndOfLine(endOfLineString)) End Function Friend Overrides Function DocumentationCommentTriviaWithUpdatedContent(trivia As SyntaxTrivia, content As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim documentationCommentTrivia = TryCast(trivia.GetStructure(), DocumentationCommentTriviaSyntax) If documentationCommentTrivia IsNot Nothing Then Return SyntaxFactory.DocumentationCommentTrivia(CType(SyntaxFactory.List(content), SyntaxList(Of XmlNodeSyntax))) End If Return Nothing End Function #Region "Expressions and Statements" Public Overrides Function AddEventHandler([event] As SyntaxNode, handler As SyntaxNode) As SyntaxNode Return SyntaxFactory.AddHandlerStatement(CType([event], ExpressionSyntax), CType(handler, ExpressionSyntax)) End Function Public Overrides Function RemoveEventHandler([event] As SyntaxNode, handler As SyntaxNode) As SyntaxNode Return SyntaxFactory.RemoveHandlerStatement(CType([event], ExpressionSyntax), CType(handler, ExpressionSyntax)) End Function Public Overrides Function AwaitExpression(expression As SyntaxNode) As SyntaxNode Return SyntaxFactory.AwaitExpression(DirectCast(expression, ExpressionSyntax)) End Function Public Overrides Function NameOfExpression(expression As SyntaxNode) As SyntaxNode Return SyntaxFactory.NameOfExpression(DirectCast(expression, ExpressionSyntax)) End Function Public Overrides Function TupleExpression(arguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.TupleExpression(SyntaxFactory.SeparatedList(arguments.Select(AddressOf AsSimpleArgument))) End Function Private Shared Function ParenthesizeNonSimple(expression As SyntaxNode, Optional addSimplifierAnnotation As Boolean = True) As ExpressionSyntax Return VisualBasicSyntaxGeneratorInternal.ParenthesizeNonSimple(expression, addSimplifierAnnotation) End Function Public Overrides Function AddExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.AddExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overloads Overrides Function Argument(name As String, refKind As RefKind, expression As SyntaxNode) As SyntaxNode If name Is Nothing Then Return SyntaxFactory.SimpleArgument(DirectCast(expression, ExpressionSyntax)) Else Return SyntaxFactory.SimpleArgument(SyntaxFactory.NameColonEquals(name.ToIdentifierName()), DirectCast(expression, ExpressionSyntax)) End If End Function Public Overrides Function TryCastExpression(expression As SyntaxNode, type As SyntaxNode) As SyntaxNode Return SyntaxFactory.TryCastExpression(DirectCast(expression, ExpressionSyntax), DirectCast(type, TypeSyntax)) End Function Public Overrides Function AssignmentStatement(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.SimpleAssignmentStatement( DirectCast(left, ExpressionSyntax), SyntaxFactory.Token(SyntaxKind.EqualsToken), DirectCast(right, ExpressionSyntax)) End Function Public Overrides Function BaseExpression() As SyntaxNode Return SyntaxFactory.MyBaseExpression() End Function Public Overrides Function BitwiseAndExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.AndExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function ConditionalExpression(condition As SyntaxNode, whenTrue As SyntaxNode, whenFalse As SyntaxNode) As SyntaxNode Return SyntaxFactory.TernaryConditionalExpression( DirectCast(condition, ExpressionSyntax), DirectCast(whenTrue, ExpressionSyntax), DirectCast(whenFalse, ExpressionSyntax)) End Function Public Overrides Function TypedConstantExpression(value As TypedConstant) As SyntaxNode Return ExpressionGenerator.GenerateExpression(Me, value) End Function Private Protected Overrides Function GenerateExpression(type As ITypeSymbol, value As Object, canUseFieldReference As Boolean) As SyntaxNode Return ExpressionGenerator.GenerateExpression(Me, type, value, canUseFieldReference) End Function Friend Overrides Function NumericLiteralToken(text As String, value As ULong) As SyntaxToken Return SyntaxFactory.Literal(text, value) End Function Public Overloads Overrides Function ElementAccessExpression(expression As SyntaxNode, arguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.InvocationExpression(VisualBasicSyntaxGeneratorInternal.ParenthesizeLeft(expression), CreateArgumentList(arguments)) End Function Public Overrides Function ExpressionStatement(expression As SyntaxNode) As SyntaxNode If TypeOf expression Is StatementSyntax Then Return expression End If Return SyntaxFactory.ExpressionStatement(DirectCast(expression, ExpressionSyntax)) End Function Public Overloads Overrides Function GenericName(identifier As String, typeArguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return GenericName(identifier.ToIdentifierToken(), typeArguments) End Function Friend Overrides Function GenericName(identifier As SyntaxToken, typeArguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.GenericName( identifier, SyntaxFactory.TypeArgumentList( SyntaxFactory.SeparatedList(typeArguments.Cast(Of TypeSyntax)()))).WithAdditionalAnnotations(Simplifier.Annotation) End Function Public Overrides Function IfStatement(condition As SyntaxNode, trueStatements As IEnumerable(Of SyntaxNode), Optional falseStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Dim ifStmt = SyntaxFactory.IfStatement(SyntaxFactory.Token(SyntaxKind.IfKeyword), DirectCast(condition, ExpressionSyntax), SyntaxFactory.Token(SyntaxKind.ThenKeyword)) If falseStatements Is Nothing Then Return SyntaxFactory.MultiLineIfBlock( ifStmt, GetStatementList(trueStatements), Nothing, Nothing ) End If ' convert nested if-blocks into else-if parts Dim statements = falseStatements.ToList() If statements.Count = 1 AndAlso TypeOf statements(0) Is MultiLineIfBlockSyntax Then Dim mifBlock = DirectCast(statements(0), MultiLineIfBlockSyntax) ' insert block's if-part onto head of elseIf-parts Dim elseIfBlocks = mifBlock.ElseIfBlocks.Insert(0, SyntaxFactory.ElseIfBlock( SyntaxFactory.ElseIfStatement(SyntaxFactory.Token(SyntaxKind.ElseIfKeyword), mifBlock.IfStatement.Condition, SyntaxFactory.Token(SyntaxKind.ThenKeyword)), mifBlock.Statements) ) Return SyntaxFactory.MultiLineIfBlock( ifStmt, GetStatementList(trueStatements), elseIfBlocks, mifBlock.ElseBlock ) End If Return SyntaxFactory.MultiLineIfBlock( ifStmt, GetStatementList(trueStatements), Nothing, SyntaxFactory.ElseBlock(GetStatementList(falseStatements)) ) End Function Private Shared Function GetStatementList(nodes As IEnumerable(Of SyntaxNode)) As SyntaxList(Of StatementSyntax) Return VisualBasicSyntaxGeneratorInternal.GetStatementList(nodes) End Function Private Shared Function AsStatement(node As SyntaxNode) As StatementSyntax Return VisualBasicSyntaxGeneratorInternal.AsStatement(node) End Function Public Overloads Overrides Function InvocationExpression(expression As SyntaxNode, arguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.InvocationExpression(VisualBasicSyntaxGeneratorInternal.ParenthesizeLeft(expression), CreateArgumentList(arguments)) End Function Public Overrides Function IsTypeExpression(expression As SyntaxNode, type As SyntaxNode) As SyntaxNode Return SyntaxFactory.TypeOfIsExpression(ParenthesizeNonSimple(expression), DirectCast(type, TypeSyntax)) End Function Public Overrides Function TypeOfExpression(type As SyntaxNode) As SyntaxNode Return SyntaxFactory.GetTypeExpression(DirectCast(type, TypeSyntax)) End Function Public Overrides Function LogicalAndExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.AndAlsoExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function LogicalNotExpression(expression As SyntaxNode) As SyntaxNode ' This helper is used in some locations where the formatter is not available. So try to ensure ' that we generate proper code with a space between the 'Not' and the expression when necessary. Return SyntaxFactory.NotExpression( SyntaxFactory.Token(SyntaxKind.NotKeyword).WithTrailingTrivia(SyntaxFactory.ElasticSpace), ParenthesizeNonSimple(expression)) End Function Public Overrides Function LogicalOrExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.OrElseExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function ConditionalAccessExpression(expression As SyntaxNode, whenNotNull As SyntaxNode) As SyntaxNode Return SyntaxGeneratorInternal.ConditionalAccessExpression(expression, whenNotNull) End Function Public Overrides Function MemberBindingExpression(name As SyntaxNode) As SyntaxNode Return SyntaxGeneratorInternal.MemberBindingExpression(name) End Function Public Overrides Function ElementBindingExpression(arguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.InvocationExpression(expression:=Nothing, SyntaxFactory.ArgumentList(CType(SyntaxFactory.SeparatedList(arguments), SeparatedSyntaxList(Of ArgumentSyntax)))) End Function Public Overrides Function MultiplyExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.MultiplyExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function NegateExpression(expression As SyntaxNode) As SyntaxNode Return SyntaxFactory.UnaryMinusExpression(ParenthesizeNonSimple(expression)) End Function Private Shared Function AsExpressionList(expressions As IEnumerable(Of SyntaxNode)) As SeparatedSyntaxList(Of ExpressionSyntax) Return SyntaxFactory.SeparatedList(Of ExpressionSyntax)(expressions.OfType(Of ExpressionSyntax)()) End Function Public Overrides Function ArrayCreationExpression(elementType As SyntaxNode, size As SyntaxNode) As SyntaxNode Dim sizes = SyntaxFactory.ArgumentList(SyntaxFactory.SingletonSeparatedList(AsArgument(size))) Dim initializer = SyntaxFactory.CollectionInitializer() Return SyntaxFactory.ArrayCreationExpression(Nothing, DirectCast(elementType, TypeSyntax), sizes, initializer) End Function Public Overrides Function ArrayCreationExpression(elementType As SyntaxNode, elements As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim sizes = SyntaxFactory.ArgumentList() Dim initializer = SyntaxFactory.CollectionInitializer(AsExpressionList(elements)) Return SyntaxFactory.ArrayCreationExpression(Nothing, DirectCast(elementType, TypeSyntax), sizes, initializer) End Function Public Overloads Overrides Function ObjectCreationExpression(typeName As SyntaxNode, arguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.ObjectCreationExpression( attributeLists:=Nothing, DirectCast(typeName, TypeSyntax), CreateArgumentList(arguments), initializer:=Nothing) End Function Friend Overrides Function ObjectCreationExpression(typeName As SyntaxNode, openParen As SyntaxToken, arguments As SeparatedSyntaxList(Of SyntaxNode), closeParen As SyntaxToken) As SyntaxNode Return SyntaxFactory.ObjectCreationExpression( attributeLists:=Nothing, DirectCast(typeName, TypeSyntax), SyntaxFactory.ArgumentList(openParen, CType(arguments, SeparatedSyntaxList(Of ArgumentSyntax)), closeParen), initializer:=Nothing) End Function Public Overrides Function QualifiedName(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.QualifiedName(DirectCast(left, NameSyntax), DirectCast(right, SimpleNameSyntax)) End Function Friend Overrides Function GlobalAliasedName(name As SyntaxNode) As SyntaxNode Return QualifiedName(SyntaxFactory.GlobalName(), name) End Function Public Overrides Function ReferenceEqualsExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.IsExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function ReferenceNotEqualsExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.IsNotExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function ReturnStatement(Optional expressionOpt As SyntaxNode = Nothing) As SyntaxNode Return SyntaxFactory.ReturnStatement(DirectCast(expressionOpt, ExpressionSyntax)) End Function Public Overrides Function ThisExpression() As SyntaxNode Return SyntaxFactory.MeExpression() End Function Public Overrides Function ThrowStatement(Optional expressionOpt As SyntaxNode = Nothing) As SyntaxNode Return SyntaxFactory.ThrowStatement(DirectCast(expressionOpt, ExpressionSyntax)) End Function Public Overrides Function ThrowExpression(expression As SyntaxNode) As SyntaxNode Throw New NotSupportedException("ThrowExpressions are not supported in Visual Basic") End Function Public Overrides Function NameExpression(namespaceOrTypeSymbol As INamespaceOrTypeSymbol) As SyntaxNode Return namespaceOrTypeSymbol.GenerateTypeSyntax() End Function Public Overrides Function TypeExpression(specialType As SpecialType) As SyntaxNode Select Case specialType Case SpecialType.System_Boolean Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.BooleanKeyword)) Case SpecialType.System_Byte Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ByteKeyword)) Case SpecialType.System_Char Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.CharKeyword)) Case SpecialType.System_Decimal Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DecimalKeyword)) Case SpecialType.System_Double Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DoubleKeyword)) Case SpecialType.System_Int16 Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ShortKeyword)) Case SpecialType.System_Int32 Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.IntegerKeyword)) Case SpecialType.System_Int64 Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.LongKeyword)) Case SpecialType.System_Object Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ObjectKeyword)) Case SpecialType.System_SByte Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.SByteKeyword)) Case SpecialType.System_Single Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.SingleKeyword)) Case SpecialType.System_String Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.StringKeyword)) Case SpecialType.System_UInt16 Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UShortKeyword)) Case SpecialType.System_UInt32 Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.UIntegerKeyword)) Case SpecialType.System_UInt64 Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.ULongKeyword)) Case SpecialType.System_DateTime Return SyntaxFactory.PredefinedType(SyntaxFactory.Token(SyntaxKind.DateKeyword)) Case Else Throw New NotSupportedException("Unsupported SpecialType") End Select End Function Public Overloads Overrides Function UsingStatement(type As SyntaxNode, identifier As String, expression As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.UsingBlock( SyntaxFactory.UsingStatement( expression:=Nothing, variables:=SyntaxFactory.SingletonSeparatedList(VisualBasicSyntaxGeneratorInternal.VariableDeclarator(type, identifier.ToModifiedIdentifier, expression))), GetStatementList(statements)) End Function Public Overloads Overrides Function UsingStatement(expression As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.UsingBlock( SyntaxFactory.UsingStatement( expression:=DirectCast(expression, ExpressionSyntax), variables:=Nothing), GetStatementList(statements)) End Function Public Overrides Function LockStatement(expression As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.SyncLockBlock( SyntaxFactory.SyncLockStatement( expression:=DirectCast(expression, ExpressionSyntax)), GetStatementList(statements)) End Function Public Overrides Function ValueEqualsExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.EqualsExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function ValueNotEqualsExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.NotEqualsExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Private Function CreateArgumentList(arguments As IEnumerable(Of SyntaxNode)) As ArgumentListSyntax Return SyntaxFactory.ArgumentList(CreateArguments(arguments)) End Function Private Function CreateArguments(arguments As IEnumerable(Of SyntaxNode)) As SeparatedSyntaxList(Of ArgumentSyntax) Return SyntaxFactory.SeparatedList(arguments.Select(AddressOf AsArgument)) End Function Private Function AsArgument(argOrExpression As SyntaxNode) As ArgumentSyntax Return If(TryCast(argOrExpression, ArgumentSyntax), SyntaxFactory.SimpleArgument(DirectCast(argOrExpression, ExpressionSyntax))) End Function Private Function AsSimpleArgument(argOrExpression As SyntaxNode) As SimpleArgumentSyntax Return If(TryCast(argOrExpression, SimpleArgumentSyntax), SyntaxFactory.SimpleArgument(DirectCast(argOrExpression, ExpressionSyntax))) End Function Public Overloads Overrides Function LocalDeclarationStatement(type As SyntaxNode, identifier As String, Optional initializer As SyntaxNode = Nothing, Optional isConst As Boolean = False) As SyntaxNode Return LocalDeclarationStatement(type, identifier.ToIdentifierToken, initializer, isConst) End Function Public Overloads Overrides Function SwitchStatement(expression As SyntaxNode, caseClauses As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.SelectBlock( SyntaxFactory.SelectStatement(DirectCast(expression, ExpressionSyntax)), SyntaxFactory.List(caseClauses.Cast(Of CaseBlockSyntax))) End Function Public Overloads Overrides Function SwitchSection(expressions As IEnumerable(Of SyntaxNode), statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.CaseBlock( SyntaxFactory.CaseStatement(GetCaseClauses(expressions)), GetStatementList(statements)) End Function Friend Overrides Function SwitchSectionFromLabels(labels As IEnumerable(Of SyntaxNode), statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.CaseBlock( SyntaxFactory.CaseStatement(SyntaxFactory.SeparatedList(labels.Cast(Of CaseClauseSyntax))), GetStatementList(statements)) End Function Public Overrides Function DefaultSwitchSection(statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.CaseElseBlock( SyntaxFactory.CaseElseStatement(SyntaxFactory.ElseCaseClause()), GetStatementList(statements)) End Function Private Shared Function GetCaseClauses(expressions As IEnumerable(Of SyntaxNode)) As SeparatedSyntaxList(Of CaseClauseSyntax) Dim cases = SyntaxFactory.SeparatedList(Of CaseClauseSyntax) If expressions IsNot Nothing Then cases = cases.AddRange(expressions.Select(Function(e) SyntaxFactory.SimpleCaseClause(DirectCast(e, ExpressionSyntax)))) End If Return cases End Function Public Overrides Function ExitSwitchStatement() As SyntaxNode Return SyntaxFactory.ExitSelectStatement() End Function Public Overloads Overrides Function ValueReturningLambdaExpression(parameters As IEnumerable(Of SyntaxNode), expression As SyntaxNode) As SyntaxNode Return SyntaxFactory.SingleLineFunctionLambdaExpression( SyntaxFactory.FunctionLambdaHeader().WithParameterList(GetParameterList(parameters)), DirectCast(expression, ExpressionSyntax)) End Function Public Overrides Function VoidReturningLambdaExpression(lambdaParameters As IEnumerable(Of SyntaxNode), expression As SyntaxNode) As SyntaxNode Return SyntaxFactory.SingleLineSubLambdaExpression( SyntaxFactory.SubLambdaHeader().WithParameterList(GetParameterList(lambdaParameters)), AsStatement(expression)) End Function Public Overloads Overrides Function ValueReturningLambdaExpression(lambdaParameters As IEnumerable(Of SyntaxNode), statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.MultiLineFunctionLambdaExpression( SyntaxFactory.FunctionLambdaHeader().WithParameterList(GetParameterList(lambdaParameters)), GetStatementList(statements), SyntaxFactory.EndFunctionStatement()) End Function Public Overrides Function VoidReturningLambdaExpression(lambdaParameters As IEnumerable(Of SyntaxNode), statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.MultiLineSubLambdaExpression( SyntaxFactory.SubLambdaHeader().WithParameterList(GetParameterList(lambdaParameters)), GetStatementList(statements), SyntaxFactory.EndSubStatement()) End Function Public Overrides Function LambdaParameter(identifier As String, Optional type As SyntaxNode = Nothing) As SyntaxNode Return ParameterDeclaration(identifier, type) End Function Public Overrides Function ArrayTypeExpression(type As SyntaxNode) As SyntaxNode Dim arrayType = TryCast(type, ArrayTypeSyntax) If arrayType IsNot Nothing Then Return arrayType.WithRankSpecifiers(arrayType.RankSpecifiers.Add(SyntaxFactory.ArrayRankSpecifier())) Else Return SyntaxFactory.ArrayType(DirectCast(type, TypeSyntax), SyntaxFactory.SingletonList(SyntaxFactory.ArrayRankSpecifier())) End If End Function Public Overrides Function NullableTypeExpression(type As SyntaxNode) As SyntaxNode Dim nullableType = TryCast(type, NullableTypeSyntax) If nullableType IsNot Nothing Then Return nullableType Else Return SyntaxFactory.NullableType(DirectCast(type, TypeSyntax)) End If End Function Friend Overrides Function CreateTupleType(elements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.TupleType(SyntaxFactory.SeparatedList(elements.Cast(Of TupleElementSyntax)())) End Function Public Overrides Function TupleElementExpression(type As SyntaxNode, Optional name As String = Nothing) As SyntaxNode If name Is Nothing Then Return SyntaxFactory.TypedTupleElement(DirectCast(type, TypeSyntax)) Else Return SyntaxFactory.NamedTupleElement(name.ToIdentifierToken(), SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax))) End If End Function Public Overrides Function WithTypeArguments(name As SyntaxNode, typeArguments As IEnumerable(Of SyntaxNode)) As SyntaxNode If name.IsKind(SyntaxKind.IdentifierName) OrElse name.IsKind(SyntaxKind.GenericName) Then Dim sname = DirectCast(name, SimpleNameSyntax) Return SyntaxFactory.GenericName(sname.Identifier, SyntaxFactory.TypeArgumentList(SyntaxFactory.SeparatedList(typeArguments.Cast(Of TypeSyntax)()))) ElseIf name.IsKind(SyntaxKind.QualifiedName) Then Dim qname = DirectCast(name, QualifiedNameSyntax) Return SyntaxFactory.QualifiedName(qname.Left, DirectCast(WithTypeArguments(qname.Right, typeArguments), SimpleNameSyntax)) ElseIf name.IsKind(SyntaxKind.SimpleMemberAccessExpression) Then Dim sma = DirectCast(name, MemberAccessExpressionSyntax) Return SyntaxFactory.MemberAccessExpression(name.Kind(), sma.Expression, sma.OperatorToken, DirectCast(WithTypeArguments(sma.Name, typeArguments), SimpleNameSyntax)) Else Throw New NotSupportedException() End If End Function Public Overrides Function SubtractExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.SubtractExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function DivideExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.DivideExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function ModuloExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.ModuloExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function BitwiseNotExpression(operand As SyntaxNode) As SyntaxNode Return SyntaxFactory.NotExpression(ParenthesizeNonSimple(operand)) End Function Public Overrides Function CoalesceExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.BinaryConditionalExpression(DirectCast(left, ExpressionSyntax), DirectCast(right, ExpressionSyntax)) End Function Public Overrides Function LessThanExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.LessThanExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function LessThanOrEqualExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.LessThanOrEqualExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function GreaterThanExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.GreaterThanExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function GreaterThanOrEqualExpression(left As SyntaxNode, right As SyntaxNode) As SyntaxNode Return SyntaxFactory.GreaterThanOrEqualExpression(ParenthesizeNonSimple(left), ParenthesizeNonSimple(right)) End Function Public Overrides Function TryCatchStatement(tryStatements As IEnumerable(Of SyntaxNode), catchClauses As IEnumerable(Of SyntaxNode), Optional finallyStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Return SyntaxFactory.TryBlock( GetStatementList(tryStatements), If(catchClauses IsNot Nothing, SyntaxFactory.List(catchClauses.Cast(Of CatchBlockSyntax)()), Nothing), If(finallyStatements IsNot Nothing, SyntaxFactory.FinallyBlock(GetStatementList(finallyStatements)), Nothing) ) End Function Public Overrides Function CatchClause(type As SyntaxNode, identifier As String, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.CatchBlock( SyntaxFactory.CatchStatement( SyntaxFactory.IdentifierName(identifier), SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)), whenClause:=Nothing ), GetStatementList(statements) ) End Function Public Overrides Function WhileStatement(condition As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.WhileBlock( SyntaxFactory.WhileStatement(DirectCast(condition, ExpressionSyntax)), GetStatementList(statements)) End Function Friend Overrides Function ScopeBlock(statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Throw New NotSupportedException() End Function Friend Overrides Function GlobalStatement(statement As SyntaxNode) As SyntaxNode ' Visual basic does not have global statements Throw New NotSupportedException() End Function Friend Overrides Function ParseExpression(stringToParse As String) As SyntaxNode Return SyntaxFactory.ParseExpression(stringToParse) End Function Friend Overrides Function ParseTypeName(stringToParse As String) As SyntaxNode Return SyntaxFactory.ParseTypeName(stringToParse) End Function #End Region #Region "Declarations" Friend Shared Function GetAllowedModifiers(kind As SyntaxKind) As DeclarationModifiers Return VisualBasicSyntaxGeneratorInternal.GetAllowedModifiers(kind) End Function Public Overrides Function FieldDeclaration(name As String, type As SyntaxNode, Optional accessibility As Accessibility = Nothing, Optional modifiers As DeclarationModifiers = Nothing, Optional initializer As SyntaxNode = Nothing) As SyntaxNode modifiers = If(modifiers.IsConst(), modifiers.WithIsReadOnly(False), modifiers) Return SyntaxFactory.FieldDeclaration( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_fieldModifiers, declaration:=Nothing, DeclarationKind.Field), declarators:=SyntaxFactory.SingletonSeparatedList(VisualBasicSyntaxGeneratorInternal.VariableDeclarator(type, name.ToModifiedIdentifier, initializer))) End Function Private Protected Overrides Function MethodDeclaration( identifier As String, parameters As IEnumerable(Of SyntaxNode), typeParameters As IEnumerable(Of SyntaxNode), returnType As SyntaxNode, accessibility As Accessibility, modifiers As DeclarationModifiers, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim statement = SyntaxFactory.MethodStatement( kind:=If(returnType Is Nothing, SyntaxKind.SubStatement, SyntaxKind.FunctionStatement), attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_methodModifiers, declaration:=Nothing, DeclarationKind.Method), subOrFunctionKeyword:=If(returnType Is Nothing, SyntaxFactory.Token(SyntaxKind.SubKeyword), SyntaxFactory.Token(SyntaxKind.FunctionKeyword)), identifier:=identifier.ToIdentifierToken(), typeParameterList:=GetTypeParameters(typeParameters), parameterList:=GetParameterList(parameters), asClause:=If(returnType IsNot Nothing, SyntaxFactory.SimpleAsClause(DirectCast(returnType, TypeSyntax)), Nothing), handlesClause:=Nothing, implementsClause:=Nothing) If modifiers.IsAbstract Then Return statement Else Return SyntaxFactory.MethodBlock( kind:=If(returnType Is Nothing, SyntaxKind.SubBlock, SyntaxKind.FunctionBlock), subOrFunctionStatement:=statement, statements:=GetStatementList(statements), endSubOrFunctionStatement:=If(returnType Is Nothing, SyntaxFactory.EndSubStatement(), SyntaxFactory.EndFunctionStatement())) End If End Function Public Overrides Function OperatorDeclaration(kind As OperatorKind, Optional parameters As IEnumerable(Of SyntaxNode) = Nothing, Optional returnType As SyntaxNode = Nothing, Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional modifiers As DeclarationModifiers = Nothing, Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Return OperatorDeclaration(GetOperatorName(kind), isImplicitConversion:=kind = OperatorKind.ImplicitConversion, parameters, returnType, accessibility, modifiers, statements) End Function Private Protected Overrides Function OperatorDeclaration(operatorName As String, isImplicitConversion As Boolean, Optional parameters As IEnumerable(Of SyntaxNode) = Nothing, Optional returnType As SyntaxNode = Nothing, Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional modifiers As DeclarationModifiers = Nothing, Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Dim statement As OperatorStatementSyntax Dim asClause = If(returnType IsNot Nothing, SyntaxFactory.SimpleAsClause(DirectCast(returnType, TypeSyntax)), Nothing) Dim parameterList = GetParameterList(parameters) Dim vbSyntaxKind As SyntaxKind = VisualBasic.SyntaxFacts.GetOperatorKind(operatorName) Dim operatorToken = SyntaxFactory.Token(vbSyntaxKind) Dim modifierList As SyntaxTokenList = GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_methodModifiers, declaration:=Nothing, DeclarationKind.Operator) If vbSyntaxKind = SyntaxKind.CTypeKeyword Then modifierList = modifierList.Add(SyntaxFactory.Token( If(isImplicitConversion, SyntaxKind.WideningKeyword, SyntaxKind.NarrowingKeyword))) statement = SyntaxFactory.OperatorStatement( attributeLists:=Nothing, modifiers:=modifierList, operatorToken:=operatorToken, parameterList:=parameterList, asClause:=asClause) Else statement = SyntaxFactory.OperatorStatement( attributeLists:=Nothing, modifiers:=modifierList, operatorToken:=operatorToken, parameterList:=parameterList, asClause:=asClause) End If If modifiers.IsAbstract Then Return statement Else Return SyntaxFactory.OperatorBlock( operatorStatement:=statement, statements:=GetStatementList(statements), endOperatorStatement:=SyntaxFactory.EndOperatorStatement()) End If End Function Private Shared Function GetOperatorName(kind As OperatorKind) As String Select Case kind Case OperatorKind.ImplicitConversion Return WellKnownMemberNames.ImplicitConversionName Case OperatorKind.ExplicitConversion Return WellKnownMemberNames.ExplicitConversionName Case OperatorKind.Addition Return WellKnownMemberNames.AdditionOperatorName Case OperatorKind.BitwiseAnd Return WellKnownMemberNames.BitwiseAndOperatorName Case OperatorKind.BitwiseOr Return WellKnownMemberNames.BitwiseOrOperatorName Case OperatorKind.Division Return WellKnownMemberNames.DivisionOperatorName Case OperatorKind.Equality Return WellKnownMemberNames.EqualityOperatorName Case OperatorKind.ExclusiveOr Return WellKnownMemberNames.ExclusiveOrOperatorName Case OperatorKind.False Return WellKnownMemberNames.FalseOperatorName Case OperatorKind.GreaterThan Return WellKnownMemberNames.GreaterThanOperatorName Case OperatorKind.GreaterThanOrEqual Return WellKnownMemberNames.GreaterThanOrEqualOperatorName Case OperatorKind.Inequality Return WellKnownMemberNames.InequalityOperatorName Case OperatorKind.LeftShift Return WellKnownMemberNames.LeftShiftOperatorName Case OperatorKind.LessThan Return WellKnownMemberNames.LessThanOperatorName Case OperatorKind.LessThanOrEqual Return WellKnownMemberNames.LessThanOrEqualOperatorName Case OperatorKind.LogicalNot Return WellKnownMemberNames.LogicalNotOperatorName Case OperatorKind.Modulus Return WellKnownMemberNames.ModulusOperatorName Case OperatorKind.Multiply Return WellKnownMemberNames.MultiplyOperatorName Case OperatorKind.RightShift Return WellKnownMemberNames.RightShiftOperatorName Case OperatorKind.Subtraction Return WellKnownMemberNames.SubtractionOperatorName Case OperatorKind.True Return WellKnownMemberNames.TrueOperatorName Case OperatorKind.UnaryNegation Return WellKnownMemberNames.UnaryNegationOperatorName Case OperatorKind.UnaryPlus Return WellKnownMemberNames.UnaryPlusOperatorName Case Else Throw New ArgumentException($"Operator {kind} cannot be generated in Visual Basic.") End Select End Function Private Shared Function GetParameterList(parameters As IEnumerable(Of SyntaxNode)) As ParameterListSyntax Return VisualBasicSyntaxGeneratorInternal.GetParameterList(parameters) End Function Private Protected Overrides Function ParameterDeclaration( name As String, type As SyntaxNode, initializer As SyntaxNode, refKind As RefKind, isExtension As Boolean, isParams As Boolean, isScoped As Boolean) As SyntaxNode Dim modifiers = GetParameterModifiers(refKind, initializer) If isParams Then modifiers = modifiers.Add(SyntaxFactory.Token(SyntaxKind.ParamArrayKeyword)) End If ' isExtension not used in vb. instead, an attribute is added at the method level. Return SyntaxFactory.Parameter( attributeLists:=Nothing, modifiers:=modifiers, identifier:=name.ToModifiedIdentifier(), asClause:=If(type IsNot Nothing, SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)), Nothing), [default]:=If(initializer IsNot Nothing, SyntaxFactory.EqualsValue(DirectCast(initializer, ExpressionSyntax)), Nothing)) End Function Private Shared Function GetParameterModifiers(refKind As RefKind, initializer As SyntaxNode) As SyntaxTokenList Dim tokens As SyntaxTokenList = Nothing If initializer IsNot Nothing Then tokens = tokens.Add(SyntaxFactory.Token(SyntaxKind.OptionalKeyword)) End If If refKind <> RefKind.None Then tokens = tokens.Add(SyntaxFactory.Token(SyntaxKind.ByRefKeyword)) End If Return tokens End Function Public Overrides Function GetAccessorDeclaration(Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Return SyntaxFactory.GetAccessorBlock( SyntaxFactory.GetAccessorStatement().WithModifiers(GetModifierList(accessibility, DeclarationModifiers.None, declaration:=Nothing, DeclarationKind.Property)), GetStatementList(statements)) End Function Private Protected Overrides Function SetAccessorDeclaration(accessibility As Accessibility, isInitOnly As Boolean, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.SetAccessorBlock( SyntaxFactory.SetAccessorStatement().WithModifiers(GetModifierList(accessibility, DeclarationModifiers.None, declaration:=Nothing, DeclarationKind.Property)), GetStatementList(statements)) End Function Public Overrides Function WithAccessorDeclarations(declaration As SyntaxNode, accessorDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim propertyBlock = GetPropertyBlock(declaration) If propertyBlock Is Nothing Then Return declaration End If propertyBlock = propertyBlock.WithAccessors( SyntaxFactory.List(accessorDeclarations.OfType(Of AccessorBlockSyntax))) Dim hasGetAccessor = propertyBlock.Accessors.Any(SyntaxKind.GetAccessorBlock) Dim hasSetAccessor = propertyBlock.Accessors.Any(SyntaxKind.SetAccessorBlock) If hasGetAccessor AndAlso Not hasSetAccessor Then propertyBlock = DirectCast(WithModifiers(propertyBlock, GetModifiers(propertyBlock) Or DeclarationModifiers.ReadOnly), PropertyBlockSyntax) ElseIf Not hasGetAccessor AndAlso hasSetAccessor Then propertyBlock = DirectCast(WithModifiers(propertyBlock, GetModifiers(propertyBlock) Or DeclarationModifiers.WriteOnly), PropertyBlockSyntax) ElseIf hasGetAccessor AndAlso hasSetAccessor Then propertyBlock = DirectCast(WithModifiers(propertyBlock, GetModifiers(propertyBlock).WithIsReadOnly(False).WithIsWriteOnly(False)), PropertyBlockSyntax) End If Return If(propertyBlock.Accessors.Count = 0, propertyBlock.PropertyStatement, DirectCast(propertyBlock, SyntaxNode)) End Function Private Shared Function GetPropertyBlock(declaration As SyntaxNode) As PropertyBlockSyntax Dim propertyBlock = TryCast(declaration, PropertyBlockSyntax) If propertyBlock IsNot Nothing Then Return propertyBlock End If Dim propertyStatement = TryCast(declaration, PropertyStatementSyntax) If propertyStatement IsNot Nothing Then Return SyntaxFactory.PropertyBlock(propertyStatement, SyntaxFactory.List(Of AccessorBlockSyntax)) End If Return Nothing End Function Public Overrides Function PropertyDeclaration( identifier As String, type As SyntaxNode, Optional accessibility As Accessibility = Nothing, Optional modifiers As DeclarationModifiers = Nothing, Optional getAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing, Optional setAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Return PropertyDeclaration( identifier, type, If(Not modifiers.IsWriteOnly, CreateGetAccessorBlock(getAccessorStatements), Nothing), If(Not modifiers.IsReadOnly, CreateSetAccessorBlock(type, setAccessorStatements), Nothing), accessibility, modifiers) End Function Private Protected Overrides Function PropertyDeclaration( name As String, type As SyntaxNode, getAccessor As SyntaxNode, setAccessor As SyntaxNode, accessibility As Accessibility, modifiers As DeclarationModifiers) As SyntaxNode Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) Dim statement = SyntaxFactory.PropertyStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_propertyModifiers, declaration:=Nothing, DeclarationKind.Property), identifier:=name.ToIdentifierToken(), parameterList:=Nothing, asClause:=asClause, initializer:=Nothing, implementsClause:=Nothing) If modifiers.IsAbstract Then Return statement Else Dim accessors = New List(Of AccessorBlockSyntax) accessors.AddIfNotNull(DirectCast(getAccessor, AccessorBlockSyntax)) accessors.AddIfNotNull(DirectCast(setAccessor, AccessorBlockSyntax)) Return SyntaxFactory.PropertyBlock( propertyStatement:=statement, accessors:=SyntaxFactory.List(accessors), endPropertyStatement:=SyntaxFactory.EndPropertyStatement()) End If End Function Public Overrides Function IndexerDeclaration( parameters As IEnumerable(Of SyntaxNode), type As SyntaxNode, Optional accessibility As Accessibility = Nothing, Optional modifiers As DeclarationModifiers = Nothing, Optional getAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing, Optional setAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) Dim statement = SyntaxFactory.PropertyStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_indexerModifiers, declaration:=Nothing, DeclarationKind.Indexer, isDefault:=True), identifier:=SyntaxFactory.Identifier("Item"), parameterList:=SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters.Cast(Of ParameterSyntax))), asClause:=asClause, initializer:=Nothing, implementsClause:=Nothing) If modifiers.IsAbstract Then Return statement Else Dim accessors = New List(Of AccessorBlockSyntax) If Not modifiers.IsWriteOnly Then accessors.Add(CreateGetAccessorBlock(getAccessorStatements)) End If If Not modifiers.IsReadOnly Then accessors.Add(CreateSetAccessorBlock(type, setAccessorStatements)) End If Return SyntaxFactory.PropertyBlock( propertyStatement:=statement, accessors:=SyntaxFactory.List(accessors), endPropertyStatement:=SyntaxFactory.EndPropertyStatement()) End If End Function Private Shared Function AccessorBlock(kind As SyntaxKind, statements As IEnumerable(Of SyntaxNode), type As SyntaxNode) As AccessorBlockSyntax Select Case kind Case SyntaxKind.GetAccessorBlock Return CreateGetAccessorBlock(statements) Case SyntaxKind.SetAccessorBlock Return CreateSetAccessorBlock(type, statements) Case SyntaxKind.AddHandlerAccessorBlock Return VisualBasicSyntaxGeneratorInternal.CreateAddHandlerAccessorBlock(type, statements) Case SyntaxKind.RemoveHandlerAccessorBlock Return VisualBasicSyntaxGeneratorInternal.CreateRemoveHandlerAccessorBlock(type, statements) Case Else Return Nothing End Select End Function Private Shared Function CreateGetAccessorBlock(statements As IEnumerable(Of SyntaxNode)) As AccessorBlockSyntax Return SyntaxFactory.AccessorBlock( SyntaxKind.GetAccessorBlock, SyntaxFactory.AccessorStatement(SyntaxKind.GetAccessorStatement, SyntaxFactory.Token(SyntaxKind.GetKeyword)), GetStatementList(statements), SyntaxFactory.EndGetStatement()) End Function Private Shared Function CreateSetAccessorBlock(type As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As AccessorBlockSyntax Dim asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) Dim valueParameter = SyntaxFactory.Parameter( attributeLists:=Nothing, modifiers:=Nothing, identifier:=SyntaxFactory.ModifiedIdentifier("value"), asClause:=asClause, [default]:=Nothing) Return SyntaxFactory.AccessorBlock( SyntaxKind.SetAccessorBlock, SyntaxFactory.AccessorStatement( kind:=SyntaxKind.SetAccessorStatement, attributeLists:=Nothing, modifiers:=Nothing, accessorKeyword:=SyntaxFactory.Token(SyntaxKind.SetKeyword), parameterList:=SyntaxFactory.ParameterList(SyntaxFactory.SingletonSeparatedList(valueParameter))), GetStatementList(statements), SyntaxFactory.EndSetStatement()) End Function Public Overrides Function AsPublicInterfaceImplementation(declaration As SyntaxNode, interfaceTypeName As SyntaxNode, interfaceMemberName As String) As SyntaxNode Return Isolate(declaration, Function(decl) AsPublicInterfaceImplementationInternal(decl, interfaceTypeName, interfaceMemberName)) End Function Private Function AsPublicInterfaceImplementationInternal(declaration As SyntaxNode, interfaceTypeName As SyntaxNode, interfaceMemberName As String) As SyntaxNode Dim type = DirectCast(interfaceTypeName, NameSyntax) declaration = WithBody(declaration, allowDefault:=True) declaration = WithAccessibility(declaration, Accessibility.Public) Dim memberName = If(interfaceMemberName IsNot Nothing, interfaceMemberName, GetInterfaceMemberName(declaration)) declaration = WithName(declaration, memberName) declaration = WithImplementsClause(declaration, SyntaxFactory.ImplementsClause(SyntaxFactory.QualifiedName(type, SyntaxFactory.IdentifierName(memberName)))) Return declaration End Function Public Overrides Function AsPrivateInterfaceImplementation(declaration As SyntaxNode, interfaceTypeName As SyntaxNode, interfaceMemberName As String) As SyntaxNode Return Isolate(declaration, Function(decl) AsPrivateInterfaceImplementationInternal(decl, interfaceTypeName, interfaceMemberName)) End Function Private Function AsPrivateInterfaceImplementationInternal(declaration As SyntaxNode, interfaceTypeName As SyntaxNode, interfaceMemberName As String) As SyntaxNode Dim type = DirectCast(interfaceTypeName, NameSyntax) declaration = WithBody(declaration, allowDefault:=False) declaration = WithAccessibility(declaration, Accessibility.Private) Dim memberName = If(interfaceMemberName IsNot Nothing, interfaceMemberName, GetInterfaceMemberName(declaration)) declaration = WithName(declaration, GetNameAsIdentifier(interfaceTypeName) & "_" & memberName) declaration = WithImplementsClause(declaration, SyntaxFactory.ImplementsClause(SyntaxFactory.QualifiedName(type, SyntaxFactory.IdentifierName(memberName)))) Return declaration End Function Private Function GetInterfaceMemberName(declaration As SyntaxNode) As String Dim clause = GetImplementsClause(declaration) If clause IsNot Nothing Then Dim qname = clause.InterfaceMembers.FirstOrDefault(Function(n) n.Right IsNot Nothing) If qname IsNot Nothing Then Return qname.Right.ToString() End If End If Return GetName(declaration) End Function Private Shared Function GetImplementsClause(declaration As SyntaxNode) As ImplementsClauseSyntax Select Case declaration.Kind Case SyntaxKind.SubBlock, SyntaxKind.FunctionBlock Return DirectCast(declaration, MethodBlockSyntax).SubOrFunctionStatement.ImplementsClause Case SyntaxKind.SubStatement, SyntaxKind.FunctionStatement Return DirectCast(declaration, MethodStatementSyntax).ImplementsClause Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.ImplementsClause Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).ImplementsClause Case Else Return Nothing End Select End Function Private Shared Function WithImplementsClause(declaration As SyntaxNode, clause As ImplementsClauseSyntax) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.SubBlock, SyntaxKind.FunctionBlock Dim mb = DirectCast(declaration, MethodBlockSyntax) Return mb.WithSubOrFunctionStatement(mb.SubOrFunctionStatement.WithImplementsClause(clause)) Case SyntaxKind.SubStatement, SyntaxKind.FunctionStatement Return DirectCast(declaration, MethodStatementSyntax).WithImplementsClause(clause) Case SyntaxKind.PropertyBlock Dim pb = DirectCast(declaration, PropertyBlockSyntax) Return pb.WithPropertyStatement(pb.PropertyStatement.WithImplementsClause(clause)) Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).WithImplementsClause(clause) Case Else Return declaration End Select End Function Private Shared Function GetNameAsIdentifier(type As SyntaxNode) As String Dim name = TryCast(type, IdentifierNameSyntax) If name IsNot Nothing Then Return name.Identifier.ValueText End If Dim gname = TryCast(type, GenericNameSyntax) If gname IsNot Nothing Then Return gname.Identifier.ValueText & "_" & gname.TypeArgumentList.Arguments.Select(Function(t) GetNameAsIdentifier(t)).Aggregate(Function(a, b) a & "_" & b) End If Dim qname = TryCast(type, QualifiedNameSyntax) If qname IsNot Nothing Then Return GetNameAsIdentifier(qname.Right) End If Return "[" & type.ToString() & "]" End Function Private Function WithBody(declaration As SyntaxNode, allowDefault As Boolean) As SyntaxNode declaration = Me.WithModifiersInternal(declaration, Me.GetModifiers(declaration) - DeclarationModifiers.Abstract) Dim method = TryCast(declaration, MethodStatementSyntax) If method IsNot Nothing Then Return SyntaxFactory.MethodBlock( kind:=If(method.IsKind(SyntaxKind.FunctionStatement), SyntaxKind.FunctionBlock, SyntaxKind.SubBlock), subOrFunctionStatement:=method, endSubOrFunctionStatement:=If(method.IsKind(SyntaxKind.FunctionStatement), SyntaxFactory.EndFunctionStatement(), SyntaxFactory.EndSubStatement())) End If Dim prop = TryCast(declaration, PropertyStatementSyntax) If prop IsNot Nothing Then prop = prop.WithModifiers(WithIsDefault(prop.Modifiers, GetIsDefault(prop.Modifiers) And allowDefault, declaration)) Dim accessors = New List(Of AccessorBlockSyntax) accessors.Add(CreateGetAccessorBlock(Nothing)) If (Not prop.Modifiers.Any(SyntaxKind.ReadOnlyKeyword)) Then accessors.Add(CreateSetAccessorBlock(prop.AsClause.Type, Nothing)) End If Return SyntaxFactory.PropertyBlock( propertyStatement:=prop, accessors:=SyntaxFactory.List(accessors), endPropertyStatement:=SyntaxFactory.EndPropertyStatement()) End If Return declaration End Function Private Shared Function GetIsDefault(modifierList As SyntaxTokenList) As Boolean Dim access As Accessibility Dim modifiers As DeclarationModifiers Dim isDefault As Boolean GetAccessibilityAndModifiers(modifierList, access, modifiers, isDefault) Return isDefault End Function Private Function WithIsDefault(modifierList As SyntaxTokenList, isDefault As Boolean, declaration As SyntaxNode) As SyntaxTokenList Dim access As Accessibility Dim modifiers As DeclarationModifiers Dim currentIsDefault As Boolean GetAccessibilityAndModifiers(modifierList, access, modifiers, currentIsDefault) If currentIsDefault <> isDefault Then Return GetModifierList(access, modifiers, declaration, GetDeclarationKind(declaration), isDefault) Else Return modifierList End If End Function Public Overrides Function ConstructorDeclaration( Optional name As String = Nothing, Optional parameters As IEnumerable(Of SyntaxNode) = Nothing, Optional accessibility As Accessibility = Nothing, Optional modifiers As DeclarationModifiers = Nothing, Optional baseConstructorArguments As IEnumerable(Of SyntaxNode) = Nothing, Optional statements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Dim stats = GetStatementList(statements) If (baseConstructorArguments IsNot Nothing) Then Dim baseCall = DirectCast(Me.ExpressionStatement(Me.InvocationExpression(Me.MemberAccessExpression(Me.BaseExpression(), SyntaxFactory.IdentifierName("New")), baseConstructorArguments)), StatementSyntax) stats = stats.Insert(0, baseCall) End If Return SyntaxFactory.ConstructorBlock( subNewStatement:=SyntaxFactory.SubNewStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_constructorModifiers, declaration:=Nothing, DeclarationKind.Constructor), parameterList:=If(parameters IsNot Nothing, SyntaxFactory.ParameterList(SyntaxFactory.SeparatedList(parameters.Cast(Of ParameterSyntax)())), SyntaxFactory.ParameterList())), statements:=stats) End Function Private Protected Overrides Function DestructorDeclaration(destructorMethod As IMethodSymbol) As SyntaxNode Return SyntaxFactory.SubBlock( SyntaxFactory.SubStatement( attributeLists:=Nothing, modifiers:=SyntaxFactory.TokenList(SyntaxFactory.Token(SyntaxKind.ProtectedKeyword), SyntaxFactory.Token(SyntaxKind.OverridesKeyword)), SyntaxFactory.Identifier("Finalize"), typeParameterList:=Nothing, SyntaxFactory.ParameterList(), asClause:=Nothing, handlesClause:=Nothing, implementsClause:=Nothing), SyntaxFactory.List(Of StatementSyntax)()) End Function Private Protected Overrides Function ClassDeclaration( isRecord As Boolean, name As String, typeParameters As IEnumerable(Of SyntaxNode), accessibility As Accessibility, modifiers As DeclarationModifiers, baseType As SyntaxNode, interfaceTypes As IEnumerable(Of SyntaxNode), members As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim itypes = If(interfaceTypes IsNot Nothing, interfaceTypes.Cast(Of TypeSyntax), Nothing) If itypes IsNot Nothing AndAlso itypes.Count = 0 Then itypes = Nothing End If Return SyntaxFactory.ClassBlock( classStatement:=SyntaxFactory.ClassStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_classModifiers, declaration:=Nothing, DeclarationKind.Class), identifier:=name.ToIdentifierToken(), typeParameterList:=GetTypeParameters(typeParameters)), [inherits]:=If(baseType IsNot Nothing, SyntaxFactory.SingletonList(SyntaxFactory.InheritsStatement(DirectCast(baseType, TypeSyntax))), Nothing), [implements]:=If(itypes IsNot Nothing, SyntaxFactory.SingletonList(SyntaxFactory.ImplementsStatement(SyntaxFactory.SeparatedList(itypes))), Nothing), members:=AsClassMembers(members)) End Function Private Function AsClassMembers(nodes As IEnumerable(Of SyntaxNode)) As SyntaxList(Of StatementSyntax) If nodes IsNot Nothing Then Return SyntaxFactory.List(nodes.Select(AddressOf AsClassMember).Where(Function(n) n IsNot Nothing)) Else Return Nothing End If End Function Private Function AsClassMember(node As SyntaxNode) As StatementSyntax Return TryCast(AsIsolatedDeclaration(node), StatementSyntax) End Function Private Protected Overrides Function StructDeclaration( isRecord As Boolean, name As String, typeParameters As IEnumerable(Of SyntaxNode), accessibility As Accessibility, modifiers As DeclarationModifiers, interfaceTypes As IEnumerable(Of SyntaxNode), members As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim itypes = If(interfaceTypes IsNot Nothing, interfaceTypes.Cast(Of TypeSyntax), Nothing) If itypes IsNot Nothing AndAlso itypes.Count = 0 Then itypes = Nothing End If Return SyntaxFactory.StructureBlock( structureStatement:=SyntaxFactory.StructureStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And VisualBasicSyntaxGeneratorInternal.s_structModifiers, declaration:=Nothing, DeclarationKind.Struct), identifier:=name.ToIdentifierToken(), typeParameterList:=GetTypeParameters(typeParameters)), [inherits]:=Nothing, [implements]:=If(itypes IsNot Nothing, SyntaxFactory.SingletonList(SyntaxFactory.ImplementsStatement(SyntaxFactory.SeparatedList(itypes))), Nothing), members:=If(members IsNot Nothing, SyntaxFactory.List(members.Cast(Of StatementSyntax)()), Nothing)) End Function Private Protected Overrides Function InterfaceDeclaration( name As String, typeParameters As IEnumerable(Of SyntaxNode), accessibility As Accessibility, interfaceTypes As IEnumerable(Of SyntaxNode), members As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim itypes = If(interfaceTypes IsNot Nothing, interfaceTypes.Cast(Of TypeSyntax), Nothing) If itypes IsNot Nothing AndAlso itypes.Count = 0 Then itypes = Nothing End If Return SyntaxFactory.InterfaceBlock( interfaceStatement:=SyntaxFactory.InterfaceStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, DeclarationModifiers.None, declaration:=Nothing, DeclarationKind.Interface), identifier:=name.ToIdentifierToken(), typeParameterList:=GetTypeParameters(typeParameters)), [inherits]:=If(itypes IsNot Nothing, SyntaxFactory.SingletonList(SyntaxFactory.InheritsStatement(SyntaxFactory.SeparatedList(itypes))), Nothing), [implements]:=Nothing, members:=AsInterfaceMembers(members)) End Function Private Function AsInterfaceMembers(nodes As IEnumerable(Of SyntaxNode)) As SyntaxList(Of StatementSyntax) If nodes IsNot Nothing Then Return CType(SyntaxFactory.List(nodes.Select(AddressOf AsInterfaceMember).Where(Function(n) n IsNot Nothing)), SyntaxList(Of StatementSyntax)) Else Return Nothing End If End Function Friend Overrides Function AsInterfaceMember(node As SyntaxNode) As SyntaxNode Select Case node.Kind Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return AsInterfaceMember(DirectCast(node, MethodBlockSyntax).BlockStatement) Case SyntaxKind.FunctionStatement, SyntaxKind.SubStatement Return Isolate(node, Function(d) DirectCast(d, MethodStatementSyntax).WithModifiers(Nothing)) Case SyntaxKind.PropertyBlock Return AsInterfaceMember(DirectCast(node, PropertyBlockSyntax).PropertyStatement) Case SyntaxKind.PropertyStatement Return Isolate( node, Function(d) Dim propertyStatement = DirectCast(d, PropertyStatementSyntax) Dim mods = SyntaxFactory.TokenList(propertyStatement.Modifiers.Where(Function(tk) tk.IsKind(SyntaxKind.ReadOnlyKeyword) Or tk.IsKind(SyntaxKind.DefaultKeyword))) Return propertyStatement.WithModifiers(mods) End Function) Case SyntaxKind.EventBlock Return AsInterfaceMember(DirectCast(node, EventBlockSyntax).EventStatement) Case SyntaxKind.EventStatement Return Isolate(node, Function(d) DirectCast(d, EventStatementSyntax).WithModifiers(Nothing).WithCustomKeyword(Nothing)) Case Else Throw ExceptionUtilities.UnexpectedValue(node.Kind) End Select End Function Public Overrides Function EnumDeclaration( name As String, Optional accessibility As Accessibility = Nothing, Optional modifiers As DeclarationModifiers = Nothing, Optional members As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Return EnumDeclaration(name, Nothing, accessibility, modifiers, members) End Function Friend Overrides Function EnumDeclaration(name As String, underlyingType As SyntaxNode, Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional modifiers As DeclarationModifiers = Nothing, Optional members As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Dim underlyingTypeClause = If(underlyingType Is Nothing, Nothing, SyntaxFactory.SimpleAsClause(DirectCast(underlyingType, TypeSyntax))) Return SyntaxFactory.EnumBlock( enumStatement:=SyntaxFactory.EnumStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And GetAllowedModifiers(SyntaxKind.EnumStatement), declaration:=Nothing, DeclarationKind.Enum), identifier:=name.ToIdentifierToken(), underlyingType:=underlyingTypeClause), members:=AsEnumMembers(members)) End Function Public Overrides Function EnumMember(name As String, Optional expression As SyntaxNode = Nothing) As SyntaxNode Return SyntaxFactory.EnumMemberDeclaration( attributeLists:=Nothing, identifier:=name.ToIdentifierToken(), initializer:=If(expression IsNot Nothing, SyntaxFactory.EqualsValue(DirectCast(expression, ExpressionSyntax)), Nothing)) End Function Private Function AsEnumMembers(nodes As IEnumerable(Of SyntaxNode)) As SyntaxList(Of StatementSyntax) If nodes IsNot Nothing Then Return SyntaxFactory.List(nodes.Select(AddressOf AsEnumMember).Where(Function(n) n IsNot Nothing)) Else Return Nothing End If End Function Private Function AsEnumMember(node As SyntaxNode) As StatementSyntax Select Case node.Kind Case SyntaxKind.IdentifierName Dim id = DirectCast(node, IdentifierNameSyntax) Return DirectCast(EnumMember(id.Identifier.ValueText), EnumMemberDeclarationSyntax) Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(node, FieldDeclarationSyntax) If fd.Declarators.Count = 1 Then Dim vd = fd.Declarators(0) If vd.Initializer IsNot Nothing AndAlso vd.Names.Count = 1 Then Return DirectCast(EnumMember(vd.Names(0).Identifier.ValueText, vd.Initializer.Value), EnumMemberDeclarationSyntax) End If End If End Select Return TryCast(node, EnumMemberDeclarationSyntax) End Function Private Protected Overrides Function DelegateDeclaration( name As String, parameters As IEnumerable(Of SyntaxNode), typeParameters As IEnumerable(Of SyntaxNode), returnType As SyntaxNode, accessibility As Accessibility, modifiers As DeclarationModifiers) As SyntaxNode Dim kind = If(returnType Is Nothing, SyntaxKind.DelegateSubStatement, SyntaxKind.DelegateFunctionStatement) Return SyntaxFactory.DelegateStatement( kind:=kind, attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And GetAllowedModifiers(kind), declaration:=Nothing, DeclarationKind.Delegate), subOrFunctionKeyword:=If(kind = SyntaxKind.DelegateSubStatement, SyntaxFactory.Token(SyntaxKind.SubKeyword), SyntaxFactory.Token(SyntaxKind.FunctionKeyword)), identifier:=name.ToIdentifierToken(), typeParameterList:=GetTypeParameters(typeParameters), parameterList:=GetParameterList(parameters), asClause:=If(kind = SyntaxKind.DelegateFunctionStatement, SyntaxFactory.SimpleAsClause(DirectCast(returnType, TypeSyntax)), Nothing)) End Function Public Overrides Function CompilationUnit(declarations As IEnumerable(Of SyntaxNode)) As SyntaxNode Return SyntaxFactory.CompilationUnit().WithImports(AsImports(declarations)).WithMembers(AsNamespaceMembers(declarations)) End Function Private Function AsImports(declarations As IEnumerable(Of SyntaxNode)) As SyntaxList(Of ImportsStatementSyntax) Return If(declarations Is Nothing, Nothing, SyntaxFactory.List(declarations.Select(AddressOf AsNamespaceImport).OfType(Of ImportsStatementSyntax)())) End Function Private Function AsNamespaceImport(node As SyntaxNode) As SyntaxNode Dim name = TryCast(node, NameSyntax) If name IsNot Nothing Then Return Me.NamespaceImportDeclaration(name) End If Return TryCast(node, ImportsStatementSyntax) End Function Private Shared Function AsNamespaceMembers(declarations As IEnumerable(Of SyntaxNode)) As SyntaxList(Of StatementSyntax) Return If(declarations Is Nothing, Nothing, SyntaxFactory.List(declarations.OfType(Of StatementSyntax)().Where(Function(s) TypeOf s IsNot ImportsStatementSyntax))) End Function Public Overrides Function NamespaceImportDeclaration(name As SyntaxNode) As SyntaxNode Return SyntaxFactory.ImportsStatement(SyntaxFactory.SingletonSeparatedList(Of ImportsClauseSyntax)(SyntaxFactory.SimpleImportsClause(DirectCast(name, NameSyntax)))) End Function Public Overrides Function AliasImportDeclaration(aliasIdentifierName As String, name As SyntaxNode) As SyntaxNode If TypeOf name Is NameSyntax Then Return SyntaxFactory.ImportsStatement(SyntaxFactory.SeparatedList(Of ImportsClauseSyntax).Add( SyntaxFactory.SimpleImportsClause( SyntaxFactory.ImportAliasClause(aliasIdentifierName), CType(name, NameSyntax)))) End If Throw New ArgumentException("name is not a NameSyntax.", NameOf(name)) End Function Public Overrides Function NamespaceDeclaration(name As SyntaxNode, nestedDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim imps As IEnumerable(Of StatementSyntax) = AsImports(nestedDeclarations) Dim members As IEnumerable(Of StatementSyntax) = AsNamespaceMembers(nestedDeclarations) ' put imports at start Dim statements = imps.Concat(members) Return SyntaxFactory.NamespaceBlock( SyntaxFactory.NamespaceStatement(DirectCast(name, NameSyntax)), members:=SyntaxFactory.List(statements)) End Function Public Overrides Function Attribute(name As SyntaxNode, Optional attributeArguments As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Dim attr = SyntaxFactory.Attribute( target:=Nothing, name:=DirectCast(name, TypeSyntax), argumentList:=AsArgumentList(attributeArguments)) Return AsAttributeList(attr) End Function Private Function AsArgumentList(arguments As IEnumerable(Of SyntaxNode)) As ArgumentListSyntax If arguments IsNot Nothing Then Return SyntaxFactory.ArgumentList(SyntaxFactory.SeparatedList(arguments.Select(AddressOf AsArgument))) Else Return Nothing End If End Function Public Overrides Function AttributeArgument(name As String, expression As SyntaxNode) As SyntaxNode Return Argument(name, RefKind.None, expression) End Function Public Overrides Function ClearTrivia(Of TNode As SyntaxNode)(node As TNode) As TNode If node IsNot Nothing Then Return node.WithLeadingTrivia(SyntaxFactory.ElasticMarker).WithTrailingTrivia(SyntaxFactory.ElasticMarker) Else Return Nothing End If End Function Private Function AsAttributeLists(attributes As IEnumerable(Of SyntaxNode)) As SyntaxList(Of AttributeListSyntax) If attributes IsNot Nothing Then Return SyntaxFactory.List(attributes.Select(AddressOf AsAttributeList)) Else Return Nothing End If End Function Private Function AsAttributeList(node As SyntaxNode) As AttributeListSyntax Dim attr = TryCast(node, AttributeSyntax) If attr IsNot Nothing Then Return SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(WithNoTarget(attr))) Else Return WithNoTargets(DirectCast(node, AttributeListSyntax)) End If End Function Private Overloads Function WithNoTargets(attrs As AttributeListSyntax) As AttributeListSyntax If (attrs.Attributes.Any(Function(a) a.Target IsNot Nothing)) Then Return attrs.WithAttributes(SyntaxFactory.SeparatedList(attrs.Attributes.Select(AddressOf WithAssemblyTarget))) Else Return attrs End If End Function Private Shared Function WithNoTarget(attr As AttributeSyntax) As AttributeSyntax Return attr.WithTarget(Nothing) End Function Friend Overrides Function GetPrimaryConstructorParameterList(declaration As SyntaxNode) As SyntaxNode Return Nothing End Function Friend Overrides Function GetTypeInheritance(declaration As SyntaxNode) As ImmutableArray(Of SyntaxNode) Dim typeDecl = TryCast(declaration, TypeBlockSyntax) If typeDecl Is Nothing Then Return ImmutableArray(Of SyntaxNode).Empty End If Dim builder = ArrayBuilder(Of SyntaxNode).GetInstance() builder.AddRange(typeDecl.Inherits) builder.AddRange(typeDecl.Implements) Return builder.ToImmutableAndFree() End Function Public Overrides Function GetAttributes(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) If declaration.IsKind(SyntaxKind.CompilationUnit) Then ' CompilationUnit syntaxes represent attribute lists in a way that we can't get a single AttributeList for all of the attributes in all cases. ' However, some consumers of this API assume that all returned values are children of "declaration", so if there's one attribute list, we'll use ' that value directly if possible. Dim compilationUnit = DirectCast(declaration, CompilationUnitSyntax) If compilationUnit.Attributes.Count = 1 Then Return compilationUnit.Attributes(0).AttributeLists End If End If Return Flatten(declaration.GetAttributeLists()) End Function Public Overrides Function InsertAttributes(declaration As SyntaxNode, index As Integer, attributes As IEnumerable(Of SyntaxNode)) As SyntaxNode Return Isolate(declaration, Function(d) InsertAttributesInternal(d, index, attributes)) End Function Private Function InsertAttributesInternal(declaration As SyntaxNode, index As Integer, attributes As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim newAttributes = AsAttributeLists(attributes) Dim existingAttributes = Me.GetAttributes(declaration) If index >= 0 AndAlso index < existingAttributes.Count Then Return Me.InsertNodesBefore(declaration, existingAttributes(index), WithRequiredTargetSpecifier(newAttributes, declaration)) ElseIf existingAttributes.Count > 0 Then Return Me.InsertNodesAfter(declaration, existingAttributes(existingAttributes.Count - 1), WithRequiredTargetSpecifier(newAttributes, declaration)) Else Dim lists = GetAttributeLists(declaration) Return Me.WithAttributeLists(declaration, lists.AddRange(AsAttributeLists(attributes))) End If End Function Private Shared Function HasAssemblyTarget(attr As AttributeSyntax) As Boolean Return attr.Target IsNot Nothing AndAlso attr.Target.AttributeModifier.IsKind(SyntaxKind.AssemblyKeyword) End Function Private Overloads Function WithAssemblyTargets(attrs As AttributeListSyntax) As AttributeListSyntax If attrs.Attributes.Any(Function(a) Not HasAssemblyTarget(a)) Then Return attrs.WithAttributes(SyntaxFactory.SeparatedList(attrs.Attributes.Select(AddressOf WithAssemblyTarget))) Else Return attrs End If End Function Private Overloads Function WithAssemblyTarget(attr As AttributeSyntax) As AttributeSyntax If Not HasAssemblyTarget(attr) Then Return attr.WithTarget(SyntaxFactory.AttributeTarget(SyntaxFactory.Token(SyntaxKind.AssemblyKeyword))) Else Return attr End If End Function Private Function WithRequiredTargetSpecifier(attributes As SyntaxList(Of AttributeListSyntax), declaration As SyntaxNode) As SyntaxList(Of AttributeListSyntax) If Not declaration.IsKind(SyntaxKind.CompilationUnit) Then Return attributes End If Return SyntaxFactory.List(attributes.Select(AddressOf WithAssemblyTargets)) End Function Public Overrides Function GetReturnAttributes(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Return Flatten(GetReturnAttributeLists(declaration)) End Function Public Overrides Function InsertReturnAttributes(declaration As SyntaxNode, index As Integer, attributes As IEnumerable(Of SyntaxNode)) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.FunctionBlock, SyntaxKind.FunctionStatement, SyntaxKind.DelegateFunctionStatement Return Isolate(declaration, Function(d) InsertReturnAttributesInternal(d, index, attributes)) Case Else Return declaration End Select End Function Private Function InsertReturnAttributesInternal(declaration As SyntaxNode, index As Integer, attributes As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim newAttributes = AsAttributeLists(attributes) Dim existingReturnAttributes = Me.GetReturnAttributes(declaration) If index >= 0 AndAlso index < existingReturnAttributes.Count Then Return Me.InsertNodesBefore(declaration, existingReturnAttributes(index), newAttributes) ElseIf existingReturnAttributes.Count > 0 Then Return Me.InsertNodesAfter(declaration, existingReturnAttributes(existingReturnAttributes.Count - 1), newAttributes) Else Dim lists = GetReturnAttributeLists(declaration) Dim newLists = lists.AddRange(newAttributes) Return WithReturnAttributeLists(declaration, newLists) End If End Function Private Shared Function GetReturnAttributeLists(declaration As SyntaxNode) As SyntaxList(Of AttributeListSyntax) Dim asClause = GetAsClause(declaration) If asClause IsNot Nothing Then Select Case declaration.Kind() Case SyntaxKind.FunctionBlock, SyntaxKind.FunctionStatement, SyntaxKind.DelegateFunctionStatement Return asClause.Attributes End Select End If Return Nothing End Function Private Shared Function WithReturnAttributeLists(declaration As SyntaxNode, lists As IEnumerable(Of AttributeListSyntax)) As SyntaxNode If declaration Is Nothing Then Return Nothing End If Select Case declaration.Kind() Case SyntaxKind.FunctionBlock Dim fb = DirectCast(declaration, MethodBlockSyntax) Dim asClause = DirectCast(WithReturnAttributeLists(GetAsClause(declaration), lists), SimpleAsClauseSyntax) Return fb.WithSubOrFunctionStatement(fb.SubOrFunctionStatement.WithAsClause(asClause)) Case SyntaxKind.FunctionStatement Dim ms = DirectCast(declaration, MethodStatementSyntax) Dim asClause = DirectCast(WithReturnAttributeLists(GetAsClause(declaration), lists), SimpleAsClauseSyntax) Return ms.WithAsClause(asClause) Case SyntaxKind.DelegateFunctionStatement Dim df = DirectCast(declaration, DelegateStatementSyntax) Dim asClause = DirectCast(WithReturnAttributeLists(GetAsClause(declaration), lists), SimpleAsClauseSyntax) Return df.WithAsClause(asClause) Case SyntaxKind.SimpleAsClause Return DirectCast(declaration, SimpleAsClauseSyntax).WithAttributeLists(SyntaxFactory.List(lists)) Case Else Return Nothing End Select End Function Private Function WithAttributeLists(node As SyntaxNode, lists As IEnumerable(Of AttributeListSyntax)) As SyntaxNode Dim arg = SyntaxFactory.List(lists) Select Case node.Kind Case SyntaxKind.CompilationUnit 'convert to assembly target arg = SyntaxFactory.List(lists.Select(Function(lst) Me.WithAssemblyTargets(lst))) ' add as single attributes statement Return DirectCast(node, CompilationUnitSyntax).WithAttributes(SyntaxFactory.SingletonList(SyntaxFactory.AttributesStatement(arg))) Case SyntaxKind.ClassBlock Return DirectCast(node, ClassBlockSyntax).WithClassStatement(DirectCast(node, ClassBlockSyntax).ClassStatement.WithAttributeLists(arg)) Case SyntaxKind.ClassStatement Return DirectCast(node, ClassStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.StructureBlock Return DirectCast(node, StructureBlockSyntax).WithStructureStatement(DirectCast(node, StructureBlockSyntax).StructureStatement.WithAttributeLists(arg)) Case SyntaxKind.StructureStatement Return DirectCast(node, StructureStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.InterfaceBlock Return DirectCast(node, InterfaceBlockSyntax).WithInterfaceStatement(DirectCast(node, InterfaceBlockSyntax).InterfaceStatement.WithAttributeLists(arg)) Case SyntaxKind.InterfaceStatement Return DirectCast(node, InterfaceStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.EnumBlock Return DirectCast(node, EnumBlockSyntax).WithEnumStatement(DirectCast(node, EnumBlockSyntax).EnumStatement.WithAttributeLists(arg)) Case SyntaxKind.EnumStatement Return DirectCast(node, EnumStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.EnumMemberDeclaration Return DirectCast(node, EnumMemberDeclarationSyntax).WithAttributeLists(arg) Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement Return DirectCast(node, DelegateStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.FieldDeclaration Return DirectCast(node, FieldDeclarationSyntax).WithAttributeLists(arg) Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return DirectCast(node, MethodBlockSyntax).WithSubOrFunctionStatement(DirectCast(node, MethodBlockSyntax).SubOrFunctionStatement.WithAttributeLists(arg)) Case SyntaxKind.FunctionStatement, SyntaxKind.SubStatement Return DirectCast(node, MethodStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.ConstructorBlock Return DirectCast(node, ConstructorBlockSyntax).WithSubNewStatement(DirectCast(node, ConstructorBlockSyntax).SubNewStatement.WithAttributeLists(arg)) Case SyntaxKind.SubNewStatement Return DirectCast(node, SubNewStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.Parameter Return DirectCast(node, ParameterSyntax).WithAttributeLists(arg) Case SyntaxKind.PropertyBlock Return DirectCast(node, PropertyBlockSyntax).WithPropertyStatement(DirectCast(node, PropertyBlockSyntax).PropertyStatement.WithAttributeLists(arg)) Case SyntaxKind.PropertyStatement Return DirectCast(node, PropertyStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.OperatorBlock Return DirectCast(node, OperatorBlockSyntax).WithOperatorStatement(DirectCast(node, OperatorBlockSyntax).OperatorStatement.WithAttributeLists(arg)) Case SyntaxKind.OperatorStatement Return DirectCast(node, OperatorStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.EventBlock Return DirectCast(node, EventBlockSyntax).WithEventStatement(DirectCast(node, EventBlockSyntax).EventStatement.WithAttributeLists(arg)) Case SyntaxKind.EventStatement Return DirectCast(node, EventStatementSyntax).WithAttributeLists(arg) Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock, SyntaxKind.AddHandlerAccessorBlock, SyntaxKind.RemoveHandlerAccessorBlock, SyntaxKind.RaiseEventAccessorBlock Return DirectCast(node, AccessorBlockSyntax).WithAccessorStatement(DirectCast(node, AccessorBlockSyntax).AccessorStatement.WithAttributeLists(arg)) Case SyntaxKind.GetAccessorStatement, SyntaxKind.SetAccessorStatement, SyntaxKind.AddHandlerAccessorStatement, SyntaxKind.RemoveHandlerAccessorStatement, SyntaxKind.RaiseEventAccessorStatement Return DirectCast(node, AccessorStatementSyntax).WithAttributeLists(arg) Case Else Return node End Select End Function Public Overrides Function GetDeclarationKind(declaration As SyntaxNode) As DeclarationKind Select Case declaration.Kind Case SyntaxKind.CompilationUnit Return DeclarationKind.CompilationUnit Case SyntaxKind.NamespaceBlock Return DeclarationKind.Namespace Case SyntaxKind.ImportsStatement Return DeclarationKind.NamespaceImport Case SyntaxKind.ClassBlock Return DeclarationKind.Class Case SyntaxKind.StructureBlock Return DeclarationKind.Struct Case SyntaxKind.InterfaceBlock Return DeclarationKind.Interface Case SyntaxKind.EnumBlock Return DeclarationKind.Enum Case SyntaxKind.EnumMemberDeclaration Return DeclarationKind.EnumMember Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement Return DeclarationKind.Delegate Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return DeclarationKind.Method Case SyntaxKind.FunctionStatement If Not IsChildOf(declaration, SyntaxKind.FunctionBlock) Then Return DeclarationKind.Method End If Case SyntaxKind.SubStatement If Not IsChildOf(declaration, SyntaxKind.SubBlock) Then Return DeclarationKind.Method End If Case SyntaxKind.ConstructorBlock Return DeclarationKind.Constructor Case SyntaxKind.PropertyBlock If IsIndexer(declaration) Then Return DeclarationKind.Indexer Else Return DeclarationKind.Property End If Case SyntaxKind.PropertyStatement If Not IsChildOf(declaration, SyntaxKind.PropertyBlock) Then If IsIndexer(declaration) Then Return DeclarationKind.Indexer Else Return DeclarationKind.Property End If End If Case SyntaxKind.OperatorBlock Return DeclarationKind.Operator Case SyntaxKind.OperatorStatement If Not IsChildOf(declaration, SyntaxKind.OperatorBlock) Then Return DeclarationKind.Operator End If Case SyntaxKind.EventBlock Return DeclarationKind.CustomEvent Case SyntaxKind.EventStatement If Not IsChildOf(declaration, SyntaxKind.EventBlock) Then Return DeclarationKind.Event End If Case SyntaxKind.Parameter Return DeclarationKind.Parameter Case SyntaxKind.FieldDeclaration Return DeclarationKind.Field Case SyntaxKind.LocalDeclarationStatement If GetDeclarationCount(declaration) = 1 Then Return DeclarationKind.Variable End If Case SyntaxKind.ModifiedIdentifier If IsChildOf(declaration, SyntaxKind.VariableDeclarator) Then If IsChildOf(declaration.Parent, SyntaxKind.FieldDeclaration) And GetDeclarationCount(declaration.Parent.Parent) > 1 Then Return DeclarationKind.Field ElseIf IsChildOf(declaration.Parent, SyntaxKind.LocalDeclarationStatement) And GetDeclarationCount(declaration.Parent.Parent) > 1 Then Return DeclarationKind.Variable End If End If Case SyntaxKind.Attribute Dim list = TryCast(declaration.Parent, AttributeListSyntax) If list Is Nothing OrElse list.Attributes.Count > 1 Then Return DeclarationKind.Attribute End If Case SyntaxKind.AttributeList Dim list = DirectCast(declaration, AttributeListSyntax) If list.Attributes.Count = 1 Then Return DeclarationKind.Attribute End If Case SyntaxKind.GetAccessorBlock Return DeclarationKind.GetAccessor Case SyntaxKind.SetAccessorBlock Return DeclarationKind.SetAccessor Case SyntaxKind.AddHandlerAccessorBlock Return DeclarationKind.AddAccessor Case SyntaxKind.RemoveHandlerAccessorBlock Return DeclarationKind.RemoveAccessor Case SyntaxKind.RaiseEventAccessorBlock Return DeclarationKind.RaiseAccessor End Select Return DeclarationKind.None End Function Private Shared Function IsIndexer(declaration As SyntaxNode) As Boolean Select Case declaration.Kind Case SyntaxKind.PropertyBlock Dim p = DirectCast(declaration, PropertyBlockSyntax).PropertyStatement Return p.ParameterList IsNot Nothing AndAlso p.ParameterList.Parameters.Count > 0 AndAlso p.Modifiers.Any(SyntaxKind.DefaultKeyword) Case SyntaxKind.PropertyStatement If Not IsChildOf(declaration, SyntaxKind.PropertyBlock) Then Dim p = DirectCast(declaration, PropertyStatementSyntax) Return p.ParameterList IsNot Nothing AndAlso p.ParameterList.Parameters.Count > 0 AndAlso p.Modifiers.Any(SyntaxKind.DefaultKeyword) End If End Select Return False End Function Private Shared Function GetDeclarationCount(node As SyntaxNode) As Integer Return VisualBasicSyntaxFacts.GetDeclarationCount(node) End Function Private Shared Function IsChildOf(node As SyntaxNode, kind As SyntaxKind) As Boolean Return VisualBasicSyntaxFacts.IsChildOf(node, kind) End Function Private Shared Function IsChildOfVariableDeclaration(node As SyntaxNode) As Boolean Return VisualBasicSyntaxFacts.IsChildOfVariableDeclaration(node) End Function Private Shared Function Isolate(declaration As SyntaxNode, editor As Func(Of SyntaxNode, SyntaxNode)) As SyntaxNode Dim isolated = AsIsolatedDeclaration(declaration) Return PreserveTrivia(isolated, editor) End Function Private Shared Function GetFullDeclaration(declaration As SyntaxNode) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.ModifiedIdentifier If IsChildOf(declaration, SyntaxKind.VariableDeclarator) Then Return GetFullDeclaration(declaration.Parent) End If Case SyntaxKind.VariableDeclarator If IsChildOfVariableDeclaration(declaration) Then Return declaration.Parent End If Case SyntaxKind.Attribute If declaration.Parent IsNot Nothing Then Return declaration.Parent End If Case SyntaxKind.SimpleImportsClause, SyntaxKind.XmlNamespaceImportsClause If declaration.Parent IsNot Nothing Then Return declaration.Parent End If End Select Return declaration End Function Private Shared Function AsIsolatedDeclaration(declaration As SyntaxNode) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.ModifiedIdentifier Dim full = GetFullDeclaration(declaration) If full IsNot declaration Then Return WithSingleVariable(full, DirectCast(declaration, ModifiedIdentifierSyntax)) End If Case SyntaxKind.Attribute Dim list = TryCast(declaration.Parent, AttributeListSyntax) If list IsNot Nothing Then Return list.WithAttributes(SyntaxFactory.SingletonSeparatedList(DirectCast(declaration, AttributeSyntax))) End If Case SyntaxKind.SimpleImportsClause, SyntaxKind.XmlNamespaceImportsClause Dim stmt = TryCast(declaration.Parent, ImportsStatementSyntax) If stmt IsNot Nothing Then Return stmt.WithImportsClauses(SyntaxFactory.SingletonSeparatedList(DirectCast(declaration, ImportsClauseSyntax))) End If End Select Return declaration End Function Private Shared Function WithSingleVariable(declaration As SyntaxNode, variable As ModifiedIdentifierSyntax) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) Return ReplaceWithTrivia(declaration, fd.Declarators(0), fd.Declarators(0).WithNames(SyntaxFactory.SingletonSeparatedList(variable))) Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) Return ReplaceWithTrivia(declaration, ld.Declarators(0), ld.Declarators(0).WithNames(SyntaxFactory.SingletonSeparatedList(variable))) Case SyntaxKind.VariableDeclarator Dim vd = DirectCast(declaration, VariableDeclaratorSyntax) Return vd.WithNames(SyntaxFactory.SingletonSeparatedList(variable)) Case Else Return declaration End Select End Function Public Overrides Function GetName(declaration As SyntaxNode) As String Select Case declaration.Kind Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).BlockStatement.Identifier.ValueText Case SyntaxKind.StructureBlock Return DirectCast(declaration, StructureBlockSyntax).BlockStatement.Identifier.ValueText Case SyntaxKind.InterfaceBlock Return DirectCast(declaration, InterfaceBlockSyntax).BlockStatement.Identifier.ValueText Case SyntaxKind.EnumBlock Return DirectCast(declaration, EnumBlockSyntax).EnumStatement.Identifier.ValueText Case SyntaxKind.EnumMemberDeclaration Return DirectCast(declaration, EnumMemberDeclarationSyntax).Identifier.ValueText Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement Return DirectCast(declaration, DelegateStatementSyntax).Identifier.ValueText Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return DirectCast(declaration, MethodBlockSyntax).SubOrFunctionStatement.Identifier.ValueText Case SyntaxKind.FunctionStatement, SyntaxKind.SubStatement Return DirectCast(declaration, MethodStatementSyntax).Identifier.ValueText Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.Identifier.ValueText Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).Identifier.ValueText Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).EventStatement.Identifier.ValueText Case SyntaxKind.EventStatement Return DirectCast(declaration, EventStatementSyntax).Identifier.ValueText Case SyntaxKind.EventStatement Return DirectCast(declaration, EventStatementSyntax).Identifier.ValueText Case SyntaxKind.Parameter Return DirectCast(declaration, ParameterSyntax).Identifier.Identifier.ValueText Case SyntaxKind.NamespaceBlock Return DirectCast(declaration, NamespaceBlockSyntax).NamespaceStatement.Name.ToString() Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) If GetDeclarationCount(fd) = 1 Then Return fd.Declarators(0).Names(0).Identifier.ValueText End If Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) If GetDeclarationCount(ld) = 1 Then Return ld.Declarators(0).Names(0).Identifier.ValueText End If Case SyntaxKind.VariableDeclarator Dim vd = DirectCast(declaration, VariableDeclaratorSyntax) If vd.Names.Count = 1 Then Return vd.Names(0).Identifier.ValueText End If Case SyntaxKind.ModifiedIdentifier Return DirectCast(declaration, ModifiedIdentifierSyntax).Identifier.ValueText Case SyntaxKind.Attribute Return DirectCast(declaration, AttributeSyntax).Name.ToString() Case SyntaxKind.AttributeList Dim list = DirectCast(declaration, AttributeListSyntax) If list.Attributes.Count = 1 Then Return list.Attributes(0).Name.ToString() End If Case SyntaxKind.ImportsStatement Dim stmt = DirectCast(declaration, ImportsStatementSyntax) If stmt.ImportsClauses.Count = 1 Then Return GetName(stmt.ImportsClauses(0)) End If Case SyntaxKind.SimpleImportsClause Return DirectCast(declaration, SimpleImportsClauseSyntax).Name.ToString() End Select Return String.Empty End Function Public Overrides Function WithName(declaration As SyntaxNode, name As String) As SyntaxNode Return Isolate(declaration, Function(d) WithNameInternal(d, name)) End Function Private Function WithNameInternal(declaration As SyntaxNode, name As String) As SyntaxNode Dim id = name.ToIdentifierToken() Select Case declaration.Kind Case SyntaxKind.ClassBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, ClassBlockSyntax).BlockStatement.Identifier, id) Case SyntaxKind.StructureBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, StructureBlockSyntax).BlockStatement.Identifier, id) Case SyntaxKind.InterfaceBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, InterfaceBlockSyntax).BlockStatement.Identifier, id) Case SyntaxKind.EnumBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, EnumBlockSyntax).EnumStatement.Identifier, id) Case SyntaxKind.EnumMemberDeclaration Return ReplaceWithTrivia(declaration, DirectCast(declaration, EnumMemberDeclarationSyntax).Identifier, id) Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement Return ReplaceWithTrivia(declaration, DirectCast(declaration, DelegateStatementSyntax).Identifier, id) Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, MethodBlockSyntax).SubOrFunctionStatement.Identifier, id) Case SyntaxKind.FunctionStatement, SyntaxKind.SubStatement Return ReplaceWithTrivia(declaration, DirectCast(declaration, MethodStatementSyntax).Identifier, id) Case SyntaxKind.PropertyBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.Identifier, id) Case SyntaxKind.PropertyStatement Return ReplaceWithTrivia(declaration, DirectCast(declaration, PropertyStatementSyntax).Identifier, id) Case SyntaxKind.EventBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, EventBlockSyntax).EventStatement.Identifier, id) Case SyntaxKind.EventStatement Return ReplaceWithTrivia(declaration, DirectCast(declaration, EventStatementSyntax).Identifier, id) Case SyntaxKind.EventStatement Return ReplaceWithTrivia(declaration, DirectCast(declaration, EventStatementSyntax).Identifier, id) Case SyntaxKind.Parameter Return ReplaceWithTrivia(declaration, DirectCast(declaration, ParameterSyntax).Identifier.Identifier, id) Case SyntaxKind.NamespaceBlock Return ReplaceWithTrivia(declaration, DirectCast(declaration, NamespaceBlockSyntax).NamespaceStatement.Name, Me.DottedName(name)) Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) If ld.Declarators.Count = 1 AndAlso ld.Declarators(0).Names.Count = 1 Then Return ReplaceWithTrivia(declaration, ld.Declarators(0).Names(0).Identifier, id) End If Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) If fd.Declarators.Count = 1 AndAlso fd.Declarators(0).Names.Count = 1 Then Return ReplaceWithTrivia(declaration, fd.Declarators(0).Names(0).Identifier, id) End If Case SyntaxKind.Attribute Return ReplaceWithTrivia(declaration, DirectCast(declaration, AttributeSyntax).Name, Me.DottedName(name)) Case SyntaxKind.AttributeList Dim al = DirectCast(declaration, AttributeListSyntax) If al.Attributes.Count = 1 Then Return ReplaceWithTrivia(declaration, al.Attributes(0).Name, Me.DottedName(name)) End If Case SyntaxKind.ImportsStatement Dim stmt = DirectCast(declaration, ImportsStatementSyntax) If stmt.ImportsClauses.Count = 1 Then Dim clause = stmt.ImportsClauses(0) Select Case clause.Kind Case SyntaxKind.SimpleImportsClause Return ReplaceWithTrivia(declaration, DirectCast(clause, SimpleImportsClauseSyntax).Name, Me.DottedName(name)) End Select End If End Select Return declaration End Function Public Overrides Function [GetType](declaration As SyntaxNode) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.ModifiedIdentifier Dim vd = TryCast(declaration.Parent, VariableDeclaratorSyntax) If vd IsNot Nothing Then Return [GetType](vd) End If Case Else Dim asClause = GetAsClause(declaration) If asClause IsNot Nothing Then Return asClause.Type End If End Select Return Nothing End Function Public Overrides Function WithType(declaration As SyntaxNode, type As SyntaxNode) As SyntaxNode Return Isolate(declaration, Function(d) WithTypeInternal(d, type)) End Function Private Function WithTypeInternal(declaration As SyntaxNode, type As SyntaxNode) As SyntaxNode If type Is Nothing Then declaration = AsSub(declaration) Else declaration = AsFunction(declaration) End If Dim asClause = GetAsClause(declaration) If asClause IsNot Nothing Then If type IsNot Nothing Then Select Case asClause.Kind Case SyntaxKind.SimpleAsClause asClause = DirectCast(asClause, SimpleAsClauseSyntax).WithType(DirectCast(type, TypeSyntax)) Case SyntaxKind.AsNewClause Dim asNew = DirectCast(asClause, AsNewClauseSyntax) Select Case asNew.NewExpression.Kind Case SyntaxKind.ObjectCreationExpression asClause = asNew.WithNewExpression(DirectCast(asNew.NewExpression, ObjectCreationExpressionSyntax).WithType(DirectCast(type, TypeSyntax))) Case SyntaxKind.ArrayCreationExpression asClause = asNew.WithNewExpression(DirectCast(asNew.NewExpression, ArrayCreationExpressionSyntax).WithType(DirectCast(type, TypeSyntax))) End Select End Select Else asClause = Nothing End If ElseIf type IsNot Nothing Then asClause = SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)) End If Return WithAsClause(declaration, asClause) End Function Private Shared Function GetAsClause(declaration As SyntaxNode) As AsClauseSyntax Select Case declaration.Kind Case SyntaxKind.DelegateFunctionStatement Return DirectCast(declaration, DelegateStatementSyntax).AsClause Case SyntaxKind.FunctionBlock Return DirectCast(declaration, MethodBlockSyntax).SubOrFunctionStatement.AsClause Case SyntaxKind.FunctionStatement Return DirectCast(declaration, MethodStatementSyntax).AsClause Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.AsClause Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).AsClause Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).EventStatement.AsClause Case SyntaxKind.EventStatement Return DirectCast(declaration, EventStatementSyntax).AsClause Case SyntaxKind.Parameter Return DirectCast(declaration, ParameterSyntax).AsClause Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) If fd.Declarators.Count = 1 Then Return fd.Declarators(0).AsClause End If Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) If ld.Declarators.Count = 1 Then Return ld.Declarators(0).AsClause End If Case SyntaxKind.VariableDeclarator Return DirectCast(declaration, VariableDeclaratorSyntax).AsClause Case SyntaxKind.ModifiedIdentifier Dim vd = TryCast(declaration.Parent, VariableDeclaratorSyntax) If vd IsNot Nothing Then Return vd.AsClause End If End Select Return Nothing End Function Private Shared Function WithAsClause(declaration As SyntaxNode, asClause As AsClauseSyntax) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.DelegateFunctionStatement Return DirectCast(declaration, DelegateStatementSyntax).WithAsClause(DirectCast(asClause, SimpleAsClauseSyntax)) Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) If fd.Declarators.Count = 1 Then Return ReplaceWithTrivia(declaration, fd.Declarators(0), fd.Declarators(0).WithAsClause(asClause)) End If Case SyntaxKind.FunctionBlock Return DirectCast(declaration, MethodBlockSyntax).WithSubOrFunctionStatement(DirectCast(declaration, MethodBlockSyntax).SubOrFunctionStatement.WithAsClause(DirectCast(asClause, SimpleAsClauseSyntax))) Case SyntaxKind.FunctionStatement Return DirectCast(declaration, MethodStatementSyntax).WithAsClause(DirectCast(asClause, SimpleAsClauseSyntax)) Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).WithPropertyStatement(DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.WithAsClause(asClause)) Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).WithAsClause(asClause) Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).WithEventStatement(DirectCast(declaration, EventBlockSyntax).EventStatement.WithAsClause(DirectCast(asClause, SimpleAsClauseSyntax))) Case SyntaxKind.EventStatement Return DirectCast(declaration, EventStatementSyntax).WithAsClause(DirectCast(asClause, SimpleAsClauseSyntax)) Case SyntaxKind.Parameter Return DirectCast(declaration, ParameterSyntax).WithAsClause(DirectCast(asClause, SimpleAsClauseSyntax)) Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) If ld.Declarators.Count = 1 Then Return ReplaceWithTrivia(declaration, ld.Declarators(0), ld.Declarators(0).WithAsClause(asClause)) End If Case SyntaxKind.VariableDeclarator Return DirectCast(declaration, VariableDeclaratorSyntax).WithAsClause(asClause) End Select Return declaration End Function Private Function AsFunction(declaration As SyntaxNode) As SyntaxNode Return Isolate(declaration, AddressOf AsFunctionInternal) End Function Private Function AsFunctionInternal(declaration As SyntaxNode) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.SubBlock Dim sb = DirectCast(declaration, MethodBlockSyntax) Return SyntaxFactory.MethodBlock( SyntaxKind.FunctionBlock, DirectCast(AsFunction(sb.BlockStatement), MethodStatementSyntax), sb.Statements, SyntaxFactory.EndBlockStatement( SyntaxKind.EndFunctionStatement, sb.EndBlockStatement.EndKeyword, SyntaxFactory.Token(sb.EndBlockStatement.BlockKeyword.LeadingTrivia, SyntaxKind.FunctionKeyword, sb.EndBlockStatement.BlockKeyword.TrailingTrivia) )) Case SyntaxKind.SubStatement Dim ss = DirectCast(declaration, MethodStatementSyntax) Return SyntaxFactory.MethodStatement( SyntaxKind.FunctionStatement, ss.AttributeLists, ss.Modifiers, SyntaxFactory.Token(ss.DeclarationKeyword.LeadingTrivia, SyntaxKind.FunctionKeyword, ss.DeclarationKeyword.TrailingTrivia), ss.Identifier, ss.TypeParameterList, ss.ParameterList, SyntaxFactory.SimpleAsClause(SyntaxFactory.IdentifierName("Object")), ss.HandlesClause, ss.ImplementsClause) Case SyntaxKind.DelegateSubStatement Dim ds = DirectCast(declaration, DelegateStatementSyntax) Return SyntaxFactory.DelegateStatement( SyntaxKind.DelegateFunctionStatement, ds.AttributeLists, ds.Modifiers, SyntaxFactory.Token(ds.DeclarationKeyword.LeadingTrivia, SyntaxKind.FunctionKeyword, ds.DeclarationKeyword.TrailingTrivia), ds.Identifier, ds.TypeParameterList, ds.ParameterList, SyntaxFactory.SimpleAsClause(SyntaxFactory.IdentifierName("Object"))) Case SyntaxKind.MultiLineSubLambdaExpression Dim ml = DirectCast(declaration, MultiLineLambdaExpressionSyntax) Return SyntaxFactory.MultiLineLambdaExpression( SyntaxKind.MultiLineFunctionLambdaExpression, DirectCast(AsFunction(ml.SubOrFunctionHeader), LambdaHeaderSyntax), ml.Statements, SyntaxFactory.EndBlockStatement( SyntaxKind.EndFunctionStatement, ml.EndSubOrFunctionStatement.EndKeyword, SyntaxFactory.Token(ml.EndSubOrFunctionStatement.BlockKeyword.LeadingTrivia, SyntaxKind.FunctionKeyword, ml.EndSubOrFunctionStatement.BlockKeyword.TrailingTrivia) )) Case SyntaxKind.SingleLineSubLambdaExpression Dim sl = DirectCast(declaration, SingleLineLambdaExpressionSyntax) Return SyntaxFactory.SingleLineLambdaExpression( SyntaxKind.SingleLineFunctionLambdaExpression, DirectCast(AsFunction(sl.SubOrFunctionHeader), LambdaHeaderSyntax), sl.Body) Case SyntaxKind.SubLambdaHeader Dim lh = DirectCast(declaration, LambdaHeaderSyntax) Return SyntaxFactory.LambdaHeader( SyntaxKind.FunctionLambdaHeader, lh.AttributeLists, lh.Modifiers, SyntaxFactory.Token(lh.DeclarationKeyword.LeadingTrivia, SyntaxKind.FunctionKeyword, lh.DeclarationKeyword.TrailingTrivia), lh.ParameterList, asClause:=Nothing) Case SyntaxKind.DeclareSubStatement Dim ds = DirectCast(declaration, DeclareStatementSyntax) Return SyntaxFactory.DeclareStatement( SyntaxKind.DeclareFunctionStatement, ds.AttributeLists, ds.Modifiers, ds.CharsetKeyword, SyntaxFactory.Token(ds.DeclarationKeyword.LeadingTrivia, SyntaxKind.FunctionKeyword, ds.DeclarationKeyword.TrailingTrivia), ds.Identifier, ds.LibraryName, ds.AliasName, ds.ParameterList, SyntaxFactory.SimpleAsClause(SyntaxFactory.IdentifierName("Object"))) Case Else Return declaration End Select End Function Private Function AsSub(declaration As SyntaxNode) As SyntaxNode Return Isolate(declaration, AddressOf AsSubInternal) End Function Private Function AsSubInternal(declaration As SyntaxNode) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.FunctionBlock Dim mb = DirectCast(declaration, MethodBlockSyntax) Return SyntaxFactory.MethodBlock( SyntaxKind.SubBlock, DirectCast(AsSub(mb.BlockStatement), MethodStatementSyntax), mb.Statements, SyntaxFactory.EndBlockStatement( SyntaxKind.EndSubStatement, mb.EndBlockStatement.EndKeyword, SyntaxFactory.Token(mb.EndBlockStatement.BlockKeyword.LeadingTrivia, SyntaxKind.SubKeyword, mb.EndBlockStatement.BlockKeyword.TrailingTrivia) )) Case SyntaxKind.FunctionStatement Dim ms = DirectCast(declaration, MethodStatementSyntax) Return SyntaxFactory.MethodStatement( SyntaxKind.SubStatement, ms.AttributeLists, ms.Modifiers, SyntaxFactory.Token(ms.DeclarationKeyword.LeadingTrivia, SyntaxKind.SubKeyword, ms.DeclarationKeyword.TrailingTrivia), ms.Identifier, ms.TypeParameterList, ms.ParameterList, asClause:=Nothing, handlesClause:=ms.HandlesClause, implementsClause:=ms.ImplementsClause) Case SyntaxKind.DelegateFunctionStatement Dim ds = DirectCast(declaration, DelegateStatementSyntax) Return SyntaxFactory.DelegateStatement( SyntaxKind.DelegateSubStatement, ds.AttributeLists, ds.Modifiers, SyntaxFactory.Token(ds.DeclarationKeyword.LeadingTrivia, SyntaxKind.SubKeyword, ds.DeclarationKeyword.TrailingTrivia), ds.Identifier, ds.TypeParameterList, ds.ParameterList, asClause:=Nothing) Case SyntaxKind.MultiLineFunctionLambdaExpression Dim ml = DirectCast(declaration, MultiLineLambdaExpressionSyntax) Return SyntaxFactory.MultiLineLambdaExpression( SyntaxKind.MultiLineSubLambdaExpression, DirectCast(AsSub(ml.SubOrFunctionHeader), LambdaHeaderSyntax), ml.Statements, SyntaxFactory.EndBlockStatement( SyntaxKind.EndSubStatement, ml.EndSubOrFunctionStatement.EndKeyword, SyntaxFactory.Token(ml.EndSubOrFunctionStatement.BlockKeyword.LeadingTrivia, SyntaxKind.SubKeyword, ml.EndSubOrFunctionStatement.BlockKeyword.TrailingTrivia) )) Case SyntaxKind.SingleLineFunctionLambdaExpression Dim sl = DirectCast(declaration, SingleLineLambdaExpressionSyntax) Return SyntaxFactory.SingleLineLambdaExpression( SyntaxKind.SingleLineSubLambdaExpression, DirectCast(AsSub(sl.SubOrFunctionHeader), LambdaHeaderSyntax), sl.Body) Case SyntaxKind.FunctionLambdaHeader Dim lh = DirectCast(declaration, LambdaHeaderSyntax) Return SyntaxFactory.LambdaHeader( SyntaxKind.SubLambdaHeader, lh.AttributeLists, lh.Modifiers, SyntaxFactory.Token(lh.DeclarationKeyword.LeadingTrivia, SyntaxKind.SubKeyword, lh.DeclarationKeyword.TrailingTrivia), lh.ParameterList, asClause:=Nothing) Case SyntaxKind.DeclareFunctionStatement Dim ds = DirectCast(declaration, DeclareStatementSyntax) Return SyntaxFactory.DeclareStatement( SyntaxKind.DeclareSubStatement, ds.AttributeLists, ds.Modifiers, ds.CharsetKeyword, SyntaxFactory.Token(ds.DeclarationKeyword.LeadingTrivia, SyntaxKind.SubKeyword, ds.DeclarationKeyword.TrailingTrivia), ds.Identifier, ds.LibraryName, ds.AliasName, ds.ParameterList, asClause:=Nothing) Case Else Return declaration End Select End Function Public Overrides Function GetModifiers(declaration As SyntaxNode) As DeclarationModifiers Dim tokens = GetModifierTokens(declaration) Dim acc As Accessibility Dim mods As DeclarationModifiers Dim isDefault As Boolean GetAccessibilityAndModifiers(tokens, acc, mods, isDefault) Return mods End Function Private Shared Sub GetAccessibilityAndModifiers(modifierTokens As SyntaxTokenList, ByRef accessibility As Accessibility, ByRef declarationModifiers As DeclarationModifiers, ByRef isDefault As Boolean) Dim modifiers As Modifiers VisualBasicAccessibilityFacts.GetAccessibilityAndModifiers(modifierTokens, accessibility, modifiers, isDefault) declarationModifiers = modifiers.ToDeclarationModifiers() End Sub Private Shared Function GetModifierTokens(declaration As SyntaxNode) As SyntaxTokenList Return VisualBasicAccessibilityFacts.GetModifierTokens(declaration) End Function Friend Overrides Function WithModifiers(Of TSyntaxNode As SyntaxNode)(declaration As TSyntaxNode, modifiers As DeclarationModifiers) As TSyntaxNode Return DirectCast(Isolate(declaration, Function(d) Me.WithModifiersInternal(d, modifiers)), TSyntaxNode) End Function Private Function WithModifiersInternal(declaration As SyntaxNode, modifiers As DeclarationModifiers) As SyntaxNode Dim tokens = GetModifierTokens(declaration) Dim acc As Accessibility Dim currentMods As DeclarationModifiers Dim isDefault As Boolean GetAccessibilityAndModifiers(tokens, acc, currentMods, isDefault) If currentMods <> modifiers Then Dim newTokens = GetModifierList(acc, modifiers And GetAllowedModifiers(declaration.Kind), declaration, GetDeclarationKind(declaration), isDefault) Return WithModifierTokens(declaration, Merge(tokens, newTokens)) Else Return declaration End If End Function Private Shared Function WithModifierTokens(declaration As SyntaxNode, tokens As SyntaxTokenList) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).WithClassStatement(DirectCast(declaration, ClassBlockSyntax).ClassStatement.WithModifiers(tokens)) Case SyntaxKind.ClassStatement Return DirectCast(declaration, ClassStatementSyntax).WithModifiers(tokens) Case SyntaxKind.StructureBlock Return DirectCast(declaration, StructureBlockSyntax).WithStructureStatement(DirectCast(declaration, StructureBlockSyntax).StructureStatement.WithModifiers(tokens)) Case SyntaxKind.StructureStatement Return DirectCast(declaration, StructureStatementSyntax).WithModifiers(tokens) Case SyntaxKind.InterfaceBlock Return DirectCast(declaration, InterfaceBlockSyntax).WithInterfaceStatement(DirectCast(declaration, InterfaceBlockSyntax).InterfaceStatement.WithModifiers(tokens)) Case SyntaxKind.InterfaceStatement Return DirectCast(declaration, InterfaceStatementSyntax).WithModifiers(tokens) Case SyntaxKind.EnumBlock Return DirectCast(declaration, EnumBlockSyntax).WithEnumStatement(DirectCast(declaration, EnumBlockSyntax).EnumStatement.WithModifiers(tokens)) Case SyntaxKind.EnumStatement Return DirectCast(declaration, EnumStatementSyntax).WithModifiers(tokens) Case SyntaxKind.ModuleBlock Return DirectCast(declaration, ModuleBlockSyntax).WithModuleStatement(DirectCast(declaration, ModuleBlockSyntax).ModuleStatement.WithModifiers(tokens)) Case SyntaxKind.ModuleStatement Return DirectCast(declaration, ModuleStatementSyntax).WithModifiers(tokens) Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement Return DirectCast(declaration, DelegateStatementSyntax).WithModifiers(tokens) Case SyntaxKind.FieldDeclaration Return DirectCast(declaration, FieldDeclarationSyntax).WithModifiers(tokens) Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return DirectCast(declaration, MethodBlockSyntax).WithSubOrFunctionStatement(DirectCast(declaration, MethodBlockSyntax).SubOrFunctionStatement.WithModifiers(tokens)) Case SyntaxKind.ConstructorBlock Return DirectCast(declaration, ConstructorBlockSyntax).WithSubNewStatement(DirectCast(declaration, ConstructorBlockSyntax).SubNewStatement.WithModifiers(tokens)) Case SyntaxKind.FunctionStatement, SyntaxKind.SubStatement Return DirectCast(declaration, MethodStatementSyntax).WithModifiers(tokens) Case SyntaxKind.SubNewStatement Return DirectCast(declaration, SubNewStatementSyntax).WithModifiers(tokens) Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).WithPropertyStatement(DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.WithModifiers(tokens)) Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).WithModifiers(tokens) Case SyntaxKind.OperatorBlock Return DirectCast(declaration, OperatorBlockSyntax).WithOperatorStatement(DirectCast(declaration, OperatorBlockSyntax).OperatorStatement.WithModifiers(tokens)) Case SyntaxKind.OperatorStatement Return DirectCast(declaration, OperatorStatementSyntax).WithModifiers(tokens) Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).WithEventStatement(DirectCast(declaration, EventBlockSyntax).EventStatement.WithModifiers(tokens)) Case SyntaxKind.EventStatement Return DirectCast(declaration, EventStatementSyntax).WithModifiers(tokens) Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock, SyntaxKind.AddHandlerAccessorBlock, SyntaxKind.RemoveHandlerAccessorBlock, SyntaxKind.RaiseEventAccessorBlock Return DirectCast(declaration, AccessorBlockSyntax).WithAccessorStatement( DirectCast(WithModifierTokens(DirectCast(declaration, AccessorBlockSyntax).AccessorStatement, tokens), AccessorStatementSyntax)) Case SyntaxKind.GetAccessorStatement, SyntaxKind.SetAccessorStatement, SyntaxKind.AddHandlerAccessorStatement, SyntaxKind.RemoveHandlerAccessorStatement, SyntaxKind.RaiseEventAccessorStatement Return DirectCast(declaration, AccessorStatementSyntax).WithModifiers(tokens) Case Else Return declaration End Select End Function Public Overrides Function GetAccessibility(declaration As SyntaxNode) As Accessibility Return VisualBasicAccessibilityFacts.Instance.GetAccessibility(declaration) End Function Public Overrides Function WithAccessibility(declaration As SyntaxNode, accessibility As Accessibility) As SyntaxNode If Not CanHaveAccessibility(declaration) AndAlso accessibility <> Accessibility.NotApplicable Then Return declaration End If Return Isolate(declaration, Function(d) Me.WithAccessibilityInternal(d, accessibility)) End Function Private Shared Function CanHaveAccessibility(declaration As SyntaxNode) As Boolean Return VisualBasicAccessibilityFacts.Instance.CanHaveAccessibility(declaration, ignoreDeclarationModifiers:=True) End Function Private Function WithAccessibilityInternal(declaration As SyntaxNode, accessibility As Accessibility) As SyntaxNode If Not CanHaveAccessibility(declaration) Then Return declaration End If Dim tokens = GetModifierTokens(declaration) Dim currentAcc As Accessibility Dim mods As DeclarationModifiers Dim isDefault As Boolean GetAccessibilityAndModifiers(tokens, currentAcc, mods, isDefault) If currentAcc = accessibility Then Return declaration End If Dim newTokens = GetModifierList(accessibility, mods, declaration, GetDeclarationKind(declaration), isDefault) 'GetDeclarationKind returns None for Field if the count is > 1 'To handle multiple declarations on a field if the Accessibility is NotApplicable, we need to add the Dim If declaration.Kind = SyntaxKind.FieldDeclaration AndAlso accessibility = Accessibility.NotApplicable AndAlso newTokens.Count = 0 Then ' Add the Dim newTokens = newTokens.Add(SyntaxFactory.Token(SyntaxKind.DimKeyword)) End If Return WithModifierTokens(declaration, Merge(tokens, newTokens)) End Function Friend Shared Function GetModifierList(accessibility As Accessibility, modifiers As DeclarationModifiers, declaration As SyntaxNode, kind As DeclarationKind, Optional isDefault As Boolean = False) As SyntaxTokenList Return VisualBasicSyntaxGeneratorInternal.GetModifierList(accessibility, modifiers, declaration, kind, isDefault) End Function Private Protected Overrides Function TypeParameter(name As String) As SyntaxNode Return SyntaxFactory.TypeParameter(name) End Function Private Protected Overrides Function TypeParameter(symbol As ITypeParameterSymbol) As SyntaxNode Dim variance As SyntaxToken = Nothing Select Case symbol.Variance Case VarianceKind.In variance = SyntaxFactory.Token(SyntaxKind.InKeyword) Case VarianceKind.Out variance = SyntaxFactory.Token(SyntaxKind.OutKeyword) End Select Return SyntaxFactory.TypeParameter( variance, SyntaxFactory.Identifier(symbol.Name), typeParameterConstraintClause:=Nothing) End Function Private Shared Function GetTypeParameters(typeParameterNodes As IEnumerable(Of SyntaxNode)) As TypeParameterListSyntax If typeParameterNodes Is Nothing Then Return Nothing End If Dim typeParameterList = SyntaxFactory.TypeParameterList(SyntaxFactory.SeparatedList(typeParameterNodes.Cast(Of TypeParameterSyntax))) Return If(typeParameterList.Parameters.Count = 0, Nothing, typeParameterList) End Function Private Protected Overrides Function WithTypeParameters(declaration As SyntaxNode, typeParameters As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim typeParameterList = GetTypeParameters(typeParameters) Return ReplaceTypeParameterList(declaration, Function(old) typeParameterList) End Function Private Shared Function ReplaceTypeParameterList(declaration As SyntaxNode, replacer As Func(Of TypeParameterListSyntax, TypeParameterListSyntax)) As SyntaxNode Dim method = TryCast(declaration, MethodStatementSyntax) If method IsNot Nothing Then Return method.WithTypeParameterList(replacer(method.TypeParameterList)) End If Dim methodBlock = TryCast(declaration, MethodBlockSyntax) If methodBlock IsNot Nothing Then Return methodBlock.WithSubOrFunctionStatement(methodBlock.SubOrFunctionStatement.WithTypeParameterList(replacer(methodBlock.SubOrFunctionStatement.TypeParameterList))) End If Dim classBlock = TryCast(declaration, ClassBlockSyntax) If classBlock IsNot Nothing Then Return classBlock.WithClassStatement(classBlock.ClassStatement.WithTypeParameterList(replacer(classBlock.ClassStatement.TypeParameterList))) End If Dim structureBlock = TryCast(declaration, StructureBlockSyntax) If structureBlock IsNot Nothing Then Return structureBlock.WithStructureStatement(structureBlock.StructureStatement.WithTypeParameterList(replacer(structureBlock.StructureStatement.TypeParameterList))) End If Dim interfaceBlock = TryCast(declaration, InterfaceBlockSyntax) If interfaceBlock IsNot Nothing Then Return interfaceBlock.WithInterfaceStatement(interfaceBlock.InterfaceStatement.WithTypeParameterList(replacer(interfaceBlock.InterfaceStatement.TypeParameterList))) End If Return declaration End Function Friend Overrides Function WithExplicitInterfaceImplementations( declaration As SyntaxNode, explicitInterfaceImplementations As ImmutableArray(Of ISymbol), Optional removeDefaults As Boolean = True) As SyntaxNode ' removeDefaults is ignored in VB as the impl method is always directly callable If TypeOf declaration Is MethodStatementSyntax Then Dim methodStatement = DirectCast(declaration, MethodStatementSyntax) Dim interfaceMembers = explicitInterfaceImplementations.Select(AddressOf GenerateInterfaceMember) Return methodStatement.WithImplementsClause( SyntaxFactory.ImplementsClause(SyntaxFactory.SeparatedList(interfaceMembers))) ElseIf TypeOf declaration Is MethodBlockSyntax Then Dim methodBlock = DirectCast(declaration, MethodBlockSyntax) Return methodBlock.WithSubOrFunctionStatement( DirectCast(WithExplicitInterfaceImplementations(methodBlock.SubOrFunctionStatement, explicitInterfaceImplementations), MethodStatementSyntax)) Else Debug.Fail("Unhandled kind to add explicit implementations for: " & declaration.Kind()) End If Return declaration End Function Private Function GenerateInterfaceMember(method As ISymbol) As QualifiedNameSyntax Dim interfaceName = method.ContainingType.GenerateTypeSyntax() Return SyntaxFactory.QualifiedName( DirectCast(interfaceName, NameSyntax), SyntaxFactory.IdentifierName(method.Name)) End Function Private Protected Overrides Function WithTypeConstraint( declaration As SyntaxNode, typeParameterName As String, kinds As SpecialTypeConstraintKind, isUnmanagedType As Boolean, types As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim constraints = SyntaxFactory.SeparatedList(Of ConstraintSyntax) If types IsNot Nothing Then constraints = constraints.AddRange(types.Select(Function(t) SyntaxFactory.TypeConstraint(DirectCast(t, TypeSyntax)))) End If If (kinds And SpecialTypeConstraintKind.Constructor) <> 0 Then constraints = constraints.Add(SyntaxFactory.NewConstraint(SyntaxFactory.Token(SyntaxKind.NewKeyword))) End If Dim isReferenceType = (kinds And SpecialTypeConstraintKind.ReferenceType) <> 0 Dim isValueType = (kinds And SpecialTypeConstraintKind.ValueType) <> 0 If isReferenceType Then constraints = constraints.Insert(0, SyntaxFactory.ClassConstraint(SyntaxFactory.Token(SyntaxKind.ClassKeyword))) ElseIf isValueType Then constraints = constraints.Insert(0, SyntaxFactory.StructureConstraint(SyntaxFactory.Token(SyntaxKind.StructureKeyword))) End If Dim clause As TypeParameterConstraintClauseSyntax = Nothing If constraints.Count = 1 Then clause = SyntaxFactory.TypeParameterSingleConstraintClause(constraints(0)) ElseIf constraints.Count > 1 Then clause = SyntaxFactory.TypeParameterMultipleConstraintClause(constraints) End If Return ReplaceTypeParameterList(declaration, Function(old) WithTypeParameterConstraints(old, typeParameterName, clause)) End Function Private Protected Overrides Function WithDefaultConstraint(declaration As SyntaxNode, typeParameterName As String) As SyntaxNode ' Not supported in VB (no nullable reference types) Return declaration End Function Private Shared Function WithTypeParameterConstraints(typeParameterList As TypeParameterListSyntax, typeParameterName As String, clause As TypeParameterConstraintClauseSyntax) As TypeParameterListSyntax If typeParameterList IsNot Nothing Then Dim typeParameter = typeParameterList.Parameters.FirstOrDefault(Function(tp) tp.Identifier.ToString() = typeParameterName) If typeParameter IsNot Nothing Then Return typeParameterList.WithParameters(typeParameterList.Parameters.Replace(typeParameter, typeParameter.WithTypeParameterConstraintClause(clause))) End If End If Return typeParameterList End Function Public Overrides Function GetParameters(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Dim list = declaration.GetParameterList() Return If(list IsNot Nothing, list.Parameters, SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode)) End Function Public Overrides Function InsertParameters(declaration As SyntaxNode, index As Integer, parameters As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim currentList = declaration.GetParameterList() Dim newList = GetParameterList(parameters) If currentList IsNot Nothing Then Return WithParameterList(declaration, currentList.WithParameters(currentList.Parameters.InsertRange(index, newList.Parameters))) Else Return WithParameterList(declaration, newList) End If End Function Public Overrides Function GetSwitchSections(switchStatement As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Dim statement = TryCast(switchStatement, SelectBlockSyntax) If statement Is Nothing Then Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode) End If Return statement.CaseBlocks End Function Public Overrides Function InsertSwitchSections(switchStatement As SyntaxNode, index As Integer, switchSections As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim statement = TryCast(switchStatement, SelectBlockSyntax) If statement Is Nothing Then Return switchStatement End If Return statement.WithCaseBlocks( statement.CaseBlocks.InsertRange(index, switchSections.Cast(Of CaseBlockSyntax))) End Function Friend Overrides Function GetParameterListNode(declaration As SyntaxNode) As SyntaxNode Return declaration.GetParameterList() End Function Private Shared Function WithParameterList(declaration As SyntaxNode, list As ParameterListSyntax) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement Return DirectCast(declaration, DelegateStatementSyntax).WithParameterList(list) Case SyntaxKind.SubBlock, SyntaxKind.FunctionBlock Return DirectCast(declaration, MethodBlockSyntax).WithBlockStatement(DirectCast(declaration, MethodBlockSyntax).BlockStatement.WithParameterList(list)) Case SyntaxKind.ConstructorBlock Return DirectCast(declaration, ConstructorBlockSyntax).WithBlockStatement(DirectCast(declaration, ConstructorBlockSyntax).BlockStatement.WithParameterList(list)) Case SyntaxKind.OperatorBlock Return DirectCast(declaration, OperatorBlockSyntax).WithBlockStatement(DirectCast(declaration, OperatorBlockSyntax).BlockStatement.WithParameterList(list)) Case SyntaxKind.SubStatement, SyntaxKind.FunctionStatement Return DirectCast(declaration, MethodStatementSyntax).WithParameterList(list) Case SyntaxKind.SubNewStatement Return DirectCast(declaration, SubNewStatementSyntax).WithParameterList(list) Case SyntaxKind.OperatorStatement Return DirectCast(declaration, OperatorStatementSyntax).WithParameterList(list) Case SyntaxKind.DeclareSubStatement, SyntaxKind.DeclareFunctionStatement Return DirectCast(declaration, DeclareStatementSyntax).WithParameterList(list) Case SyntaxKind.DelegateSubStatement, SyntaxKind.DelegateFunctionStatement Return DirectCast(declaration, DelegateStatementSyntax).WithParameterList(list) Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).WithPropertyStatement(DirectCast(declaration, PropertyBlockSyntax).PropertyStatement.WithParameterList(list)) Case SyntaxKind.PropertyStatement Return DirectCast(declaration, PropertyStatementSyntax).WithParameterList(list) Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).WithEventStatement(DirectCast(declaration, EventBlockSyntax).EventStatement.WithParameterList(list)) Case SyntaxKind.EventStatement Return DirectCast(declaration, EventStatementSyntax).WithParameterList(list) Case SyntaxKind.MultiLineFunctionLambdaExpression, SyntaxKind.MultiLineSubLambdaExpression Return DirectCast(declaration, MultiLineLambdaExpressionSyntax).WithSubOrFunctionHeader(DirectCast(declaration, MultiLineLambdaExpressionSyntax).SubOrFunctionHeader.WithParameterList(list)) Case SyntaxKind.SingleLineFunctionLambdaExpression, SyntaxKind.SingleLineSubLambdaExpression Return DirectCast(declaration, SingleLineLambdaExpressionSyntax).WithSubOrFunctionHeader(DirectCast(declaration, SingleLineLambdaExpressionSyntax).SubOrFunctionHeader.WithParameterList(list)) End Select Return declaration End Function Public Overrides Function GetExpression(declaration As SyntaxNode) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.SingleLineFunctionLambdaExpression, SyntaxKind.SingleLineSubLambdaExpression Return AsExpression(DirectCast(declaration, SingleLineLambdaExpressionSyntax).Body) Case Else Dim ev = GetEqualsValue(declaration) If ev IsNot Nothing Then Return ev.Value End If End Select Return Nothing End Function Private Shared Function AsExpression(node As SyntaxNode) As ExpressionSyntax Dim es = TryCast(node, ExpressionStatementSyntax) If es IsNot Nothing Then Return es.Expression End If Return DirectCast(node, ExpressionSyntax) End Function Public Overrides Function WithExpression(declaration As SyntaxNode, expression As SyntaxNode) As SyntaxNode Return Isolate(declaration, Function(d) WithExpressionInternal(d, expression)) End Function Private Shared Function WithExpressionInternal(declaration As SyntaxNode, expression As SyntaxNode) As SyntaxNode Dim expr = DirectCast(expression, ExpressionSyntax) Select Case declaration.Kind Case SyntaxKind.SingleLineFunctionLambdaExpression Dim sll = DirectCast(declaration, SingleLineLambdaExpressionSyntax) If expression IsNot Nothing Then Return sll.WithBody(expr) Else Return SyntaxFactory.MultiLineLambdaExpression(SyntaxKind.MultiLineFunctionLambdaExpression, sll.SubOrFunctionHeader, SyntaxFactory.EndFunctionStatement()) End If Case SyntaxKind.MultiLineFunctionLambdaExpression Dim mll = DirectCast(declaration, MultiLineLambdaExpressionSyntax) If expression IsNot Nothing Then Return SyntaxFactory.SingleLineLambdaExpression(SyntaxKind.SingleLineFunctionLambdaExpression, mll.SubOrFunctionHeader, expr) End If Case SyntaxKind.SingleLineSubLambdaExpression Dim sll = DirectCast(declaration, SingleLineLambdaExpressionSyntax) If expression IsNot Nothing Then Return sll.WithBody(AsStatement(expr)) Else Return SyntaxFactory.MultiLineLambdaExpression(SyntaxKind.MultiLineSubLambdaExpression, sll.SubOrFunctionHeader, SyntaxFactory.EndSubStatement()) End If Case SyntaxKind.MultiLineSubLambdaExpression Dim mll = DirectCast(declaration, MultiLineLambdaExpressionSyntax) If expression IsNot Nothing Then Return SyntaxFactory.SingleLineLambdaExpression(SyntaxKind.SingleLineSubLambdaExpression, mll.SubOrFunctionHeader, AsStatement(expr)) End If Case Else Dim currentEV = GetEqualsValue(declaration) If currentEV IsNot Nothing Then Return WithEqualsValue(declaration, currentEV.WithValue(expr)) Else Return WithEqualsValue(declaration, SyntaxFactory.EqualsValue(expr)) End If End Select Return declaration End Function Private Shared Function GetEqualsValue(declaration As SyntaxNode) As EqualsValueSyntax Select Case declaration.Kind Case SyntaxKind.Parameter Return DirectCast(declaration, ParameterSyntax).Default Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) If ld.Declarators.Count = 1 Then Return ld.Declarators(0).Initializer End If Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) If fd.Declarators.Count = 1 Then Return fd.Declarators(0).Initializer End If Case SyntaxKind.VariableDeclarator Return DirectCast(declaration, VariableDeclaratorSyntax).Initializer End Select Return Nothing End Function Private Shared Function WithEqualsValue(declaration As SyntaxNode, ev As EqualsValueSyntax) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.Parameter Return DirectCast(declaration, ParameterSyntax).WithDefault(ev) Case SyntaxKind.LocalDeclarationStatement Dim ld = DirectCast(declaration, LocalDeclarationStatementSyntax) If ld.Declarators.Count = 1 Then Return ReplaceWithTrivia(declaration, ld.Declarators(0), ld.Declarators(0).WithInitializer(ev)) End If Case SyntaxKind.FieldDeclaration Dim fd = DirectCast(declaration, FieldDeclarationSyntax) If fd.Declarators.Count = 1 Then Return ReplaceWithTrivia(declaration, fd.Declarators(0), fd.Declarators(0).WithInitializer(ev)) End If End Select Return declaration End Function Public Overrides Function GetNamespaceImports(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Return Flatten(GetUnflattenedNamespaceImports(declaration)) End Function Private Shared Function GetUnflattenedNamespaceImports(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Select Case declaration.Kind Case SyntaxKind.CompilationUnit Return DirectCast(declaration, CompilationUnitSyntax).Imports Case Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode) End Select End Function Public Overrides Function InsertNamespaceImports(declaration As SyntaxNode, index As Integer, [imports] As IEnumerable(Of SyntaxNode)) As SyntaxNode Return Isolate(declaration, Function(d) InsertNamespaceImportsInternal(d, index, [imports])) End Function Private Function InsertNamespaceImportsInternal(declaration As SyntaxNode, index As Integer, [imports] As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim newImports = AsImports([imports]) Dim existingImports = Me.GetNamespaceImports(declaration) If index >= 0 AndAlso index < existingImports.Count Then Return Me.InsertNodesBefore(declaration, existingImports(index), newImports) ElseIf existingImports.Count > 0 Then Return Me.InsertNodesAfter(declaration, existingImports(existingImports.Count - 1), newImports) Else Select Case declaration.Kind Case SyntaxKind.CompilationUnit Dim cu = DirectCast(declaration, CompilationUnitSyntax) Return cu.WithImports(cu.Imports.AddRange(newImports)) Case Else Return declaration End Select End If End Function Public Overrides Function GetMembers(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Return Flatten(GetUnflattenedMembers(declaration)) End Function Private Shared Function GetUnflattenedMembers(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Select Case declaration.Kind Case SyntaxKind.CompilationUnit Return DirectCast(declaration, CompilationUnitSyntax).Members Case SyntaxKind.NamespaceBlock Return DirectCast(declaration, NamespaceBlockSyntax).Members Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).Members Case SyntaxKind.StructureBlock Return DirectCast(declaration, StructureBlockSyntax).Members Case SyntaxKind.InterfaceBlock Return DirectCast(declaration, InterfaceBlockSyntax).Members Case SyntaxKind.EnumBlock Return DirectCast(declaration, EnumBlockSyntax).Members Case Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode)() End Select End Function Private Function AsMembersOf(declaration As SyntaxNode, members As IEnumerable(Of SyntaxNode)) As IEnumerable(Of StatementSyntax) Select Case declaration.Kind Case SyntaxKind.CompilationUnit Return AsNamespaceMembers(members) Case SyntaxKind.NamespaceBlock Return AsNamespaceMembers(members) Case SyntaxKind.ClassBlock Return AsClassMembers(members) Case SyntaxKind.StructureBlock Return AsClassMembers(members) Case SyntaxKind.InterfaceBlock Return AsInterfaceMembers(members) Case SyntaxKind.EnumBlock Return AsEnumMembers(members) Case Else Return SpecializedCollections.EmptyEnumerable(Of StatementSyntax) End Select End Function Public Overrides Function InsertMembers(declaration As SyntaxNode, index As Integer, members As IEnumerable(Of SyntaxNode)) As SyntaxNode Return Isolate(declaration, Function(d) InsertMembersInternal(d, index, members)) End Function Private Function InsertMembersInternal(declaration As SyntaxNode, index As Integer, members As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim newMembers = Me.AsMembersOf(declaration, members) Dim existingMembers = Me.GetMembers(declaration) If index >= 0 AndAlso index < existingMembers.Count Then Return Me.InsertNodesBefore(declaration, existingMembers(index), members) ElseIf existingMembers.Count > 0 Then Return Me.InsertNodesAfter(declaration, existingMembers(existingMembers.Count - 1), members) End If Select Case declaration.Kind Case SyntaxKind.CompilationUnit Dim cu = DirectCast(declaration, CompilationUnitSyntax) Return cu.WithMembers(cu.Members.AddRange(newMembers)) Case SyntaxKind.NamespaceBlock Dim ns = DirectCast(declaration, NamespaceBlockSyntax) Return ns.WithMembers(ns.Members.AddRange(newMembers)) Case SyntaxKind.ClassBlock Dim cb = DirectCast(declaration, ClassBlockSyntax) Return cb.WithMembers(cb.Members.AddRange(newMembers)) Case SyntaxKind.StructureBlock Dim sb = DirectCast(declaration, StructureBlockSyntax) Return sb.WithMembers(sb.Members.AddRange(newMembers)) Case SyntaxKind.InterfaceBlock Dim ib = DirectCast(declaration, InterfaceBlockSyntax) Return ib.WithMembers(ib.Members.AddRange(newMembers)) Case SyntaxKind.EnumBlock Dim eb = DirectCast(declaration, EnumBlockSyntax) Return eb.WithMembers(eb.Members.AddRange(newMembers)) Case Else Return declaration End Select End Function Public Overrides Function GetStatements(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Select Case declaration.Kind Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock, SyntaxKind.ConstructorBlock, SyntaxKind.OperatorBlock Return DirectCast(declaration, MethodBlockBaseSyntax).Statements Case SyntaxKind.MultiLineFunctionLambdaExpression, SyntaxKind.MultiLineSubLambdaExpression Return DirectCast(declaration, MultiLineLambdaExpressionSyntax).Statements Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock, SyntaxKind.AddHandlerAccessorBlock, SyntaxKind.RemoveHandlerAccessorBlock, SyntaxKind.RaiseEventAccessorBlock Return DirectCast(declaration, AccessorBlockSyntax).Statements Case Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode) End Select End Function Public Overrides Function WithStatements(declaration As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return Isolate(declaration, Function(d) WithStatementsInternal(d, statements)) End Function Private Shared Function WithStatementsInternal(declaration As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim list = GetStatementList(statements) Select Case declaration.Kind Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock Return DirectCast(declaration, MethodBlockSyntax).WithStatements(list) Case SyntaxKind.ConstructorBlock Return DirectCast(declaration, ConstructorBlockSyntax).WithStatements(list) Case SyntaxKind.OperatorBlock Return DirectCast(declaration, OperatorBlockSyntax).WithStatements(list) Case SyntaxKind.MultiLineFunctionLambdaExpression, SyntaxKind.MultiLineSubLambdaExpression Return DirectCast(declaration, MultiLineLambdaExpressionSyntax).WithStatements(list) Case SyntaxKind.SingleLineFunctionLambdaExpression Dim sll = DirectCast(declaration, SingleLineLambdaExpressionSyntax) Return SyntaxFactory.MultiLineLambdaExpression(SyntaxKind.MultiLineFunctionLambdaExpression, sll.SubOrFunctionHeader, list, SyntaxFactory.EndFunctionStatement()) Case SyntaxKind.SingleLineSubLambdaExpression Dim sll = DirectCast(declaration, SingleLineLambdaExpressionSyntax) Return SyntaxFactory.MultiLineLambdaExpression(SyntaxKind.MultiLineSubLambdaExpression, sll.SubOrFunctionHeader, list, SyntaxFactory.EndSubStatement()) Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock, SyntaxKind.AddHandlerAccessorBlock, SyntaxKind.RemoveHandlerAccessorBlock, SyntaxKind.RaiseEventAccessorBlock Return DirectCast(declaration, AccessorBlockSyntax).WithStatements(list) Case Else Return declaration End Select End Function Public Overrides Function GetAccessors(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Select Case declaration.Kind Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).Accessors Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).Accessors Case Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode)() End Select End Function Public Overrides Function InsertAccessors(declaration As SyntaxNode, index As Integer, accessors As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim currentList = GetAccessorList(declaration) Dim newList = AsAccessorList(accessors, declaration.Kind) If Not currentList.IsEmpty Then Return WithAccessorList(declaration, currentList.InsertRange(index, newList)) Else Return WithAccessorList(declaration, newList) End If End Function Private Shared Function WithAccessorList(declaration As SyntaxNode, accessorList As SyntaxList(Of AccessorBlockSyntax)) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).WithAccessors(accessorList) Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).WithAccessors(accessorList) Case Else Return declaration End Select End Function Private Shared Function AsAccessorList(nodes As IEnumerable(Of SyntaxNode), parentKind As SyntaxKind) As SyntaxList(Of AccessorBlockSyntax) Return SyntaxFactory.List(nodes.Select(Function(n) AsAccessor(n, parentKind)).Where(Function(n) n IsNot Nothing)) End Function Private Shared Function AsAccessor(node As SyntaxNode, parentKind As SyntaxKind) As AccessorBlockSyntax Select Case parentKind Case SyntaxKind.PropertyBlock Select Case node.Kind Case SyntaxKind.GetAccessorBlock, SyntaxKind.SetAccessorBlock Return DirectCast(node, AccessorBlockSyntax) End Select Case SyntaxKind.EventBlock Select Case node.Kind Case SyntaxKind.AddHandlerAccessorBlock, SyntaxKind.RemoveHandlerAccessorBlock, SyntaxKind.RaiseEventAccessorBlock Return DirectCast(node, AccessorBlockSyntax) End Select End Select Return Nothing End Function Private Shared Function CanHaveAccessors(kind As SyntaxKind) As Boolean Select Case kind Case SyntaxKind.PropertyBlock, SyntaxKind.EventBlock Return True Case Else Return False End Select End Function Public Overrides Function GetGetAccessorStatements(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Return GetAccessorStatements(declaration, SyntaxKind.GetAccessorBlock) End Function Public Overrides Function WithGetAccessorStatements(declaration As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return WithAccessorStatements(declaration, statements, SyntaxKind.GetAccessorBlock) End Function Public Overrides Function GetSetAccessorStatements(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Return GetAccessorStatements(declaration, SyntaxKind.SetAccessorBlock) End Function Public Overrides Function WithSetAccessorStatements(declaration As SyntaxNode, statements As IEnumerable(Of SyntaxNode)) As SyntaxNode Return WithAccessorStatements(declaration, statements, SyntaxKind.SetAccessorBlock) End Function Private Function GetAccessorStatements(declaration As SyntaxNode, kind As SyntaxKind) As IReadOnlyList(Of SyntaxNode) Dim accessor = GetAccessorBlock(declaration, kind) If accessor IsNot Nothing Then Return Me.GetStatements(accessor) Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode)() End If End Function Private Function WithAccessorStatements(declaration As SyntaxNode, statements As IEnumerable(Of SyntaxNode), kind As SyntaxKind) As SyntaxNode Dim accessor = GetAccessorBlock(declaration, kind) If accessor IsNot Nothing Then accessor = DirectCast(Me.WithStatements(accessor, statements), AccessorBlockSyntax) Return Me.WithAccessorBlock(declaration, kind, accessor) ElseIf CanHaveAccessors(declaration.Kind) Then accessor = AccessorBlock(kind, statements, Me.ClearTrivia(Me.GetType(declaration))) Return Me.WithAccessorBlock(declaration, kind, accessor) Else Return declaration End If End Function Private Shared Function GetAccessorBlock(declaration As SyntaxNode, kind As SyntaxKind) As AccessorBlockSyntax Select Case declaration.Kind Case SyntaxKind.PropertyBlock Return DirectCast(declaration, PropertyBlockSyntax).Accessors.FirstOrDefault(Function(a) a.IsKind(kind)) Case SyntaxKind.EventBlock Return DirectCast(declaration, EventBlockSyntax).Accessors.FirstOrDefault(Function(a) a.IsKind(kind)) Case Else Return Nothing End Select End Function Private Function WithAccessorBlock(declaration As SyntaxNode, kind As SyntaxKind, accessor As AccessorBlockSyntax) As SyntaxNode Dim currentAccessor = GetAccessorBlock(declaration, kind) If currentAccessor IsNot Nothing Then Return Me.ReplaceNode(declaration, currentAccessor, accessor) ElseIf accessor IsNot Nothing Then Select Case declaration.Kind Case SyntaxKind.PropertyBlock Dim pb = DirectCast(declaration, PropertyBlockSyntax) Return pb.WithAccessors(pb.Accessors.Add(accessor)) Case SyntaxKind.EventBlock Dim eb = DirectCast(declaration, EventBlockSyntax) Return eb.WithAccessors(eb.Accessors.Add(accessor)) End Select End If Return declaration End Function Public Overrides Function EventDeclaration(name As String, type As SyntaxNode, Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional modifiers As DeclarationModifiers = Nothing) As SyntaxNode Return SyntaxFactory.EventStatement( attributeLists:=Nothing, modifiers:=GetModifierList(accessibility, modifiers And GetAllowedModifiers(SyntaxKind.EventStatement), declaration:=Nothing, DeclarationKind.Event), customKeyword:=Nothing, eventKeyword:=SyntaxFactory.Token(SyntaxKind.EventKeyword), identifier:=name.ToIdentifierToken(), parameterList:=Nothing, asClause:=SyntaxFactory.SimpleAsClause(DirectCast(type, TypeSyntax)), implementsClause:=Nothing) End Function Public Overrides Function CustomEventDeclaration( name As String, type As SyntaxNode, Optional accessibility As Accessibility = Accessibility.NotApplicable, Optional modifiers As DeclarationModifiers = Nothing, Optional parameters As IEnumerable(Of SyntaxNode) = Nothing, Optional addAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing, Optional removeAccessorStatements As IEnumerable(Of SyntaxNode) = Nothing) As SyntaxNode Return VisualBasicSyntaxGeneratorInternal.CustomEventDeclarationWithRaise( name, type, accessibility, modifiers, parameters, addAccessorStatements, removeAccessorStatements) End Function Public Overrides Function GetAttributeArguments(attributeDeclaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Dim list = GetArgumentList(attributeDeclaration) If list IsNot Nothing Then Return list.Arguments Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode)() End If End Function Public Overrides Function InsertAttributeArguments(attributeDeclaration As SyntaxNode, index As Integer, attributeArguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Return Isolate(attributeDeclaration, Function(d) InsertAttributeArgumentsInternal(d, index, attributeArguments)) End Function Private Function InsertAttributeArgumentsInternal(attributeDeclaration As SyntaxNode, index As Integer, attributeArguments As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim list = GetArgumentList(attributeDeclaration) Dim newArguments = AsArgumentList(attributeArguments) If list Is Nothing Then list = newArguments Else list = list.WithArguments(list.Arguments.InsertRange(index, newArguments.Arguments)) End If Return WithArgumentList(attributeDeclaration, list) End Function Private Shared Function GetArgumentList(declaration As SyntaxNode) As ArgumentListSyntax Select Case declaration.Kind Case SyntaxKind.AttributeList Dim al = DirectCast(declaration, AttributeListSyntax) If al.Attributes.Count = 1 Then Return al.Attributes(0).ArgumentList End If Case SyntaxKind.Attribute Return DirectCast(declaration, AttributeSyntax).ArgumentList End Select Return Nothing End Function Private Shared Function WithArgumentList(declaration As SyntaxNode, argumentList As ArgumentListSyntax) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.AttributeList Dim al = DirectCast(declaration, AttributeListSyntax) If al.Attributes.Count = 1 Then Return ReplaceWithTrivia(declaration, al.Attributes(0), al.Attributes(0).WithArgumentList(argumentList)) End If Case SyntaxKind.Attribute Return DirectCast(declaration, AttributeSyntax).WithArgumentList(argumentList) End Select Return declaration End Function Public Overrides Function GetBaseAndInterfaceTypes(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Return GetInherits(declaration).SelectMany(Function(ih) ih.Types).Concat(GetImplements(declaration).SelectMany(Function(imp) imp.Types)).ToBoxedImmutableArray() End Function Public Overrides Function AddBaseType(declaration As SyntaxNode, baseType As SyntaxNode) As SyntaxNode If declaration.IsKind(SyntaxKind.ClassBlock) Then Dim existingBaseType = GetInherits(declaration).SelectMany(Function(inh) inh.Types).FirstOrDefault() If existingBaseType IsNot Nothing Then Return declaration.ReplaceNode(existingBaseType, baseType.WithTriviaFrom(existingBaseType)) Else Return WithInherits(declaration, SyntaxFactory.SingletonList(SyntaxFactory.InheritsStatement(DirectCast(baseType, TypeSyntax)))) End If Else Return declaration End If End Function Public Overrides Function AddInterfaceType(declaration As SyntaxNode, interfaceType As SyntaxNode) As SyntaxNode If declaration.IsKind(SyntaxKind.InterfaceBlock) Then Dim inh = GetInherits(declaration) Dim last = inh.SelectMany(Function(s) s.Types).LastOrDefault() If inh.Count = 1 AndAlso last IsNot Nothing Then Dim inh0 = inh(0) Dim newInh0 = PreserveTrivia(inh0.TrackNodes(last), Function(_inh0) InsertNodesAfter(_inh0, _inh0.GetCurrentNode(last), {interfaceType})) Return ReplaceNode(declaration, inh0, newInh0) Else Return WithInherits(declaration, inh.Add(SyntaxFactory.InheritsStatement(DirectCast(interfaceType, TypeSyntax)))) End If Else Dim imp = GetImplements(declaration) Dim last = imp.SelectMany(Function(s) s.Types).LastOrDefault() If imp.Count = 1 AndAlso last IsNot Nothing Then Dim imp0 = imp(0) Dim newImp0 = PreserveTrivia(imp0.TrackNodes(last), Function(_imp0) InsertNodesAfter(_imp0, _imp0.GetCurrentNode(last), {interfaceType})) Return ReplaceNode(declaration, imp0, newImp0) Else Return WithImplements(declaration, imp.Add(SyntaxFactory.ImplementsStatement(DirectCast(interfaceType, TypeSyntax)))) End If End If End Function Private Shared Function GetInherits(declaration As SyntaxNode) As SyntaxList(Of InheritsStatementSyntax) Select Case declaration.Kind Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).Inherits Case SyntaxKind.InterfaceBlock Return DirectCast(declaration, InterfaceBlockSyntax).Inherits Case Else Return Nothing End Select End Function Private Shared Function WithInherits(declaration As SyntaxNode, list As SyntaxList(Of InheritsStatementSyntax)) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).WithInherits(list) Case SyntaxKind.InterfaceBlock Return DirectCast(declaration, InterfaceBlockSyntax).WithInherits(list) Case Else Return declaration End Select End Function Private Shared Function GetImplements(declaration As SyntaxNode) As SyntaxList(Of ImplementsStatementSyntax) Select Case declaration.Kind Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).Implements Case SyntaxKind.StructureBlock Return DirectCast(declaration, StructureBlockSyntax).Implements Case Else Return Nothing End Select End Function Private Shared Function WithImplements(declaration As SyntaxNode, list As SyntaxList(Of ImplementsStatementSyntax)) As SyntaxNode Select Case declaration.Kind Case SyntaxKind.ClassBlock Return DirectCast(declaration, ClassBlockSyntax).WithImplements(list) Case SyntaxKind.StructureBlock Return DirectCast(declaration, StructureBlockSyntax).WithImplements(list) Case Else Return declaration End Select End Function #End Region #Region "Remove, Replace, Insert" Public Overrides Function ReplaceNode(root As SyntaxNode, declaration As SyntaxNode, newDeclaration As SyntaxNode) As SyntaxNode If newDeclaration Is Nothing Then Return Me.RemoveNode(root, declaration) End If If root.Span.Contains(declaration.Span) Then Dim newFullDecl = AsIsolatedDeclaration(newDeclaration) Dim fullDecl = GetFullDeclaration(declaration) ' special handling for replacing at location of a sub-declaration If fullDecl IsNot declaration AndAlso fullDecl.IsKind(newFullDecl.Kind) Then ' try to replace inline if possible If GetDeclarationCount(newFullDecl) = 1 Then Dim newSubDecl = GetSubDeclarations(newFullDecl)(0) If AreInlineReplaceableSubDeclarations(declaration, newSubDecl) Then Return MyBase.ReplaceNode(root, declaration, newSubDecl) End If End If ' otherwise replace by splitting full-declaration into two parts and inserting newDeclaration between them Dim index = MyBase.IndexOf(GetSubDeclarations(fullDecl), declaration) Return Me.ReplaceSubDeclaration(root, fullDecl, index, newFullDecl) End If ' attempt normal replace Return MyBase.ReplaceNode(root, declaration, newFullDecl) Else Return MyBase.ReplaceNode(root, declaration, newDeclaration) End If End Function ' return true if one sub-declaration can be replaced in-line with another sub-declaration Private Shared Function AreInlineReplaceableSubDeclarations(decl1 As SyntaxNode, decl2 As SyntaxNode) As Boolean Dim kind = decl1.Kind If Not decl2.IsKind(kind) Then Return False End If Select Case kind Case SyntaxKind.ModifiedIdentifier, SyntaxKind.Attribute, SyntaxKind.SimpleImportsClause, SyntaxKind.XmlNamespaceImportsClause Return AreSimilarExceptForSubDeclarations(decl1.Parent, decl2.Parent) End Select Return False End Function Private Shared Function AreSimilarExceptForSubDeclarations(decl1 As SyntaxNode, decl2 As SyntaxNode) As Boolean If decl1 Is Nothing OrElse decl2 Is Nothing Then Return False End If Dim kind = decl1.Kind If Not decl2.IsKind(kind) Then Return False End If Select Case kind Case SyntaxKind.FieldDeclaration Dim fd1 = DirectCast(decl1, FieldDeclarationSyntax) Dim fd2 = DirectCast(decl2, FieldDeclarationSyntax) Return SyntaxFactory.AreEquivalent(fd1.AttributeLists, fd2.AttributeLists) AndAlso SyntaxFactory.AreEquivalent(fd1.Modifiers, fd2.Modifiers) Case SyntaxKind.LocalDeclarationStatement Dim ld1 = DirectCast(decl1, LocalDeclarationStatementSyntax) Dim ld2 = DirectCast(decl2, LocalDeclarationStatementSyntax) Return SyntaxFactory.AreEquivalent(ld1.Modifiers, ld2.Modifiers) Case SyntaxKind.VariableDeclarator Dim vd1 = DirectCast(decl1, VariableDeclaratorSyntax) Dim vd2 = DirectCast(decl2, VariableDeclaratorSyntax) Return SyntaxFactory.AreEquivalent(vd1.AsClause, vd2.AsClause) AndAlso SyntaxFactory.AreEquivalent(vd2.Initializer, vd1.Initializer) AndAlso AreSimilarExceptForSubDeclarations(decl1.Parent, decl2.Parent) Case SyntaxKind.AttributeList, SyntaxKind.ImportsStatement Return True End Select Return False End Function Public Overrides Function InsertNodesBefore(root As SyntaxNode, declaration As SyntaxNode, newDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode If root.Span.Contains(declaration.Span) Then Return Isolate(root.TrackNodes(declaration), Function(r) InsertDeclarationsBeforeInternal(r, r.GetCurrentNode(declaration), newDeclarations)) Else Return MyBase.InsertNodesBefore(root, declaration, newDeclarations) End If End Function Private Function InsertDeclarationsBeforeInternal(root As SyntaxNode, declaration As SyntaxNode, newDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim fullDecl = GetFullDeclaration(declaration) If fullDecl Is declaration OrElse GetDeclarationCount(fullDecl) = 1 Then Return MyBase.InsertNodesBefore(root, declaration, newDeclarations) End If Dim subDecls = GetSubDeclarations(fullDecl) Dim count = subDecls.Count Dim index = MyBase.IndexOf(subDecls, declaration) ' insert New declaration between full declaration split into two If index > 0 Then Return ReplaceRange(root, fullDecl, SplitAndInsert(fullDecl, subDecls, index, newDeclarations)) End If Return MyBase.InsertNodesBefore(root, fullDecl, newDeclarations) End Function Public Overrides Function InsertNodesAfter(root As SyntaxNode, declaration As SyntaxNode, newDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode If root.Span.Contains(declaration.Span) Then Return Isolate(root.TrackNodes(declaration), Function(r) InsertNodesAfterInternal(r, r.GetCurrentNode(declaration), newDeclarations)) Else Return MyBase.InsertNodesAfter(root, declaration, newDeclarations) End If End Function Private Function InsertNodesAfterInternal(root As SyntaxNode, declaration As SyntaxNode, newDeclarations As IEnumerable(Of SyntaxNode)) As SyntaxNode Dim fullDecl = GetFullDeclaration(declaration) If fullDecl Is declaration OrElse GetDeclarationCount(fullDecl) = 1 Then Return MyBase.InsertNodesAfter(root, declaration, newDeclarations) End If Dim subDecls = GetSubDeclarations(fullDecl) Dim count = subDecls.Count Dim index = MyBase.IndexOf(subDecls, declaration) ' insert New declaration between full declaration split into two If index >= 0 AndAlso index < count - 1 Then Return ReplaceRange(root, fullDecl, SplitAndInsert(fullDecl, subDecls, index + 1, newDeclarations)) End If Return MyBase.InsertNodesAfter(root, fullDecl, newDeclarations) End Function Private Function SplitAndInsert(multiPartDeclaration As SyntaxNode, subDeclarations As IReadOnlyList(Of SyntaxNode), index As Integer, newDeclarations As IEnumerable(Of SyntaxNode)) As IEnumerable(Of SyntaxNode) Dim count = subDeclarations.Count Dim newNodes = New List(Of SyntaxNode)() newNodes.Add(Me.WithSubDeclarationsRemoved(multiPartDeclaration, index, count - index).WithTrailingTrivia(SyntaxFactory.ElasticSpace)) newNodes.AddRange(newDeclarations) newNodes.Add(Me.WithSubDeclarationsRemoved(multiPartDeclaration, 0, index).WithLeadingTrivia(SyntaxFactory.ElasticSpace)) Return newNodes End Function ' replaces sub-declaration by splitting multi-part declaration first Private Function ReplaceSubDeclaration(root As SyntaxNode, declaration As SyntaxNode, index As Integer, newDeclaration As SyntaxNode) As SyntaxNode Dim newNodes = New List(Of SyntaxNode)() Dim count = GetDeclarationCount(declaration) If index >= 0 AndAlso index < count Then If (index > 0) Then ' make a single declaration with only the sub-declarations before the sub-declaration being replaced newNodes.Add(Me.WithSubDeclarationsRemoved(declaration, index, count - index).WithTrailingTrivia(SyntaxFactory.ElasticSpace)) End If newNodes.Add(newDeclaration) If (index < count - 1) Then ' make a single declaration with only the sub-declarations after the sub-declaration being replaced newNodes.Add(Me.WithSubDeclarationsRemoved(declaration, 0, index + 1).WithLeadingTrivia(SyntaxFactory.ElasticSpace)) End If ' replace declaration with multiple declarations Return ReplaceRange(root, declaration, newNodes) Else Return root End If End Function Private Function WithSubDeclarationsRemoved(declaration As SyntaxNode, index As Integer, count As Integer) As SyntaxNode Return Me.RemoveNodes(declaration, GetSubDeclarations(declaration).Skip(index).Take(count)) End Function Private Shared Function GetSubDeclarations(declaration As SyntaxNode) As IReadOnlyList(Of SyntaxNode) Select Case declaration.Kind Case SyntaxKind.FieldDeclaration Return DirectCast(declaration, FieldDeclarationSyntax).Declarators.SelectMany(Function(d) d.Names).ToBoxedImmutableArray() Case SyntaxKind.LocalDeclarationStatement Return DirectCast(declaration, LocalDeclarationStatementSyntax).Declarators.SelectMany(Function(d) d.Names).ToBoxedImmutableArray() Case SyntaxKind.AttributeList Return DirectCast(declaration, AttributeListSyntax).Attributes Case SyntaxKind.ImportsStatement Return DirectCast(declaration, ImportsStatementSyntax).ImportsClauses Case Else Return SpecializedCollections.EmptyReadOnlyList(Of SyntaxNode) End Select End Function Private Shared Function Flatten(members As IReadOnlyList(Of SyntaxNode)) As IReadOnlyList(Of SyntaxNode) Dim builder = ArrayBuilder(Of SyntaxNode).GetInstance() Flatten(builder, members) Return builder.ToImmutableAndFree() End Function Private Shared Sub Flatten(builder As ArrayBuilder(Of SyntaxNode), members As IReadOnlyList(Of SyntaxNode)) For Each member In members If GetDeclarationCount(member) > 1 Then Select Case member.Kind Case SyntaxKind.FieldDeclaration Flatten(builder, DirectCast(member, FieldDeclarationSyntax).Declarators) Case SyntaxKind.LocalDeclarationStatement Flatten(builder, DirectCast(member, LocalDeclarationStatementSyntax).Declarators) Case SyntaxKind.VariableDeclarator Flatten(builder, DirectCast(member, VariableDeclaratorSyntax).Names) Case SyntaxKind.AttributesStatement Flatten(builder, DirectCast(member, AttributesStatementSyntax).AttributeLists) Case SyntaxKind.AttributeList Flatten(builder, DirectCast(member, AttributeListSyntax).Attributes) Case SyntaxKind.ImportsStatement Flatten(builder, DirectCast(member, ImportsStatementSyntax).ImportsClauses) Case Else builder.Add(member) End Select Else builder.Add(member) End If Next End Sub Public Overrides Function RemoveNode(root As SyntaxNode, declaration As SyntaxNode) As SyntaxNode Return RemoveNode(root, declaration, DefaultRemoveOptions) End Function Public Overrides Function RemoveNode(root As SyntaxNode, declaration As SyntaxNode, options As SyntaxRemoveOptions) As SyntaxNode If root.Span.Contains(declaration.Span) Then Return Isolate(root.TrackNodes(declaration), Function(r) RemoveNodeInternal(r, r.GetCurrentNode(declaration), options)) Else Return MyBase.RemoveNode(root, declaration, options) End If End Function Private Shared Function RemoveNodeInternal(root As SyntaxNode, node As SyntaxNode, options As SyntaxRemoveOptions) As SyntaxNode ' special case handling for nodes that remove their parents too Select Case node.Kind Case SyntaxKind.ModifiedIdentifier Dim vd = TryCast(node.Parent, VariableDeclaratorSyntax) If vd IsNot Nothing AndAlso vd.Names.Count = 1 Then ' remove entire variable declarator if only name Return RemoveNodeInternal(root, vd, options) End If Case SyntaxKind.VariableDeclarator If IsChildOfVariableDeclaration(node) AndAlso GetDeclarationCount(node.Parent) = 1 Then ' remove entire parent declaration if this is the only declarator Return RemoveNodeInternal(root, node.Parent, options) End If Case SyntaxKind.AttributeList Dim attrList = DirectCast(node, AttributeListSyntax) Dim attrStmt = TryCast(attrList.Parent, AttributesStatementSyntax) If attrStmt IsNot Nothing AndAlso attrStmt.AttributeLists.Count = 1 Then ' remove entire attribute statement if this is the only attribute list Return RemoveNodeInternal(root, attrStmt, options) End If Case SyntaxKind.Attribute Dim attrList = TryCast(node.Parent, AttributeListSyntax) If attrList IsNot Nothing AndAlso attrList.Attributes.Count = 1 Then ' remove entire attribute list if this is the only attribute Return RemoveNodeInternal(root, attrList, options) End If Case SyntaxKind.SimpleArgument If IsChildOf(node, SyntaxKind.ArgumentList) AndAlso IsChildOf(node.Parent, SyntaxKind.Attribute) Then Dim argList = DirectCast(node.Parent, ArgumentListSyntax) If argList.Arguments.Count = 1 Then ' remove attribute's arg list if this is the only argument Return RemoveNodeInternal(root, argList, options) End If End If Case SyntaxKind.SimpleImportsClause, SyntaxKind.XmlNamespaceImportsClause Dim imps = DirectCast(node.Parent, ImportsStatementSyntax) If imps.ImportsClauses.Count = 1 Then ' remove entire imports statement if this is the only clause Return RemoveNodeInternal(root, node.Parent, options) End If Case Else Dim parent = node.Parent If parent IsNot Nothing Then Select Case parent.Kind Case SyntaxKind.ImplementsStatement Dim imp = DirectCast(parent, ImplementsStatementSyntax) If imp.Types.Count = 1 Then Return RemoveNodeInternal(root, parent, options) End If Case SyntaxKind.InheritsStatement Dim inh = DirectCast(parent, InheritsStatementSyntax) If inh.Types.Count = 1 Then Return RemoveNodeInternal(root, parent, options) End If End Select End If End Select ' do it the normal way Return root.RemoveNode(node, options) End Function Friend Overrides Function IdentifierName(identifier As SyntaxToken) As SyntaxNode Return SyntaxFactory.IdentifierName(identifier) End Function Friend Overrides Function NamedAnonymousObjectMemberDeclarator(identifier As SyntaxNode, expression As SyntaxNode) As SyntaxNode Return SyntaxFactory.NamedFieldInitializer( DirectCast(identifier, IdentifierNameSyntax), DirectCast(expression, ExpressionSyntax)) End Function Friend Overrides Function IsRegularOrDocComment(trivia As SyntaxTrivia) As Boolean Return trivia.IsRegularOrDocComment() End Function Friend Overrides Function RemoveAllComments(node As SyntaxNode) As SyntaxNode Return RemoveLeadingAndTrailingComments(node) End Function Friend Overrides Function RemoveCommentLines(syntaxList As SyntaxTriviaList) As SyntaxTriviaList Return syntaxList.Where(Function(s) Not IsRegularOrDocComment(s)).ToSyntaxTriviaList() End Function Friend Overrides Function ExtensionBlockDeclaration(extensionParameter As SyntaxNode, typeParameters As IEnumerable(Of SyntaxNode), members As IEnumerable(Of SyntaxNode)) As SyntaxNode Throw New NotSupportedException("Extension blocks are not supported in Visual Basic") End Function #End Region End Class End Namespace