|
' 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.Text
Imports System.Threading
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.CodeGeneration
Imports Microsoft.CodeAnalysis.Editor
Imports Microsoft.CodeAnalysis.Editor.Shared.Utilities
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.LineCommit
Imports Microsoft.CodeAnalysis.Editor.VisualBasic.Utilities
Imports Microsoft.CodeAnalysis.Formatting
Imports Microsoft.CodeAnalysis.Host
Imports Microsoft.CodeAnalysis.LanguageService
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Shared.Extensions
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic
Imports Microsoft.CodeAnalysis.VisualBasic.CodeGeneration
Imports Microsoft.CodeAnalysis.VisualBasic.Extensions
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel
Imports Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.InternalElements
Imports Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.Interop
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Utilities
Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel.Extenders
Imports Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel.MethodXml
Imports Microsoft.VisualStudio.Text
Imports Microsoft.VisualStudio.Text.Editor
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel
Partial Friend Class VisualBasicCodeModelService
Inherits AbstractCodeModelService
Private Shared ReadOnly s_emptyTree As SyntaxTree = SyntaxFactory.ParseSyntaxTree(SourceText.From("", encoding:=Nothing, SourceHashAlgorithms.Default))
Private ReadOnly _commitBufferManagerFactory As CommitBufferManagerFactory
Friend Sub New(
provider As HostLanguageServices,
editorOptionsService As EditorOptionsService,
refactorNotifyServices As IEnumerable(Of IRefactorNotifyService),
commitBufferManagerFactory As CommitBufferManagerFactory,
threadingContext As IThreadingContext)
MyBase.New(
provider,
editorOptionsService,
refactorNotifyServices,
LineAdjustmentFormattingRule.Instance,
EndRegionFormattingRule.Instance,
threadingContext)
Me._commitBufferManagerFactory = commitBufferManagerFactory
End Sub
Private Shared ReadOnly s_codeTypeRefAsFullNameFormat As SymbolDisplayFormat =
New SymbolDisplayFormat(
typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.ExpandNullable)
Private Shared ReadOnly s_codeTypeRefAsStringFormat As SymbolDisplayFormat =
New SymbolDisplayFormat(
typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes)
Private Shared ReadOnly s_externalNameFormat As SymbolDisplayFormat =
New SymbolDisplayFormat(
genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.ExpandNullable,
parameterOptions:=SymbolDisplayParameterOptions.IncludeName)
Private Shared ReadOnly s_externalfullNameFormat As SymbolDisplayFormat =
New SymbolDisplayFormat(
typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters,
memberOptions:=SymbolDisplayMemberOptions.IncludeContainingType,
miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.ExpandNullable,
parameterOptions:=SymbolDisplayParameterOptions.IncludeName)
Private Shared ReadOnly s_setTypeFormat As SymbolDisplayFormat =
New SymbolDisplayFormat(
typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.ExpandNullable Or SymbolDisplayMiscellaneousOptions.UseSpecialTypes)
Private Shared ReadOnly s_raiseEventSignatureFormat As SymbolDisplayFormat =
New SymbolDisplayFormat(
typeQualificationStyle:=SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions:=SymbolDisplayGenericsOptions.IncludeTypeParameters,
parameterOptions:=SymbolDisplayParameterOptions.IncludeName Or SymbolDisplayParameterOptions.IncludeParamsRefOut Or SymbolDisplayParameterOptions.IncludeType,
miscellaneousOptions:=SymbolDisplayMiscellaneousOptions.UseSpecialTypes)
Private Shared Function IsNameableNode(node As SyntaxNode) As Boolean
Select Case node.Kind
Case SyntaxKind.Attribute,
SyntaxKind.ClassBlock,
SyntaxKind.ConstructorBlock,
SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement,
SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement,
SyntaxKind.EnumBlock,
SyntaxKind.EnumMemberDeclaration,
SyntaxKind.EventBlock,
SyntaxKind.FunctionBlock,
SyntaxKind.InterfaceBlock,
SyntaxKind.ModuleBlock,
SyntaxKind.NamespaceBlock,
SyntaxKind.OperatorBlock,
SyntaxKind.Parameter,
SyntaxKind.PropertyBlock,
SyntaxKind.StructureBlock,
SyntaxKind.SubBlock,
SyntaxKind.OptionStatement,
SyntaxKind.SimpleImportsClause,
SyntaxKind.InheritsStatement,
SyntaxKind.ImplementsStatement
Return True
Case SyntaxKind.NameColonEquals
Return True
Case SyntaxKind.SimpleArgument,
SyntaxKind.OmittedArgument
' Only arguments in attributes are valid
Return node.FirstAncestorOrSelf(Of AttributeSyntax) IsNot Nothing
Case SyntaxKind.ModifiedIdentifier
Return node.FirstAncestorOrSelf(Of FieldDeclarationSyntax)() IsNot Nothing
Case SyntaxKind.EventStatement
' Only top-level event statements that aren't included in an event block are valid (e.g. single line events)
Return node.FirstAncestorOrSelf(Of EventBlockSyntax)() Is Nothing
Case SyntaxKind.PropertyStatement
' Only top-level property statements that aren't included in an property block are valid (e.g. auto-properties)
Return node.FirstAncestorOrSelf(Of PropertyBlockSyntax)() Is Nothing
Case SyntaxKind.SubStatement,
SyntaxKind.FunctionStatement
Return node.FirstAncestorOrSelf(Of MethodBlockSyntax)() Is Nothing
Case Else
Return False
End Select
End Function
Public Overrides Function GetElementKind(node As SyntaxNode) As EnvDTE.vsCMElement
Select Case node.Kind
Case SyntaxKind.ModuleBlock
Return EnvDTE.vsCMElement.vsCMElementModule
Case SyntaxKind.ClassBlock
Return EnvDTE.vsCMElement.vsCMElementClass
Case Else
Debug.Fail("Unsupported element kind" & CType(node.Kind, SyntaxKind))
Throw Exceptions.ThrowEInvalidArg()
End Select
End Function
Public Overrides Function MatchesScope(node As SyntaxNode, scope As EnvDTE.vsCMElement) As Boolean
'TODO: This has been copied from CSharpCodeModelService. Tweak to implement VB semantics.
Select Case node.Kind
Case SyntaxKind.NamespaceBlock
If scope = EnvDTE.vsCMElement.vsCMElementNamespace AndAlso
node.Parent IsNot Nothing Then
Return True
End If
Case SyntaxKind.ModuleBlock
If scope = EnvDTE.vsCMElement.vsCMElementModule Then
Return True
End If
Case SyntaxKind.ClassBlock
If scope = EnvDTE.vsCMElement.vsCMElementClass Then
Return True
End If
Case SyntaxKind.StructureBlock
If scope = EnvDTE.vsCMElement.vsCMElementStruct Then
Return True
End If
Case SyntaxKind.FunctionStatement,
SyntaxKind.SubStatement
If scope = EnvDTE.vsCMElement.vsCMElementFunction AndAlso
node.FirstAncestorOrSelf(Of MethodBlockSyntax)() Is Nothing Then
Return True
End If
Case SyntaxKind.ConstructorBlock,
SyntaxKind.SubBlock,
SyntaxKind.FunctionBlock,
SyntaxKind.OperatorBlock,
SyntaxKind.GetAccessorBlock,
SyntaxKind.SetAccessorBlock,
SyntaxKind.AddHandlerAccessorBlock,
SyntaxKind.RemoveHandlerAccessorBlock,
SyntaxKind.RaiseEventAccessorBlock
If scope = EnvDTE.vsCMElement.vsCMElementFunction Then
Return True
End If
Case SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement
If scope = EnvDTE.vsCMElement.vsCMElementDeclareDecl Then
Return True
End If
Case SyntaxKind.EnumMemberDeclaration
If scope = EnvDTE.vsCMElement.vsCMElementVariable Then
Return True
End If
Case SyntaxKind.FieldDeclaration
If scope = EnvDTE.vsCMElement.vsCMElementVariable Then
Return True
End If
Case SyntaxKind.EventBlock
If scope = EnvDTE.vsCMElement.vsCMElementEvent Then
Return True
End If
Case SyntaxKind.EventStatement
If Not TypeOf node.Parent Is EventBlockSyntax Then
If scope = EnvDTE.vsCMElement.vsCMElementEvent Then
Return True
End If
End If
Case SyntaxKind.PropertyBlock
If scope = EnvDTE.vsCMElement.vsCMElementProperty Then
Return True
End If
Case SyntaxKind.PropertyStatement
If Not TypeOf node.Parent Is PropertyBlockSyntax Then
If scope = EnvDTE.vsCMElement.vsCMElementProperty Then
Return True
End If
End If
Case SyntaxKind.Attribute
If scope = EnvDTE.vsCMElement.vsCMElementAttribute Then
Return True
End If
Case SyntaxKind.InterfaceBlock
If scope = EnvDTE.vsCMElement.vsCMElementInterface Then
Return True
End If
Case SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement
If scope = EnvDTE.vsCMElement.vsCMElementDelegate Then
Return True
End If
Case SyntaxKind.EnumBlock
If scope = EnvDTE.vsCMElement.vsCMElementEnum Then
Return True
End If
Case SyntaxKind.StructureBlock
If scope = EnvDTE.vsCMElement.vsCMElementStruct Then
Return True
End If
Case SyntaxKind.SimpleImportsClause
If scope = EnvDTE.vsCMElement.vsCMElementImportStmt Then
Return True
End If
Case SyntaxKind.ModifiedIdentifier,
SyntaxKind.VariableDeclarator
If node.Parent.Kind <> SyntaxKind.Parameter Then
' The parent of an identifier/variable declarator may be a
' field. If the parent matches the desired scope, then this
' node matches as well.
Return MatchesScope(node.Parent, scope)
End If
Case SyntaxKind.Parameter
If scope = EnvDTE.vsCMElement.vsCMElementParameter Then
Return True
End If
Case SyntaxKind.OptionStatement
If scope = EnvDTE.vsCMElement.vsCMElementOptionStmt Then
Return True
End If
Case SyntaxKind.InheritsStatement
If scope = EnvDTE.vsCMElement.vsCMElementInheritsStmt Then
Return True
End If
Case SyntaxKind.ImplementsStatement
If scope = EnvDTE.vsCMElement.vsCMElementImplementsStmt Then
Return True
End If
Case Else
Return False
End Select
Return False
End Function
Public Overrides Function GetOptionNodes(parent As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf parent Is CompilationUnitSyntax Then
Return DirectCast(parent, CompilationUnitSyntax).Options.AsEnumerable()
End If
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End Function
Private Overloads Shared Function GetImportNodes(parent As CompilationUnitSyntax) As IEnumerable(Of SyntaxNode)
Dim result = New List(Of SyntaxNode)
For Each importStatement In parent.Imports
For Each importClause In importStatement.ImportsClauses
' NOTE: XmlNamespaceImportsClause is not support by VB Code Model
If importClause.IsKind(SyntaxKind.SimpleImportsClause) Then
result.Add(importClause)
End If
Next
Next
Return result
End Function
Public Overrides Function GetImportNodes(parent As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf parent Is CompilationUnitSyntax Then
Return GetImportNodes(DirectCast(parent, CompilationUnitSyntax))
End If
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End Function
Private Overloads Shared Function GetAttributeNodes(attributesBlockList As SyntaxList(Of AttributeListSyntax)) As IEnumerable(Of SyntaxNode)
Dim result = New List(Of SyntaxNode)
For Each attributeBlock In attributesBlockList
For Each attribute In attributeBlock.Attributes
result.Add(attribute)
Next
Next
Return result
End Function
Private Overloads Shared Function GetAttributeNodes(attributesStatementList As SyntaxList(Of AttributesStatementSyntax)) As IEnumerable(Of SyntaxNode)
Dim result = New List(Of SyntaxNode)
For Each attributesStatement In attributesStatementList
For Each attributeBlock In attributesStatement.AttributeLists
For Each attribute In attributeBlock.Attributes
result.Add(attribute)
Next
Next
Next
Return result
End Function
Public Overrides Function GetAttributeNodes(node As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf node Is CompilationUnitSyntax Then
Return GetAttributeNodes(DirectCast(node, CompilationUnitSyntax).Attributes)
ElseIf TypeOf node Is TypeBlockSyntax Then
Return GetAttributeNodes(DirectCast(node, TypeBlockSyntax).BlockStatement.AttributeLists)
ElseIf TypeOf node Is EnumBlockSyntax Then
Return GetAttributeNodes(DirectCast(node, EnumBlockSyntax).EnumStatement.AttributeLists)
ElseIf TypeOf node Is DelegateStatementSyntax Then
Return GetAttributeNodes(DirectCast(node, DelegateStatementSyntax).AttributeLists)
ElseIf TypeOf node Is DeclareStatementSyntax Then
Return GetAttributeNodes(DirectCast(node, DeclareStatementSyntax).AttributeLists)
ElseIf TypeOf node Is MethodStatementSyntax Then
Return GetAttributeNodes(DirectCast(node, MethodStatementSyntax).AttributeLists)
ElseIf TypeOf node Is MethodBlockBaseSyntax Then
Return GetAttributeNodes(DirectCast(node, MethodBlockBaseSyntax).BlockStatement.AttributeLists)
ElseIf TypeOf node Is PropertyBlockSyntax Then
Return GetAttributeNodes(DirectCast(node, PropertyBlockSyntax).PropertyStatement.AttributeLists)
ElseIf TypeOf node Is PropertyStatementSyntax Then
Return GetAttributeNodes(DirectCast(node, PropertyStatementSyntax).AttributeLists)
ElseIf TypeOf node Is EventBlockSyntax Then
Return GetAttributeNodes(DirectCast(node, EventBlockSyntax).EventStatement.AttributeLists)
ElseIf TypeOf node Is EventStatementSyntax Then
Return GetAttributeNodes(DirectCast(node, EventStatementSyntax).AttributeLists)
ElseIf TypeOf node Is FieldDeclarationSyntax Then
Return GetAttributeNodes(DirectCast(node, FieldDeclarationSyntax).AttributeLists)
ElseIf TypeOf node Is ParameterSyntax Then
Return GetAttributeNodes(DirectCast(node, ParameterSyntax).AttributeLists)
ElseIf TypeOf node Is EnumMemberDeclarationSyntax Then
Return GetAttributeNodes(DirectCast(node, EnumMemberDeclarationSyntax).AttributeLists)
ElseIf TypeOf node Is ModifiedIdentifierSyntax OrElse
TypeOf node Is VariableDeclaratorSyntax Then
Return GetAttributeNodes(node.Parent)
End If
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End Function
Public Overrides Function GetAttributeArgumentNodes(parent As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf parent Is AttributeSyntax Then
Dim attribute = DirectCast(parent, AttributeSyntax)
If attribute.ArgumentList Is Nothing Then
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End If
Return attribute.ArgumentList.Arguments
End If
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End Function
Public Overrides Function GetInheritsNodes(parent As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf parent Is TypeBlockSyntax Then
Dim typeBlock = DirectCast(parent, TypeBlockSyntax)
Return typeBlock.Inherits.AsEnumerable()
End If
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End Function
Public Overrides Function GetImplementsNodes(parent As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf parent Is TypeBlockSyntax Then
Dim typeBlock = DirectCast(parent, TypeBlockSyntax)
Return typeBlock.Implements.AsEnumerable()
End If
Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
End Function
Private Shared Function IsContainerNode(container As SyntaxNode) As Boolean
Return TypeOf container Is CompilationUnitSyntax OrElse
TypeOf container Is NamespaceBlockSyntax OrElse
TypeOf container Is TypeBlockSyntax OrElse
TypeOf container Is EnumBlockSyntax
End Function
Private Shared Function IsNamespaceOrTypeDeclaration(node As SyntaxNode) As Boolean
Return node.Kind() = SyntaxKind.NamespaceBlock OrElse
TypeOf node Is TypeBlockSyntax OrElse
TypeOf node Is EnumBlockSyntax OrElse
TypeOf node Is DelegateStatementSyntax
End Function
Private Shared Iterator Function GetChildMemberNodes(container As SyntaxNode) As IEnumerable(Of DeclarationStatementSyntax)
If TypeOf container Is CompilationUnitSyntax Then
For Each member In DirectCast(container, CompilationUnitSyntax).Members
If IsNamespaceOrTypeDeclaration(member) Then
Yield DirectCast(member, DeclarationStatementSyntax)
End If
Next
ElseIf TypeOf container Is NamespaceBlockSyntax Then
For Each member In DirectCast(container, NamespaceBlockSyntax).Members
If IsNamespaceOrTypeDeclaration(member) Then
Yield DirectCast(member, DeclarationStatementSyntax)
End If
Next
ElseIf TypeOf container Is TypeBlockSyntax Then
For Each member In DirectCast(container, TypeBlockSyntax).Members
If member.Kind() <> SyntaxKind.NamespaceBlock AndAlso TypeOf member Is DeclarationStatementSyntax Then
Yield DirectCast(member, DeclarationStatementSyntax)
End If
Next
ElseIf TypeOf container Is EnumBlockSyntax Then
For Each member In DirectCast(container, EnumBlockSyntax).Members
If member.Kind() = SyntaxKind.EnumMemberDeclaration Then
Yield DirectCast(member, DeclarationStatementSyntax)
End If
Next
End If
End Function
Private Shared Function NodeIsSupported(test As Boolean, node As SyntaxNode) As Boolean
Return Not test OrElse IsNameableNode(node)
End Function
''' <summary>
''' Retrieves the members of a specified <paramref name="container"/> node. The members that are
''' returned can be controlled by passing various parameters.
''' </summary>
''' <param name="container">The <see cref="SyntaxNode"/> from which to retrieve members.</param>
''' <param name="includeSelf">If true, the container Is returned as well.</param>
''' <param name="recursive">If true, members are recursed to return descendant members as well
''' as immediate children. For example, a namespace would return the namespaces And types within.
''' However, if <paramref name="recursive"/> Is true, members with the namespaces And types would
''' also be returned.</param>
''' <param name="logicalFields">If true, field declarations are broken into their respective declarators.
''' For example, the field "Dim x, y As Integer" would return two nodes, one for x And one for y in place
''' of the field.</param>
''' <param name="onlySupportedNodes">If true, only members supported by Code Model are returned.</param>
Public Overrides Iterator Function GetMemberNodes(container As SyntaxNode, includeSelf As Boolean, recursive As Boolean, logicalFields As Boolean, onlySupportedNodes As Boolean) As IEnumerable(Of SyntaxNode)
If Not IsContainerNode(container) Then
Exit Function
End If
If includeSelf AndAlso NodeIsSupported(onlySupportedNodes, container) Then
Yield container
End If
For Each member In GetChildMemberNodes(container)
If member.Kind = SyntaxKind.FieldDeclaration Then
' For fields, the 'logical' and 'supported' flags are intrinsically tied.
' * If 'logical' is true, only declarators should be returned, regardless of the value of 'supported'.
' * If 'logical' is false, the field should only be returned if 'supported' is also false.
If logicalFields Then
For Each declarator In DirectCast(member, FieldDeclarationSyntax).Declarators
' We know that declarators are supported, so there's no need to check them here.
For Each identifier In declarator.Names
Yield identifier
Next
Next
ElseIf Not onlySupportedNodes Then
' Only return fields if the supported flag Is false.
Yield member
End If
ElseIf NodeIsSupported(onlySupportedNodes, member) Then
Yield member
End If
If recursive AndAlso IsContainerNode(member) Then
For Each innerMember In GetMemberNodes(member, includeSelf:=False, recursive:=True, logicalFields:=logicalFields, onlySupportedNodes:=onlySupportedNodes)
Yield innerMember
Next
End If
Next
End Function
Public Overrides ReadOnly Property Language As String
Get
Return EnvDTE.CodeModelLanguageConstants.vsCMLanguageVB
End Get
End Property
Public Overrides ReadOnly Property AssemblyAttributeString As String
Get
Return "Assembly"
End Get
End Property
''' <summary>
''' Do not use this method directly! Instead, go through <see cref="FileCodeModel.GetOrCreateCodeElement(Of T)(SyntaxNode)"/>
''' </summary>
Public Overloads Overrides Function CreateInternalCodeElement(
state As CodeModelState,
fileCodeModel As FileCodeModel,
node As SyntaxNode
) As EnvDTE.CodeElement
Select Case node.Kind
Case SyntaxKind.Attribute
Return CType(CreateInternalCodeAttribute(state, fileCodeModel, node), EnvDTE.CodeElement)
Case SyntaxKind.NameColonEquals
Return Nothing
Case SyntaxKind.SimpleArgument
Return CType(CreateInternalCodeAttributeArgument(state, fileCodeModel, node), EnvDTE.CodeElement)
Case SyntaxKind.SimpleImportsClause
Return CType(CreateInternalCodeImport(state, fileCodeModel, node), EnvDTE.CodeElement)
Case SyntaxKind.ImportsStatement
Dim importsStatement = DirectCast(node, ImportsStatementSyntax)
Return CreateInternalCodeElement(state, fileCodeModel, importsStatement.ImportsClauses(0))
Case SyntaxKind.Parameter
Return CType(CreateInternalCodeParameter(state, fileCodeModel, node), EnvDTE.CodeElement)
Case SyntaxKind.OptionStatement
Return CType(CreateInternalCodeOptionStatement(state, fileCodeModel, node), EnvDTE.CodeElement)
Case SyntaxKind.InheritsStatement
Return CType(CreateInternalCodeInheritsStatement(state, fileCodeModel, node), EnvDTE.CodeElement)
Case SyntaxKind.ImplementsStatement
Return CType(CreateInternalCodeImplementsStatement(state, fileCodeModel, node), EnvDTE.CodeElement)
End Select
If IsAccessorNode(node) Then
Return CType(CreateInternalCodeAccessorFunction(state, fileCodeModel, node), EnvDTE.CodeElement)
End If
Dim nodeKey = GetNodeKey(node)
Select Case node.Kind
Case SyntaxKind.ClassBlock,
SyntaxKind.ModuleBlock
Return CType(CodeClass.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.StructureBlock
Return CType(CodeStruct.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.InterfaceBlock
Return CType(CodeInterface.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.EnumBlock
Return CType(CodeEnum.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement
Return CType(CodeDelegate.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.ConstructorBlock,
SyntaxKind.FunctionBlock,
SyntaxKind.OperatorBlock,
SyntaxKind.SubBlock,
SyntaxKind.SubStatement,
SyntaxKind.FunctionStatement
Return CType(CodeFunctionWithEventHandler.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement
Return CType(CodeFunctionDeclareDecl.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.PropertyBlock,
SyntaxKind.PropertyStatement
Return CType(CodeProperty.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.EventBlock,
SyntaxKind.EventStatement
Return CType(CodeEvent.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.NamespaceBlock
Return CType(CodeNamespace.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case SyntaxKind.ModifiedIdentifier,
SyntaxKind.EnumMemberDeclaration
Return CType(CodeVariable.Create(state, fileCodeModel, nodeKey, node.Kind), EnvDTE.CodeElement)
Case Else
Throw New NotImplementedException()
End Select
End Function
Public Overrides Function CreateUnknownCodeElement(state As CodeModelState, fileCodeModel As FileCodeModel, node As SyntaxNode) As EnvDTE.CodeElement
Select Case node.Kind
Case SyntaxKind.ClassBlock,
SyntaxKind.ModuleBlock
Return CType(CodeClass.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.StructureBlock
Return CType(CodeStruct.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.InterfaceBlock
Return CType(CodeInterface.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.EnumBlock
Return CType(CodeEnum.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement
Return CType(CodeDelegate.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.ConstructorBlock,
SyntaxKind.FunctionBlock,
SyntaxKind.OperatorBlock,
SyntaxKind.SubBlock,
SyntaxKind.SubStatement,
SyntaxKind.FunctionStatement
Return CType(CodeFunctionWithEventHandler.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement
Return CType(CodeFunctionDeclareDecl.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.PropertyBlock,
SyntaxKind.PropertyStatement
Return CType(CodeProperty.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.EventBlock,
SyntaxKind.EventStatement
Return CType(CodeEvent.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.NamespaceBlock
Return CType(CodeNamespace.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.ModifiedIdentifier,
SyntaxKind.EnumMemberDeclaration
Return CType(CodeVariable.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.SimpleImportsClause
Return CType(CodeImport.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.OptionStatement
Return CType(CodeOptionsStatement.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.InheritsStatement
Return CType(CodeInheritsStatement.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case SyntaxKind.ImplementsStatement
Return CType(CodeImplementsStatement.CreateUnknown(state, fileCodeModel, node.Kind, GetName(node)), EnvDTE.CodeElement)
Case Else
Throw New NotImplementedException()
End Select
End Function
Public Overrides Function CreateUnknownRootNamespaceCodeElement(state As CodeModelState, fileCodeModel As FileCodeModel) As EnvDTE.CodeElement
Dim compilation = CType(fileCodeModel.GetCompilation(), Compilation)
Dim rootNamespace = DirectCast(compilation.Options, VisualBasicCompilationOptions).RootNamespace
Return CType(CodeNamespace.CreateUnknown(state, fileCodeModel, SyntaxKind.NamespaceBlock, rootNamespace), EnvDTE.CodeElement)
End Function
Private Shared Function IsValidTypeRefKind(kind As EnvDTE.vsCMTypeRef) As Boolean
Return kind = EnvDTE.vsCMTypeRef.vsCMTypeRefVoid OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefObject OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefBool OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefByte OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefShort OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefInt OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefLong OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefDecimal OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefFloat OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefDouble OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefChar OrElse
kind = EnvDTE.vsCMTypeRef.vsCMTypeRefString OrElse
kind = EnvDTE80.vsCMTypeRef2.vsCMTypeRefSByte OrElse
kind = EnvDTE80.vsCMTypeRef2.vsCMTypeRefUnsignedInt OrElse
kind = EnvDTE80.vsCMTypeRef2.vsCMTypeRefUnsignedLong OrElse
kind = EnvDTE80.vsCMTypeRef2.vsCMTypeRefUnsignedShort
End Function
Public Overrides Function CreateCodeTypeRef(state As CodeModelState, projectId As ProjectId, type As Object) As EnvDTE.CodeTypeRef
Dim project = state.Workspace.CurrentSolution.GetProject(projectId)
If project Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim compilation = project.GetCompilationAsync().Result
If TypeOf type Is Byte OrElse
TypeOf type Is Short OrElse
TypeOf type Is Integer Then
Dim typeRefKind = CType(type, EnvDTE.vsCMTypeRef)
If Not IsValidTypeRefKind(typeRefKind) Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim specialType = GetSpecialType(typeRefKind)
Return CodeTypeRef.Create(state, Nothing, projectId, compilation.GetSpecialType(specialType))
End If
Dim typeName As String
Dim parent As Object = Nothing
If TypeOf type Is String Then
typeName = CStr(type)
ElseIf TypeOf type Is EnvDTE.CodeType Then
typeName = CType(type, EnvDTE.CodeType).FullName
parent = type
Else
Throw Exceptions.ThrowEInvalidArg()
End If
Dim typeSymbol = GetTypeSymbolFromFullName(typeName, compilation)
If typeSymbol Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Return CodeTypeRef.Create(state, parent, projectId, typeSymbol)
End Function
Public Overrides Function GetTypeKindForCodeTypeRef(typeSymbol As ITypeSymbol) As EnvDTE.vsCMTypeRef
' Rough translation of CodeModelSymbol::GetTypeKind from vb\Language\VsPackage\CodeModelHelpers.cpp
If typeSymbol.SpecialType = SpecialType.System_Void Then
Return EnvDTE.vsCMTypeRef.vsCMTypeRefVoid
End If
If typeSymbol.TypeKind = TypeKind.Array Then
Return EnvDTE.vsCMTypeRef.vsCMTypeRefArray
End If
If typeSymbol.TypeKind = TypeKind.Pointer Then
typeSymbol = DirectCast(typeSymbol, IPointerTypeSymbol).PointedAtType
End If
If typeSymbol IsNot Nothing AndAlso Not typeSymbol.TypeKind = TypeKind.Error Then
If typeSymbol.SpecialType = SpecialType.System_Object Then
Return EnvDTE.vsCMTypeRef.vsCMTypeRefObject
End If
If typeSymbol.TypeKind = TypeKind.Enum Then
Return EnvDTE.vsCMTypeRef.vsCMTypeRefCodeType
End If
Select Case typeSymbol.SpecialType
Case SpecialType.System_Boolean
Return EnvDTE.vsCMTypeRef.vsCMTypeRefBool
Case SpecialType.System_SByte
Return CType(EnvDTE80.vsCMTypeRef2.vsCMTypeRefSByte, EnvDTE.vsCMTypeRef)
Case SpecialType.System_Byte
Return EnvDTE.vsCMTypeRef.vsCMTypeRefByte
Case SpecialType.System_Int16
Return EnvDTE.vsCMTypeRef.vsCMTypeRefShort
Case SpecialType.System_UInt16
Return CType(EnvDTE80.vsCMTypeRef2.vsCMTypeRefUnsignedShort, EnvDTE.vsCMTypeRef)
Case SpecialType.System_Int32
Return EnvDTE.vsCMTypeRef.vsCMTypeRefInt
Case SpecialType.System_UInt32
Return CType(EnvDTE80.vsCMTypeRef2.vsCMTypeRefUnsignedInt, EnvDTE.vsCMTypeRef)
Case SpecialType.System_Int64
Return EnvDTE.vsCMTypeRef.vsCMTypeRefLong
Case SpecialType.System_UInt64
Return CType(EnvDTE80.vsCMTypeRef2.vsCMTypeRefUnsignedLong, EnvDTE.vsCMTypeRef)
Case SpecialType.System_Decimal
Return EnvDTE.vsCMTypeRef.vsCMTypeRefDecimal
Case SpecialType.System_Single
Return EnvDTE.vsCMTypeRef.vsCMTypeRefFloat
Case SpecialType.System_Double
Return EnvDTE.vsCMTypeRef.vsCMTypeRefDouble
Case SpecialType.System_Char
Return EnvDTE.vsCMTypeRef.vsCMTypeRefChar
Case SpecialType.System_String
Return EnvDTE.vsCMTypeRef.vsCMTypeRefString
End Select
If typeSymbol.TypeKind = TypeKind.Pointer Then
Return EnvDTE.vsCMTypeRef.vsCMTypeRefPointer
End If
If typeSymbol.TypeKind = TypeKind.TypeParameter Then
Return EnvDTE.vsCMTypeRef.vsCMTypeRefOther
End If
Return EnvDTE.vsCMTypeRef.vsCMTypeRefCodeType
End If
Return EnvDTE.vsCMTypeRef.vsCMTypeRefOther
End Function
Public Overrides Function GetAsFullNameForCodeTypeRef(typeSymbol As ITypeSymbol) As String
Return typeSymbol.ToDisplayString(s_codeTypeRefAsFullNameFormat)
End Function
Public Overrides Function GetAsStringForCodeTypeRef(typeSymbol As ITypeSymbol) As String
Return typeSymbol.ToDisplayString(s_codeTypeRefAsStringFormat)
End Function
Public Overrides Function IsParameterNode(node As SyntaxNode) As Boolean
Return TypeOf node Is ParameterSyntax
End Function
Public Overrides Function IsAttributeNode(node As SyntaxNode) As Boolean
Return TypeOf node Is AttributeSyntax
End Function
Public Overrides Function IsAttributeArgumentNode(node As SyntaxNode) As Boolean
Return TypeOf node Is SimpleArgumentSyntax OrElse
TypeOf node Is OmittedArgumentSyntax
End Function
Public Overrides Function IsOptionNode(node As SyntaxNode) As Boolean
Return TypeOf node Is OptionStatementSyntax
End Function
Public Overrides Function IsImportNode(node As SyntaxNode) As Boolean
Return TypeOf node Is SimpleImportsClauseSyntax
End Function
Public Overrides Function GetUnescapedName(name As String) As String
Return If(name IsNot Nothing AndAlso name.Length > 2 AndAlso name.StartsWith("[", StringComparison.Ordinal) AndAlso name.EndsWith("]", StringComparison.Ordinal),
name.Substring(1, name.Length - 2),
name)
End Function
Private Shared Function GetNormalizedName(node As SyntaxNode) As String
Dim nameBuilder = New StringBuilder()
Dim token = node.GetFirstToken(includeSkipped:=True)
While True
nameBuilder.Append(token.ToString())
Dim nextToken = token.GetNextToken(includeSkipped:=True)
If Not nextToken.IsDescendantOf(node) Then
Exit While
End If
If (token.IsKeyword() OrElse token.Kind = SyntaxKind.IdentifierToken) AndAlso
(nextToken.IsKeyword() OrElse nextToken.Kind = SyntaxKind.IdentifierToken) Then
nameBuilder.Append(" "c)
End If
token = nextToken
End While
Return nameBuilder.ToString().Trim()
End Function
Public Overrides Function GetName(node As SyntaxNode) As String
If node Is Nothing Then
Throw New ArgumentNullException(NameOf(node))
End If
Debug.Assert(TypeOf node Is SyntaxNode)
Debug.Assert(IsNameableNode(node))
Select Case node.Kind
Case SyntaxKind.Attribute
Return GetNormalizedName(DirectCast(node, AttributeSyntax).Name)
Case SyntaxKind.ClassBlock,
SyntaxKind.InterfaceBlock,
SyntaxKind.ModuleBlock,
SyntaxKind.StructureBlock
Return DirectCast(node, TypeBlockSyntax).BlockStatement.Identifier.ToString()
Case SyntaxKind.EnumBlock
Return DirectCast(node, EnumBlockSyntax).EnumStatement.Identifier.ToString()
Case SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement
Return DirectCast(node, DelegateStatementSyntax).Identifier.ToString()
Case SyntaxKind.NamespaceBlock
Return DirectCast(node, NamespaceBlockSyntax).NamespaceStatement.Name.ToString()
Case SyntaxKind.SubBlock,
SyntaxKind.FunctionBlock
Dim methodBlock = DirectCast(node, MethodBlockSyntax)
Return methodBlock.SubOrFunctionStatement.Identifier.ToString()
Case SyntaxKind.SubStatement,
SyntaxKind.FunctionStatement
Return DirectCast(node, MethodStatementSyntax).Identifier.ToString()
Case SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement
Return DirectCast(node, DeclareStatementSyntax).Identifier.ToString()
Case SyntaxKind.ConstructorBlock
Dim methodBlock = DirectCast(node, ConstructorBlockSyntax)
Return methodBlock.SubNewStatement.NewKeyword.ToString()
Case SyntaxKind.OperatorBlock
Dim operatorBlock = DirectCast(node, OperatorBlockSyntax)
Return operatorBlock.OperatorStatement.OperatorToken.ToString()
Case SyntaxKind.PropertyBlock
Dim propertyBlock = DirectCast(node, PropertyBlockSyntax)
Return propertyBlock.PropertyStatement.Identifier.ToString()
Case SyntaxKind.PropertyStatement
Return DirectCast(node, PropertyStatementSyntax).Identifier.ToString()
Case SyntaxKind.EventBlock
Return DirectCast(node, EventBlockSyntax).EventStatement.Identifier.ToString()
Case SyntaxKind.EventStatement
Return DirectCast(node, EventStatementSyntax).Identifier.ToString()
Case SyntaxKind.ModifiedIdentifier
Return DirectCast(node, ModifiedIdentifierSyntax).Identifier.ToString()
Case SyntaxKind.EnumMemberDeclaration
Return DirectCast(node, EnumMemberDeclarationSyntax).Identifier.ToString()
Case SyntaxKind.SimpleArgument
Dim simpleArgument = DirectCast(node, SimpleArgumentSyntax)
Return If(simpleArgument.IsNamed,
simpleArgument.NameColonEquals.Name.ToString(),
String.Empty)
Case SyntaxKind.OmittedArgument
Return String.Empty
Case SyntaxKind.Parameter
Return GetParameterName(node)
Case SyntaxKind.OptionStatement
Return GetNormalizedName(node)
Case SyntaxKind.SimpleImportsClause
Return GetNormalizedName(DirectCast(node, ImportsClauseSyntax).GetName())
Case SyntaxKind.InheritsStatement
Return DirectCast(node, InheritsStatementSyntax).InheritsKeyword.ToString()
Case SyntaxKind.ImplementsStatement
Return DirectCast(node, ImplementsStatementSyntax).ImplementsKeyword.ToString()
Case Else
Debug.Fail(String.Format("Invalid node kind: {0}", node.Kind))
Throw New ArgumentException()
End Select
End Function
Public Overrides Function SetName(node As SyntaxNode, name As String) As SyntaxNode
If node Is Nothing Then
Throw New ArgumentNullException(NameOf(node))
End If
' In all cases, the resulting syntax for the new name has elastic trivia attached,
' whether via this call to SyntaxFactory.Identifier or via explicitly added elastic
' markers.
Dim identifier As SyntaxToken = SyntaxFactory.Identifier(name)
Select Case node.Kind
Case SyntaxKind.Attribute
Return DirectCast(node, AttributeSyntax).WithName(
SyntaxFactory.ParseTypeName(name) _
.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker)) _
.WithTrailingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker)))
Case SyntaxKind.ClassStatement
Return DirectCast(node, ClassStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.InterfaceStatement
Return DirectCast(node, InterfaceStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.ModuleStatement
Return DirectCast(node, ModuleStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.StructureStatement
Return DirectCast(node, StructureStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.EnumStatement
Return DirectCast(node, EnumStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement
Return DirectCast(node, DelegateStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.NamespaceStatement
Return DirectCast(node, NamespaceStatementSyntax).WithName(
SyntaxFactory.ParseName(name) _
.WithLeadingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker)) _
.WithTrailingTrivia(SyntaxFactory.TriviaList(SyntaxFactory.ElasticMarker)))
Case SyntaxKind.SubStatement,
SyntaxKind.FunctionStatement,
SyntaxKind.SubNewStatement
Return DirectCast(node, MethodStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareFunctionStatement
Return DirectCast(node, DeclareStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.PropertyStatement
Return DirectCast(node, PropertyStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.EventStatement
Return DirectCast(node, EventStatementSyntax).WithIdentifier(identifier)
Case SyntaxKind.ModifiedIdentifier
Return DirectCast(node, ModifiedIdentifierSyntax).WithIdentifier(identifier)
Case SyntaxKind.SimpleArgument
Return DirectCast(node, SimpleArgumentSyntax).WithNameColonEquals(SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName(name)))
Case Else
Debug.Fail("Invalid node kind: " & CType(node.Kind, SyntaxKind))
Throw Exceptions.ThrowEFail()
End Select
End Function
Public Overrides Function GetNodeWithName(node As SyntaxNode) As SyntaxNode
If node Is Nothing Then
Throw New ArgumentNullException(NameOf(node))
End If
If node.Kind = SyntaxKind.OperatorBlock Then
Throw Exceptions.ThrowEFail
End If
Debug.Assert(IsNameableNode(node))
Select Case node.Kind
Case SyntaxKind.Attribute
Return node
Case SyntaxKind.ClassBlock,
SyntaxKind.InterfaceBlock,
SyntaxKind.ModuleBlock,
SyntaxKind.StructureBlock
Return DirectCast(node, TypeBlockSyntax).BlockStatement
Case SyntaxKind.EnumBlock
Return DirectCast(node, EnumBlockSyntax).EnumStatement
Case SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement
Return node
Case SyntaxKind.NamespaceBlock
Return DirectCast(node, NamespaceBlockSyntax).NamespaceStatement
Case SyntaxKind.SubBlock,
SyntaxKind.FunctionBlock,
SyntaxKind.ConstructorBlock
Return DirectCast(node, MethodBlockBaseSyntax).BlockStatement
Case SyntaxKind.PropertyBlock
Return DirectCast(node, PropertyBlockSyntax).PropertyStatement
Case SyntaxKind.EventBlock
Return DirectCast(node, EventBlockSyntax).EventStatement
Case SyntaxKind.ModifiedIdentifier
Return node
Case SyntaxKind.SimpleArgument
Dim simpleArgument = DirectCast(node, SimpleArgumentSyntax)
Return If(simpleArgument.IsNamed, simpleArgument.NameColonEquals.Name, node)
Case SyntaxKind.SubStatement,
SyntaxKind.FunctionStatement,
SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement
Return node
Case SyntaxKind.EventStatement
Return node
Case Else
Debug.Fail("Invalid node kind: " & CType(node.Kind, SyntaxKind))
Throw New ArgumentException()
End Select
End Function
Public Overrides Function GetFullName(node As SyntaxNode, semanticModel As SemanticModel) As String
If node.Kind = SyntaxKind.SimpleImportsClause Then
Throw Exceptions.ThrowENotImpl()
End If
Dim symbol = If(TypeOf node Is AttributeSyntax,
semanticModel.GetTypeInfo(node).Type,
semanticModel.GetDeclaredSymbol(node))
Return GetExternalSymbolFullName(symbol)
End Function
Public Overrides Function IsExpressionBodiedProperty(node As SyntaxNode) As Boolean
Return False
End Function
Public Overrides Function TryGetAutoPropertyExpressionBody(parentNode As SyntaxNode, ByRef accessorNode As SyntaxNode) As Boolean
Return False
End Function
Public Overrides Function IsAccessorNode(node As SyntaxNode) As Boolean
Select Case node.Kind
Case SyntaxKind.GetAccessorBlock,
SyntaxKind.SetAccessorBlock,
SyntaxKind.AddHandlerAccessorBlock,
SyntaxKind.RemoveHandlerAccessorBlock,
SyntaxKind.RaiseEventAccessorBlock
Return True
End Select
Return False
End Function
Public Overrides Function GetAccessorKind(node As SyntaxNode) As MethodKind
Select Case node.Kind
Case SyntaxKind.GetAccessorBlock
Return MethodKind.PropertyGet
Case SyntaxKind.SetAccessorBlock
Return MethodKind.PropertySet
Case SyntaxKind.AddHandlerAccessorBlock
Return MethodKind.EventAdd
Case SyntaxKind.RemoveHandlerAccessorBlock
Return MethodKind.EventRemove
Case SyntaxKind.RaiseEventAccessorBlock
Return MethodKind.EventRaise
Case Else
Throw Exceptions.ThrowEUnexpected()
End Select
End Function
Private Overloads Shared Function GetAccessorKind(methodKind As MethodKind) As SyntaxKind
Select Case methodKind
Case MethodKind.PropertyGet
Return SyntaxKind.GetAccessorBlock
Case MethodKind.PropertySet
Return SyntaxKind.SetAccessorBlock
Case MethodKind.EventAdd
Return SyntaxKind.AddHandlerAccessorBlock
Case MethodKind.EventRemove
Return SyntaxKind.RemoveHandlerAccessorBlock
Case MethodKind.EventRaise
Return SyntaxKind.RaiseEventAccessorBlock
Case Else
Throw Exceptions.ThrowEUnexpected()
End Select
End Function
Private Shared Function GetAccessors(node As SyntaxNode) As SyntaxList(Of AccessorBlockSyntax)
Select Case node.Kind()
Case SyntaxKind.PropertyBlock
Return DirectCast(node, PropertyBlockSyntax).Accessors
Case SyntaxKind.EventBlock
Return DirectCast(node, EventBlockSyntax).Accessors
Case Else
Return Nothing
End Select
End Function
Public Overrides Function TryGetAccessorNode(parentNode As SyntaxNode, kind As MethodKind, ByRef accessorNode As SyntaxNode) As Boolean
Dim accessorKind = GetAccessorKind(kind)
For Each accessor In GetAccessors(parentNode)
If accessor.Kind = accessorKind Then
accessorNode = accessor
Return True
End If
Next
accessorNode = Nothing
Return False
End Function
Public Overrides Function TryGetParameterNode(parentNode As SyntaxNode, name As String, ByRef parameterNode As SyntaxNode) As Boolean
For Each parameter As ParameterSyntax In GetParameterNodes(parentNode)
Dim parameterName = GetNameFromParameter(parameter)
If String.Equals(parameterName, name, StringComparison.OrdinalIgnoreCase) Then
parameterNode = parameter
Return True
End If
Next
parameterNode = Nothing
Return False
End Function
Private Overloads Shared Function GetParameterNodes(methodStatement As MethodBaseSyntax) As IEnumerable(Of ParameterSyntax)
Return If(methodStatement.ParameterList IsNot Nothing,
methodStatement.ParameterList.Parameters,
SpecializedCollections.EmptyEnumerable(Of ParameterSyntax))
End Function
Public Overloads Overrides Function GetParameterNodes(parent As SyntaxNode) As IEnumerable(Of SyntaxNode)
If TypeOf parent Is MethodBaseSyntax Then
Return GetParameterNodes(DirectCast(parent, MethodBaseSyntax))
ElseIf TypeOf parent Is MethodBlockBaseSyntax Then
Return GetParameterNodes(DirectCast(parent, MethodBlockBaseSyntax).BlockStatement)
ElseIf TypeOf parent Is PropertyBlockSyntax Then
Return GetParameterNodes(DirectCast(parent, PropertyBlockSyntax).PropertyStatement)
End If
Return SpecializedCollections.EmptyEnumerable(Of ParameterSyntax)()
End Function
Public Overrides Function TryGetImportNode(parentNode As SyntaxNode, dottedName As String, ByRef importNode As SyntaxNode) As Boolean
For Each node In GetImportNodes(parentNode)
If GetImportNamespaceOrType(node) = dottedName Then
importNode = node
Return True
End If
Next
importNode = Nothing
Return False
End Function
Public Overrides Function TryGetOptionNode(parentNode As SyntaxNode, name As String, ordinal As Integer, ByRef optionNode As SyntaxNode) As Boolean
Dim count = -1
For Each [option] As OptionStatementSyntax In GetOptionNodes(parentNode)
If [option].ToString() = name Then
count += 1
If count = ordinal Then
optionNode = [option]
Return True
End If
End If
Next
optionNode = Nothing
Return False
End Function
Public Overrides Function TryGetInheritsNode(parentNode As SyntaxNode, name As String, ordinal As Integer, ByRef inheritsNode As SyntaxNode) As Boolean
Dim count = -1
For Each [inherits] As InheritsStatementSyntax In GetInheritsNodes(parentNode)
If [inherits].Types.ToString() = name Then
count += 1
If count = ordinal Then
inheritsNode = [inherits]
Return True
End If
End If
Next
inheritsNode = Nothing
Return False
End Function
Public Overrides Function TryGetImplementsNode(parentNode As SyntaxNode, name As String, ordinal As Integer, ByRef implementsNode As SyntaxNode) As Boolean
Dim count = -1
For Each [implements] As ImplementsStatementSyntax In GetImplementsNodes(parentNode)
If [implements].Types.ToString() = name Then
count += 1
If count = ordinal Then
implementsNode = [implements]
Return True
End If
End If
Next
implementsNode = Nothing
Return False
End Function
Public Overrides Function TryGetAttributeNode(parentNode As SyntaxNode, name As String, ordinal As Integer, ByRef attributeNode As SyntaxNode) As Boolean
Dim count = -1
For Each attribute As AttributeSyntax In GetAttributeNodes(parentNode)
If attribute.Name.ToString() = name Then
count += 1
If count = ordinal Then
attributeNode = attribute
Return True
End If
End If
Next
attributeNode = Nothing
Return False
End Function
Public Overrides Function TryGetAttributeArgumentNode(attributeNode As SyntaxNode, index As Integer, ByRef attributeArgumentNode As SyntaxNode) As Boolean
Debug.Assert(TypeOf attributeNode Is AttributeSyntax)
Dim attribute = DirectCast(attributeNode, AttributeSyntax)
If attribute.ArgumentList IsNot Nothing AndAlso
attribute.ArgumentList.Arguments.Count > index Then
attributeArgumentNode = attribute.ArgumentList.Arguments(index)
Return True
End If
attributeArgumentNode = Nothing
Return False
End Function
Private Shared Function DeleteMember(document As Document, node As SyntaxNode) As Document
Dim text = document.GetTextSynchronously(CancellationToken.None)
Dim deletionEnd = node.FullSpan.End
Dim deletionStart = node.SpanStart
Dim contiguousEndOfLines = 0
For Each trivia In node.GetLeadingTrivia().Reverse()
If trivia.IsDirective Then
Exit For
End If
If trivia.Kind = SyntaxKind.EndOfLineTrivia Then
If contiguousEndOfLines > 0 Then
Exit For
Else
contiguousEndOfLines += 1
End If
ElseIf trivia.Kind <> SyntaxKind.WhitespaceTrivia Then
contiguousEndOfLines = 0
End If
deletionStart = trivia.FullSpan.Start
Next
text = text.Replace(TextSpan.FromBounds(deletionStart, deletionEnd), String.Empty)
Return document.WithText(text)
End Function
Public Overrides Function Delete(document As Document, node As SyntaxNode) As Document
Select Case node.Kind
Case SyntaxKind.Attribute
Return Delete(document, DirectCast(node, AttributeSyntax))
Case SyntaxKind.SimpleArgument
Return Delete(document, DirectCast(node, ArgumentSyntax))
Case SyntaxKind.Parameter
Return Delete(document, DirectCast(node, ParameterSyntax))
Case SyntaxKind.ModifiedIdentifier
Return Delete(document, DirectCast(node, ModifiedIdentifierSyntax))
Case SyntaxKind.VariableDeclarator
Return Delete(document, DirectCast(node, VariableDeclaratorSyntax))
Case Else
Return DeleteMember(document, node)
End Select
End Function
Private Overloads Function Delete(document As Document, node As ModifiedIdentifierSyntax) As Document
Dim declarator = node.FirstAncestorOrSelf(Of VariableDeclaratorSyntax)()
' If this is the only name in declarator, then delete the entire
' declarator.
If declarator.Names.Count = 1 Then
Return Delete(document, declarator)
Else
Dim newDeclarator = declarator.RemoveNode(node, SyntaxRemoveOptions.KeepEndOfLine).WithAdditionalAnnotations(Formatter.Annotation)
Return document.ReplaceNodeSynchronously(declarator, newDeclarator, CancellationToken.None)
End If
End Function
Private Overloads Function Delete(document As Document, node As VariableDeclaratorSyntax) As Document
Dim declaration = node.FirstAncestorOrSelf(Of FieldDeclarationSyntax)()
' If this is the only declarator in the declaration, then delete
' the entire declarator.
If declaration.Declarators.Count = 1 Then
Return Delete(document, declaration)
Else
Dim newDeclaration = declaration.RemoveNode(node, SyntaxRemoveOptions.KeepEndOfLine).WithAdditionalAnnotations(Formatter.Annotation)
Return document.ReplaceNodeSynchronously(declaration, newDeclaration, CancellationToken.None)
End If
End Function
Private Overloads Shared Function Delete(document As Document, node As AttributeSyntax) As Document
Dim attributeList = node.FirstAncestorOrSelf(Of AttributeListSyntax)()
' If we don't have anything left, then just delete the whole attribute list.
' Keep all leading trivia, but delete all trailing trivia.
If attributeList.Attributes.Count = 1 Then
Dim spanStart = attributeList.SpanStart
Dim spanEnd = attributeList.FullSpan.End
Dim text = document.GetTextSynchronously(CancellationToken.None)
text = text.Replace(TextSpan.FromBounds(spanStart, spanEnd), String.Empty)
Return document.WithText(text)
Else
Dim newAttributeList = attributeList.RemoveNode(node, SyntaxRemoveOptions.KeepEndOfLine)
Return document.ReplaceNodeSynchronously(attributeList, newAttributeList, CancellationToken.None)
End If
End Function
Private Overloads Shared Function Delete(document As Document, node As ArgumentSyntax) As Document
Dim argumentList = node.FirstAncestorOrSelf(Of ArgumentListSyntax)()
Dim newArgumentList = argumentList.RemoveNode(node, SyntaxRemoveOptions.KeepEndOfLine).WithAdditionalAnnotations(Formatter.Annotation)
Return document.ReplaceNodeSynchronously(argumentList, newArgumentList, CancellationToken.None)
End Function
Private Overloads Shared Function Delete(document As Document, node As ParameterSyntax) As Document
Dim parameterList = node.FirstAncestorOrSelf(Of ParameterListSyntax)()
Dim newParameterList = parameterList.RemoveNode(node, SyntaxRemoveOptions.KeepEndOfLine).WithAdditionalAnnotations(Formatter.Annotation)
Return document.ReplaceNodeSynchronously(parameterList, newParameterList, CancellationToken.None)
End Function
Public Overrides Function IsValidExternalSymbol(symbol As ISymbol) As Boolean
Dim methodSymbol = TryCast(symbol, IMethodSymbol)
If methodSymbol IsNot Nothing Then
If methodSymbol.MethodKind = MethodKind.PropertyGet OrElse
methodSymbol.MethodKind = MethodKind.PropertySet OrElse
methodSymbol.MethodKind = MethodKind.EventAdd OrElse
methodSymbol.MethodKind = MethodKind.EventRemove OrElse
methodSymbol.MethodKind = MethodKind.EventRaise Then
Return False
End If
End If
Dim fieldSymbol = TryCast(symbol, IFieldSymbol)
If fieldSymbol IsNot Nothing Then
Dim propertySymbol = TryCast(fieldSymbol.AssociatedSymbol, IPropertySymbol)
If propertySymbol?.IsWithEvents Then
Return True
End If
End If
Return symbol.DeclaredAccessibility = Accessibility.Public OrElse
symbol.DeclaredAccessibility = Accessibility.Protected OrElse
symbol.DeclaredAccessibility = Accessibility.ProtectedOrFriend OrElse
symbol.DeclaredAccessibility = Accessibility.ProtectedAndFriend OrElse
symbol.DeclaredAccessibility = Accessibility.Friend
End Function
Public Overrides Function GetExternalSymbolName(symbol As ISymbol) As String
If symbol Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Return symbol.ToDisplayString(s_externalNameFormat)
End Function
Public Overrides Function GetExternalSymbolFullName(symbol As ISymbol) As String
If symbol Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Return symbol.ToDisplayString(s_externalfullNameFormat)
End Function
Public Overrides Function GetAccess(symbol As ISymbol) As EnvDTE.vsCMAccess
Debug.Assert(symbol IsNot Nothing)
Dim access As EnvDTE.vsCMAccess = 0
Select Case symbol.DeclaredAccessibility
Case Accessibility.Private
access = access Or EnvDTE.vsCMAccess.vsCMAccessPrivate
Case Accessibility.Protected
access = access Or EnvDTE.vsCMAccess.vsCMAccessProtected
Case Accessibility.Internal, Accessibility.Friend
access = access Or EnvDTE.vsCMAccess.vsCMAccessProject
Case Accessibility.ProtectedOrInternal, Accessibility.ProtectedOrFriend
access = access Or EnvDTE.vsCMAccess.vsCMAccessProjectOrProtected
Case Accessibility.ProtectedAndInternal, Accessibility.ProtectedAndFriend
' there is no appropriate mapping for private protected in EnvDTE.vsCMAccess
' See https://github.com/dotnet/roslyn/issues/22406
access = access Or EnvDTE.vsCMAccess.vsCMAccessProject
Case Accessibility.Public
access = access Or EnvDTE.vsCMAccess.vsCMAccessPublic
Case Else
Throw Exceptions.ThrowEFail()
End Select
If TryCast(symbol, IPropertySymbol)?.IsWithEvents Then
access = access Or EnvDTE.vsCMAccess.vsCMAccessWithEvents
End If
Return access
End Function
Public Overrides Function GetAccess(node As SyntaxNode) As EnvDTE.vsCMAccess
Dim member = TryCast(Me.GetNodeWithModifiers(node), StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = member.GetModifierFlags()
Dim access As EnvDTE.vsCMAccess
If (flags And ModifierFlags.Public) <> 0 Then
access = EnvDTE.vsCMAccess.vsCMAccessPublic
ElseIf (flags And ModifierFlags.Protected) <> 0 AndAlso
(flags And ModifierFlags.Friend) <> 0 Then
access = EnvDTE.vsCMAccess.vsCMAccessProjectOrProtected
ElseIf (flags And ModifierFlags.Friend) <> 0 Then
access = EnvDTE.vsCMAccess.vsCMAccessProject
ElseIf (flags And ModifierFlags.Protected) <> 0 Then
access = EnvDTE.vsCMAccess.vsCMAccessProtected
ElseIf (flags And ModifierFlags.Private) <> 0 Then
access = EnvDTE.vsCMAccess.vsCMAccessPrivate
Else
' The code does not specify the accessibility, so we need to
' determine the default accessibility
access = GetDefaultAccessibility(member)
End If
If (flags And ModifierFlags.WithEvents) <> 0 Then
access = access Or EnvDTE.vsCMAccess.vsCMAccessWithEvents
End If
Return access
End Function
Public Overrides Function GetNodeWithModifiers(node As SyntaxNode) As SyntaxNode
Return If(TypeOf node Is ModifiedIdentifierSyntax,
node.GetAncestor(Of DeclarationStatementSyntax)(),
node)
End Function
Public Overrides Function GetNodeWithType(node As SyntaxNode) As SyntaxNode
Return If(TypeOf node Is ModifiedIdentifierSyntax,
node.GetAncestor(Of VariableDeclaratorSyntax)(),
node)
End Function
Public Overrides Function GetNodeWithInitializer(node As SyntaxNode) As SyntaxNode
Return If(TypeOf node Is ModifiedIdentifierSyntax,
node.GetAncestor(Of VariableDeclaratorSyntax)(),
node)
End Function
Public Overrides Function SetAccess(node As SyntaxNode, newAccess As EnvDTE.vsCMAccess) As SyntaxNode
Dim member = TryCast(node, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
If member.Parent.Kind = SyntaxKind.InterfaceBlock OrElse
member.Parent.Kind = SyntaxKind.EnumBlock Then
If newAccess = EnvDTE.vsCMAccess.vsCMAccessDefault OrElse
newAccess = EnvDTE.vsCMAccess.vsCMAccessPublic Then
Return node
Else
Throw Exceptions.ThrowEInvalidArg()
End If
End If
If TypeOf member Is TypeBlockSyntax OrElse
TypeOf member Is EnumBlockSyntax Then
If Not TypeOf member.Parent Is TypeBlockSyntax AndAlso
(newAccess = EnvDTE.vsCMAccess.vsCMAccessPrivate OrElse
newAccess = EnvDTE.vsCMAccess.vsCMAccessProtected OrElse
newAccess = EnvDTE.vsCMAccess.vsCMAccessProjectOrProtected) Then
Throw Exceptions.ThrowEInvalidArg()
End If
End If
Dim flags = member.GetModifierFlags() And Not (ModifierFlags.AccessModifierMask Or ModifierFlags.Dim Or ModifierFlags.WithEvents)
If (newAccess And EnvDTE.vsCMAccess.vsCMAccessPrivate) <> 0 Then
flags = flags Or ModifierFlags.Private
ElseIf (newAccess And EnvDTE.vsCMAccess.vsCMAccessProtected) <> 0 Then
flags = flags Or ModifierFlags.Protected
If (newAccess And EnvDTE.vsCMAccess.vsCMAccessProject) <> 0 Then
flags = flags Or ModifierFlags.Friend
End If
ElseIf (newAccess And EnvDTE.vsCMAccess.vsCMAccessPublic) <> 0 Then
flags = flags Or ModifierFlags.Public
ElseIf (newAccess And EnvDTE.vsCMAccess.vsCMAccessProject) <> 0 Then
flags = flags Or ModifierFlags.Friend
ElseIf (newAccess And EnvDTE.vsCMAccess.vsCMAccessProjectOrProtected) <> 0 Then
flags = flags Or ModifierFlags.Protected Or ModifierFlags.Friend
ElseIf (newAccess And EnvDTE.vsCMAccess.vsCMAccessDefault) <> 0 Then
' No change
End If
If (newAccess And EnvDTE.vsCMAccess.vsCMAccessWithEvents) <> 0 Then
flags = flags Or ModifierFlags.WithEvents
End If
If flags = 0 AndAlso member.IsKind(SyntaxKind.FieldDeclaration) Then
flags = flags Or ModifierFlags.Dim
End If
Return member.UpdateModifiers(flags)
End Function
Private Overloads Shared Function GetDefaultAccessibility(node As SyntaxNode) As EnvDTE.vsCMAccess
If node.HasAncestor(Of StructureBlockSyntax)() Then
Return EnvDTE.vsCMAccess.vsCMAccessPublic
End If
If TypeOf node Is FieldDeclarationSyntax Then
Return EnvDTE.vsCMAccess.vsCMAccessPrivate
ElseIf (TypeOf node Is MethodBlockBaseSyntax OrElse
TypeOf node Is TypeBlockSyntax OrElse
TypeOf node Is EnumBlockSyntax OrElse
TypeOf node Is MethodBaseSyntax OrElse
TypeOf node Is EnumMemberDeclarationSyntax) Then
Return EnvDTE.vsCMAccess.vsCMAccessPublic
End If
Throw Exceptions.ThrowEFail()
End Function
Protected Overrides Function GetAttributeIndexInContainer(containerNode As SyntaxNode, predicate As Func(Of SyntaxNode, Boolean)) As Integer
Dim attributes = GetAttributeNodes(containerNode).ToArray()
Dim index = 0
While index < attributes.Length
Dim attribute = DirectCast(attributes(index), AttributeSyntax)
If predicate(attribute) Then
Dim attributeBlock = DirectCast(attribute.Parent, AttributeListSyntax)
' If this attribute is part of a block with multiple attributes,
' make sure to return the index of the last attribute in the block.
If attributeBlock.Attributes.Count > 1 Then
Dim indexOfAttributeInBlock = attributeBlock.Attributes.IndexOf(attribute)
Return index + (attributeBlock.Attributes.Count - indexOfAttributeInBlock)
End If
Return index + 1
End If
index += 1
End While
Return -1
End Function
Protected Overrides Function GetAttributeArgumentIndexInContainer(containerNode As SyntaxNode, predicate As Func(Of SyntaxNode, Boolean)) As Integer
Dim attributeArguments = GetAttributeArgumentNodes(containerNode).ToArray()
Dim index = 0
While index < attributeArguments.Length
If predicate(attributeArguments(index)) Then
Return index + 1
End If
index += 1
End While
Return -1
End Function
Protected Overrides Function GetImportIndexInContainer(containerNode As SyntaxNode, predicate As Func(Of SyntaxNode, Boolean)) As Integer
Dim importsClauses = GetImportNodes(containerNode).ToArray()
Dim index = 0
While index < importsClauses.Length
Dim importsClause = DirectCast(importsClauses(index), ImportsClauseSyntax)
If predicate(importsClause) Then
Dim importsStatement = DirectCast(importsClause.Parent, ImportsStatementSyntax)
' If this attribute is part of a block with multiple attributes,
' make sure to return the index of the last attribute in the block.
If importsStatement.ImportsClauses.Count > 1 Then
Dim indexOfImportClauseInStatement = importsStatement.ImportsClauses.IndexOf(importsClause)
Return index + (importsStatement.ImportsClauses.Count - indexOfImportClauseInStatement)
End If
Return index + 1
End If
index += 1
End While
Return -1
End Function
Protected Overrides Function GetParameterIndexInContainer(containerNode As SyntaxNode, predicate As Func(Of SyntaxNode, Boolean)) As Integer
Dim parameters = GetParameterNodes(containerNode).ToArray()
For index = 0 To parameters.Length - 1
If predicate(parameters(index)) Then
Return index + 1
End If
Next
Return -1
End Function
Protected Overrides Function GetMemberIndexInContainer(containerNode As SyntaxNode, predicate As Func(Of SyntaxNode, Boolean)) As Integer
Dim members = GetLogicalMemberNodes(containerNode).ToArray()
Dim index = 0
While index < members.Length
Dim member = members(index)
If predicate(member) Then
' Special case: if a modified identifier was specified, make sure we return the index
' of the last modified identifier of the last variable declarator in the parenting field
' declaration.
If member.Kind = SyntaxKind.ModifiedIdentifier Then
Dim modifiedIdentifier = DirectCast(member, ModifiedIdentifierSyntax)
Dim variableDeclarator = DirectCast(member.Parent, VariableDeclaratorSyntax)
Dim fieldDeclaration = DirectCast(variableDeclarator.Parent, FieldDeclarationSyntax)
Dim indexOfNameInDeclarator = variableDeclarator.Names.IndexOf(modifiedIdentifier)
Dim indexOfDeclaratorInField = fieldDeclaration.Declarators.IndexOf(variableDeclarator)
Dim indexOfNameInField = indexOfNameInDeclarator
If indexOfDeclaratorInField > 0 Then
For i = 0 To indexOfDeclaratorInField - 1
indexOfNameInField += fieldDeclaration.Declarators(i).Names.Count
Next
End If
Dim namesInFieldCount = fieldDeclaration.Declarators.SelectMany(Function(v) v.Names).Count()
Return index + (namesInFieldCount - indexOfNameInField)
End If
Return index + 1
End If
index += 1
End While
Return -1
End Function
Public Overrides Sub GetOptionNameAndOrdinal(parentNode As SyntaxNode, optionNode As SyntaxNode, ByRef name As String, ByRef ordinal As Integer)
Debug.Assert(TypeOf optionNode Is OptionStatementSyntax)
name = GetNormalizedName(DirectCast(optionNode, OptionStatementSyntax))
ordinal = -1
For Each [option] As OptionStatementSyntax In GetOptionNodes(parentNode)
If GetNormalizedName([option]) = name Then
ordinal += 1
End If
If [option].Equals(optionNode) Then
Exit For
End If
Next
End Sub
Public Overrides Sub GetInheritsNamespaceAndOrdinal(parentNode As SyntaxNode, inheritsNode As SyntaxNode, ByRef namespaceName As String, ByRef ordinal As Integer)
Debug.Assert(TypeOf inheritsNode Is InheritsStatementSyntax)
namespaceName = DirectCast(inheritsNode, InheritsStatementSyntax).Types.ToString()
ordinal = -1
For Each [inherits] As InheritsStatementSyntax In GetInheritsNodes(parentNode)
If [inherits].Types.ToString() = namespaceName Then
ordinal += 1
End If
If [inherits].Equals(inheritsNode) Then
Exit For
End If
Next
End Sub
Public Overrides Sub GetImplementsNamespaceAndOrdinal(parentNode As SyntaxNode, implementsNode As SyntaxNode, ByRef namespaceName As String, ByRef ordinal As Integer)
Debug.Assert(TypeOf implementsNode Is ImplementsStatementSyntax)
namespaceName = DirectCast(implementsNode, ImplementsStatementSyntax).Types.ToString()
ordinal = -1
For Each [implements] As ImplementsStatementSyntax In GetImplementsNodes(parentNode)
If [implements].Types.ToString() = namespaceName Then
ordinal += 1
End If
If [implements].Equals(implementsNode) Then
Exit For
End If
Next
End Sub
Public Overrides Sub GetAttributeNameAndOrdinal(parentNode As SyntaxNode, attributeNode As SyntaxNode, ByRef name As String, ByRef ordinal As Integer)
Debug.Assert(TypeOf attributeNode Is AttributeSyntax)
name = DirectCast(attributeNode, AttributeSyntax).Name.ToString()
ordinal = -1
For Each attribute As AttributeSyntax In GetAttributeNodes(parentNode)
If attribute.Name.ToString() = name Then
ordinal += 1
End If
If attribute.Equals(attributeNode) Then
Exit For
End If
Next
End Sub
Public Overrides Function GetAttributeTargetNode(attributeNode As SyntaxNode) As SyntaxNode
If TypeOf attributeNode Is AttributeSyntax Then
Return attributeNode
End If
Throw Exceptions.ThrowEUnexpected()
End Function
Public Overrides Function GetAttributeTarget(attributeNode As SyntaxNode) As String
Debug.Assert(TypeOf attributeNode Is AttributeSyntax)
Dim attribute = DirectCast(attributeNode, AttributeSyntax)
Return If(attribute.Target IsNot Nothing,
attribute.Target.AttributeModifier.ToString(),
String.Empty)
End Function
Public Overrides Function SetAttributeTarget(attributeNode As SyntaxNode, value As String) As SyntaxNode
Debug.Assert(TypeOf attributeNode Is AttributeSyntax)
Dim attribute = DirectCast(attributeNode, AttributeSyntax)
Dim target = attribute.Target
If Not String.IsNullOrEmpty(value) Then
' VB only supports Assembly and Module as attribute modifiers.
Dim newModifier As SyntaxToken
If String.Equals(value, "Assembly", StringComparison.OrdinalIgnoreCase) Then
newModifier = SyntaxFactory.Token(SyntaxKind.AssemblyKeyword)
ElseIf String.Equals(value, "Module", StringComparison.OrdinalIgnoreCase) Then
newModifier = SyntaxFactory.Token(SyntaxKind.ModuleKeyword)
Else
Throw Exceptions.ThrowEInvalidArg()
End If
Dim newTarget = If(target IsNot Nothing,
target.WithAttributeModifier(newModifier),
SyntaxFactory.AttributeTarget(newModifier))
Return attribute.WithTarget(newTarget)
Else
Return attribute.WithTarget(Nothing)
End If
End Function
Public Overrides Function GetAttributeValue(attributeNode As SyntaxNode) As String
Debug.Assert(TypeOf attributeNode Is AttributeSyntax)
Dim attribute = DirectCast(attributeNode, AttributeSyntax)
Dim argumentList = attribute.ArgumentList
If argumentList IsNot Nothing Then
Return argumentList.Arguments.ToString()
End If
Return String.Empty
End Function
Public Overrides Function SetAttributeValue(attributeNode As SyntaxNode, value As String) As SyntaxNode
Debug.Assert(TypeOf attributeNode Is AttributeSyntax)
Dim attribute = DirectCast(attributeNode, AttributeSyntax)
Dim argumentList = attribute.ArgumentList
Dim parsedArgumentList = SyntaxFactory.ParseArgumentList("(" & value & ")")
Dim newArgumentList = If(argumentList IsNot Nothing,
argumentList.WithArguments(parsedArgumentList.Arguments),
parsedArgumentList)
Return attribute.WithArgumentList(newArgumentList)
End Function
Public Overrides Function GetNodeWithAttributes(node As SyntaxNode) As SyntaxNode
Return If(TypeOf node Is ModifiedIdentifierSyntax,
node.GetAncestor(Of FieldDeclarationSyntax),
node)
End Function
Public Overrides Function GetEffectiveParentForAttribute(node As SyntaxNode) As SyntaxNode
If node.HasAncestor(Of FieldDeclarationSyntax)() Then
Return node.GetAncestor(Of FieldDeclarationSyntax).Declarators.First().Names.First()
ElseIf node.HasAncestor(Of ParameterSyntax)() Then
Return node.GetAncestor(Of ParameterSyntax)()
Else
Return node.Parent
End If
End Function
Public Overrides Sub GetAttributeArgumentParentAndIndex(attributeArgumentNode As SyntaxNode, ByRef attributeNode As SyntaxNode, ByRef index As Integer)
Debug.Assert(TypeOf attributeArgumentNode Is ArgumentSyntax)
Dim argument = DirectCast(attributeArgumentNode, ArgumentSyntax)
Dim attribute = DirectCast(argument.Ancestors.FirstOrDefault(Function(n) n.Kind = SyntaxKind.Attribute), AttributeSyntax)
attributeNode = attribute
index = attribute.ArgumentList.Arguments.IndexOf(DirectCast(attributeArgumentNode, ArgumentSyntax))
End Sub
Public Overrides Function CreateAttributeNode(name As String, value As String, Optional target As String = Nothing) As SyntaxNode
Dim specifier As AttributeTargetSyntax = Nothing
If target IsNot Nothing Then
Dim contextualKeywordKind = SyntaxFacts.GetContextualKeywordKind(target)
If contextualKeywordKind = SyntaxKind.AssemblyKeyword OrElse
contextualKeywordKind = SyntaxKind.ModuleKeyword Then
specifier = SyntaxFactory.AttributeTarget(SyntaxFactory.Token(contextualKeywordKind, text:=target))
Else
specifier = SyntaxFactory.AttributeTarget(SyntaxFactory.ParseToken(target))
End If
End If
Return SyntaxFactory.AttributeList(
SyntaxFactory.SingletonSeparatedList(
SyntaxFactory.Attribute(
target:=specifier,
name:=SyntaxFactory.ParseName(name),
argumentList:=SyntaxFactory.ParseArgumentList("(" & value & ")"))))
End Function
Public Overrides Function CreateAttributeArgumentNode(name As String, value As String) As SyntaxNode
If Not String.IsNullOrEmpty(name) Then
Return SyntaxFactory.SimpleArgument(
SyntaxFactory.NameColonEquals(SyntaxFactory.IdentifierName(name)),
SyntaxFactory.ParseExpression(value))
Else
Return SyntaxFactory.SimpleArgument(SyntaxFactory.ParseExpression(value))
End If
End Function
Public Overrides Function CreateImportNode(name As String, Optional [alias] As String = Nothing) As SyntaxNode
Dim nameSyntax = SyntaxFactory.ParseName(name)
Dim importsClause As ImportsClauseSyntax
If Not String.IsNullOrEmpty([alias]) Then
importsClause = SyntaxFactory.SimpleImportsClause(SyntaxFactory.ImportAliasClause([alias]), nameSyntax)
Else
importsClause = SyntaxFactory.SimpleImportsClause(nameSyntax)
End If
Return SyntaxFactory.ImportsStatement(SyntaxFactory.SingletonSeparatedList(importsClause))
End Function
Public Overrides Function CreateParameterNode(name As String, type As String) As SyntaxNode
Return SyntaxFactory.Parameter(SyntaxFactory.ModifiedIdentifier(name)).WithAsClause(SyntaxFactory.SimpleAsClause(SyntaxFactory.ParseTypeName(type)))
End Function
Public Overrides Function GetAttributeArgumentValue(attributeArgumentNode As SyntaxNode) As String
Select Case attributeArgumentNode.Kind
Case SyntaxKind.SimpleArgument
Return DirectCast(attributeArgumentNode, SimpleArgumentSyntax).Expression.ToString()
End Select
Throw New InvalidOperationException()
End Function
Public Overrides Function GetImportAlias(node As SyntaxNode) As String
Select Case node.Kind
Case SyntaxKind.SimpleImportsClause
Dim simpleImportsClause = DirectCast(node, SimpleImportsClauseSyntax)
Return If(simpleImportsClause.Alias IsNot Nothing,
simpleImportsClause.Alias.Identifier.ToString(),
String.Empty)
Case Else
Throw New InvalidOperationException()
End Select
End Function
Public Overrides Function GetImportNamespaceOrType(node As SyntaxNode) As String
Select Case node.Kind
Case SyntaxKind.SimpleImportsClause
Return GetNormalizedName(DirectCast(node, SimpleImportsClauseSyntax).Name)
Case Else
Throw New InvalidOperationException()
End Select
End Function
Public Overrides Sub GetImportParentAndName(node As SyntaxNode, ByRef parentNode As SyntaxNode, ByRef name As String)
parentNode = Nothing
Select Case node.Kind
Case SyntaxKind.SimpleImportsClause
name = GetNormalizedName(DirectCast(node, SimpleImportsClauseSyntax).Name)
Case Else
Throw New InvalidOperationException()
End Select
End Sub
Public Overrides Function GetParameterName(node As SyntaxNode) As String
Dim parameter = TryCast(node, ParameterSyntax)
If parameter IsNot Nothing Then
Return GetNameFromParameter(parameter)
End If
Throw New InvalidOperationException()
End Function
Private Function GetNameFromParameter(parameter As ParameterSyntax) As String
Dim parameterName As String = parameter.Identifier.Identifier.ToString()
Return If(Not String.IsNullOrEmpty(parameterName) AndAlso SyntaxFactsService.IsTypeCharacter(parameterName.Last()),
parameterName.Substring(0, parameterName.Length - 1),
parameterName)
End Function
Public Overrides Function GetParameterFullName(node As SyntaxNode) As String
Dim parameter = TryCast(node, ParameterSyntax)
If parameter IsNot Nothing Then
Return parameter.Identifier.ToString()
End If
Throw New InvalidOperationException()
End Function
Public Overrides Function GetParameterKind(node As SyntaxNode) As EnvDTE80.vsCMParameterKind
Dim parameter = TryCast(node, ParameterSyntax)
If parameter IsNot Nothing Then
Dim kind = EnvDTE80.vsCMParameterKind.vsCMParameterKindNone
Dim modifiers = parameter.Modifiers
If modifiers.Any(SyntaxKind.OptionalKeyword) Then
kind = kind Or EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional
End If
If modifiers.Any(SyntaxKind.ParamArrayKeyword) Then
kind = kind Or EnvDTE80.vsCMParameterKind.vsCMParameterKindParamArray
End If
If modifiers.Any(SyntaxKind.ByRefKeyword) Then
kind = kind Or EnvDTE80.vsCMParameterKind.vsCMParameterKindRef
Else
kind = kind Or EnvDTE80.vsCMParameterKind.vsCMParameterKindIn
End If
Return kind
End If
Throw New InvalidOperationException()
End Function
Public Overrides Function SetParameterKind(node As SyntaxNode, kind As EnvDTE80.vsCMParameterKind) As SyntaxNode
Dim parameter = TryCast(node, ParameterSyntax)
If parameter Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
If Not IsValidParameterKind(kind) Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim newModifierList = New List(Of SyntaxToken)
' TODO (tomescht): The Dev11 code allowed different sets of modifiers to be
' set when in batch mode vs non-batch mode.
If (kind And EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional) <> 0 Then
newModifierList.Add(SyntaxFactory.Token(SyntaxKind.OptionalKeyword))
End If
If (kind And EnvDTE80.vsCMParameterKind.vsCMParameterKindIn) <> 0 AndAlso parameter.Modifiers.Any(SyntaxKind.ByValKeyword) Then
' Ensure that we keep ByVal if it was already present.
newModifierList.Add(SyntaxFactory.Token(SyntaxKind.ByValKeyword))
ElseIf (kind And EnvDTE80.vsCMParameterKind.vsCMParameterKindRef) <> 0 Then
newModifierList.Add(SyntaxFactory.Token(SyntaxKind.ByRefKeyword))
End If
If (kind And EnvDTE80.vsCMParameterKind.vsCMParameterKindParamArray) <> 0 Then
newModifierList.Add(SyntaxFactory.Token(SyntaxKind.ParamArrayKeyword))
End If
Return parameter.WithModifiers(SyntaxFactory.TokenList(newModifierList))
End Function
Private Shared Function IsValidParameterKind(kind As EnvDTE80.vsCMParameterKind) As Boolean
Select Case kind
Case EnvDTE80.vsCMParameterKind.vsCMParameterKindNone,
EnvDTE80.vsCMParameterKind.vsCMParameterKindIn,
EnvDTE80.vsCMParameterKind.vsCMParameterKindRef,
EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional,
EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional Or EnvDTE80.vsCMParameterKind.vsCMParameterKindIn,
EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional Or EnvDTE80.vsCMParameterKind.vsCMParameterKindRef,
EnvDTE80.vsCMParameterKind.vsCMParameterKindParamArray,
EnvDTE80.vsCMParameterKind.vsCMParameterKindParamArray Or EnvDTE80.vsCMParameterKind.vsCMParameterKindIn
Return True
End Select
Return False
End Function
Public Overrides Function UpdateParameterKind(parameterKind As EnvDTE80.vsCMParameterKind, passingMode As PARAMETER_PASSING_MODE) As EnvDTE80.vsCMParameterKind
Dim updatedParameterKind = parameterKind
Select Case passingMode
Case PARAMETER_PASSING_MODE.cmParameterTypeIn
updatedParameterKind = updatedParameterKind Or EnvDTE80.vsCMParameterKind.vsCMParameterKindIn
updatedParameterKind = updatedParameterKind And Not EnvDTE80.vsCMParameterKind.vsCMParameterKindRef
updatedParameterKind = updatedParameterKind And Not EnvDTE80.vsCMParameterKind.vsCMParameterKindOut
Case PARAMETER_PASSING_MODE.cmParameterTypeInOut
updatedParameterKind = updatedParameterKind And Not EnvDTE80.vsCMParameterKind.vsCMParameterKindIn
updatedParameterKind = updatedParameterKind Or EnvDTE80.vsCMParameterKind.vsCMParameterKindRef
updatedParameterKind = updatedParameterKind And Not EnvDTE80.vsCMParameterKind.vsCMParameterKindOut
Case PARAMETER_PASSING_MODE.cmParameterTypeOut
Throw Exceptions.ThrowEInvalidArg()
End Select
Return updatedParameterKind
End Function
Public Overrides Function ValidateFunctionKind(containerNode As SyntaxNode, kind As EnvDTE.vsCMFunction, name As String) As EnvDTE.vsCMFunction
If kind = EnvDTE.vsCMFunction.vsCMFunctionSub Then
Return If(name = "New" AndAlso Not TypeOf containerNode Is InterfaceBlockSyntax,
EnvDTE.vsCMFunction.vsCMFunctionConstructor,
kind)
End If
If kind = EnvDTE.vsCMFunction.vsCMFunctionFunction Then
Return kind
End If
Throw Exceptions.ThrowEInvalidArg()
End Function
Public Overrides ReadOnly Property SupportsEventThrower As Boolean
Get
Return True
End Get
End Property
Public Overrides Function GetCanOverride(memberNode As SyntaxNode) As Boolean
Debug.Assert(TypeOf memberNode Is StatementSyntax)
Dim member = TryCast(memberNode, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
If member.Parent.Kind = SyntaxKind.InterfaceBlock Then
Return True
End If
Dim flags = member.GetModifierFlags()
If (flags And ModifierFlags.NotOverridable) <> 0 Then
Return False
End If
If (flags And ModifierFlags.MustOverride) <> 0 Then
Return True
End If
If (flags And ModifierFlags.Overridable) <> 0 Then
Return True
End If
If (flags And ModifierFlags.Overrides) <> 0 Then
Return True
End If
Return False
End Function
Public Overrides Function SetCanOverride(memberNode As SyntaxNode, value As Boolean) As SyntaxNode
Dim overrideKind = If(value, EnvDTE80.vsCMOverrideKind.vsCMOverrideKindVirtual, EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNone)
Return SetOverrideKind(memberNode, overrideKind)
End Function
Public Overrides Function GetClassKind(typeNode As SyntaxNode, typeSymbol As INamedTypeSymbol) As EnvDTE80.vsCMClassKind
Debug.Assert(TypeOf typeNode Is ClassBlockSyntax OrElse
TypeOf typeNode Is ModuleBlockSyntax)
Dim typeBlock = DirectCast(typeNode, TypeBlockSyntax)
If TypeOf typeBlock Is ModuleBlockSyntax Then
Return EnvDTE80.vsCMClassKind.vsCMClassKindModule
End If
Dim flags = typeBlock.GetModifierFlags()
If (flags And ModifierFlags.Partial) <> 0 Then
Return EnvDTE80.vsCMClassKind.vsCMClassKindPartialClass
End If
If typeSymbol.DeclaringSyntaxReferences.Length > 1 Then
Return EnvDTE80.vsCMClassKind.vsCMClassKindPartialClass
End If
Return EnvDTE80.vsCMClassKind.vsCMClassKindMainClass
End Function
Private Shared Function IsValidClassKind(kind As EnvDTE80.vsCMClassKind) As Boolean
Return kind = EnvDTE80.vsCMClassKind.vsCMClassKindMainClass OrElse
kind = EnvDTE80.vsCMClassKind.vsCMClassKindPartialClass
End Function
Public Overrides Function SetClassKind(typeNode As SyntaxNode, kind As EnvDTE80.vsCMClassKind) As SyntaxNode
Debug.Assert(TypeOf typeNode Is ClassBlockSyntax OrElse
TypeOf typeNode Is ModuleBlockSyntax)
Dim typeBlock = DirectCast(typeNode, StatementSyntax)
If TypeOf typeBlock Is ModuleBlockSyntax Then
If kind = EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNone Then
Return typeBlock
End If
Throw Exceptions.ThrowENotImpl()
End If
If Not IsValidClassKind(kind) Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim flags = typeBlock.GetModifierFlags()
flags = flags And Not ModifierFlags.Partial
If kind = EnvDTE80.vsCMClassKind.vsCMClassKindPartialClass Then
flags = flags Or ModifierFlags.Partial
End If
Return typeBlock.UpdateModifiers(flags)
End Function
Private Shared Function CollectComments(triviaList As IList(Of SyntaxTrivia)) As IList(Of SyntaxTrivia)
Dim commentList = New List(Of SyntaxTrivia)
Dim firstCommentFound = False
For i = triviaList.Count - 1 To 0 Step -1
Dim trivia = triviaList(i)
Dim nextTrivia = If(i > 0, triviaList(i - 1), Nothing)
If trivia.Kind = SyntaxKind.CommentTrivia Then
firstCommentFound = True
commentList.Add(trivia)
ElseIf Not firstCommentFound AndAlso trivia.IsWhitespaceOrEndOfLine() Then
Continue For
ElseIf firstCommentFound AndAlso trivia.Kind = SyntaxKind.EndOfLineTrivia AndAlso nextTrivia.Kind = SyntaxKind.CommentTrivia Then
Continue For
Else
Exit For
End If
Next
commentList.Reverse()
Return commentList
End Function
Public Overrides Function GetComment(node As SyntaxNode) As String
Debug.Assert(TypeOf node Is StatementSyntax)
Dim member = DirectCast(node, StatementSyntax)
Dim firstToken = member.GetFirstToken()
Dim triviaList = firstToken.LeadingTrivia
Dim commentList = CollectComments(firstToken.LeadingTrivia.ToArray())
If commentList.Count = 0 Then
Return String.Empty
End If
Dim textBuilder = New StringBuilder()
For Each trivia In commentList
Debug.Assert(trivia.ToString().StartsWith("'", StringComparison.Ordinal))
Dim commentText = trivia.ToString().Substring(1)
textBuilder.AppendLine(commentText)
Next
Return textBuilder.ToString().TrimEnd()
End Function
Public Overrides Function SetComment(node As SyntaxNode, value As String) As SyntaxNode
Debug.Assert(TypeOf node Is StatementSyntax)
Dim member = DirectCast(node, StatementSyntax)
Dim text = member.SyntaxTree.GetText(CancellationToken.None)
Dim newLine = GetNewLineCharacter(text)
Dim commentText = String.Empty
If value IsNot Nothing Then
Dim builder = New StringBuilder()
For Each line In value.Split({vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
builder.Append("' ")
builder.Append(line)
builder.Append(newLine)
Next
commentText = builder.ToString()
End If
Dim newTriviaList = SyntaxFactory.ParseLeadingTrivia(commentText)
Dim leadingTriviaList = member.GetLeadingTrivia().ToList()
Dim commentList = CollectComments(leadingTriviaList)
If commentList.Count > 0 Then
' In this case, we're going to replace the existing comment.
Dim firstIndex = leadingTriviaList.FindIndex(Function(t) t = commentList(0))
Dim lastIndex = leadingTriviaList.FindIndex(Function(t) t = commentList(commentList.Count - 1))
Dim count = lastIndex - firstIndex + 1
leadingTriviaList.RemoveRange(firstIndex, count)
' Note: single line comments have a trailing new-line but that won't be
' returned by CollectComments. So, we may need to remove an additional new line below.
If firstIndex < leadingTriviaList.Count AndAlso
leadingTriviaList(firstIndex).Kind = SyntaxKind.EndOfLineTrivia Then
leadingTriviaList.RemoveAt(firstIndex)
End If
For Each triviaElement In newTriviaList.Reverse()
leadingTriviaList.Insert(firstIndex, triviaElement)
Next
Else
' Otherwise, just add the comment to the end of the leading trivia.
leadingTriviaList.AddRange(newTriviaList)
End If
Return member.WithLeadingTrivia(leadingTriviaList)
End Function
Public Overrides Function GetConstKind(variableNode As SyntaxNode) As EnvDTE80.vsCMConstKind
If TypeOf variableNode Is EnumMemberDeclarationSyntax Then
Return EnvDTE80.vsCMConstKind.vsCMConstKindConst
End If
Dim member = TryCast(GetNodeWithModifiers(variableNode), StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = member.GetModifierFlags()
If (flags And ModifierFlags.Const) <> 0 Then
Return EnvDTE80.vsCMConstKind.vsCMConstKindConst
End If
If (flags And ModifierFlags.ReadOnly) <> 0 Then
Return EnvDTE80.vsCMConstKind.vsCMConstKindReadOnly
End If
Return EnvDTE80.vsCMConstKind.vsCMConstKindNone
End Function
Private Shared Function IsValidConstKind(kind As EnvDTE80.vsCMConstKind) As Boolean
Return kind = EnvDTE80.vsCMConstKind.vsCMConstKindConst OrElse
kind = EnvDTE80.vsCMConstKind.vsCMConstKindReadOnly OrElse
kind = EnvDTE80.vsCMConstKind.vsCMConstKindNone
End Function
Public Overrides Function SetConstKind(variableNode As SyntaxNode, kind As EnvDTE80.vsCMConstKind) As SyntaxNode
If TypeOf variableNode Is EnumMemberDeclarationSyntax Then
Throw Exceptions.ThrowENotImpl()
End If
If Not IsValidConstKind(kind) Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim member = TryCast(GetNodeWithModifiers(variableNode), StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = member.GetModifierFlags()
flags = flags And Not (ModifierFlags.Const Or ModifierFlags.ReadOnly Or ModifierFlags.Dim)
If kind = EnvDTE80.vsCMConstKind.vsCMConstKindConst Then
flags = flags Or ModifierFlags.Const
ElseIf kind = EnvDTE80.vsCMConstKind.vsCMConstKindReadOnly Then
flags = flags Or ModifierFlags.ReadOnly
End If
If flags = 0 Then
flags = flags Or ModifierFlags.Dim
End If
Return member.UpdateModifiers(flags)
End Function
Public Overrides Function GetDataTypeKind(typeNode As SyntaxNode, symbol As INamedTypeSymbol) As EnvDTE80.vsCMDataTypeKind
Debug.Assert(TypeOf typeNode Is ClassBlockSyntax OrElse
TypeOf typeNode Is InterfaceBlockSyntax OrElse
TypeOf typeNode Is ModuleBlockSyntax OrElse
TypeOf typeNode Is StructureBlockSyntax)
Dim typeBlock = DirectCast(typeNode, TypeBlockSyntax)
If TypeOf typeBlock Is ModuleBlockSyntax Then
Return EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindModule
End If
Dim flags = typeBlock.GetModifierFlags()
If (flags And ModifierFlags.Partial) <> 0 Then
Return EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindPartial
End If
If symbol.DeclaringSyntaxReferences.Length > 1 Then
Return EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindPartial
End If
Return EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindMain
End Function
Private Shared Function IsValidDataTypeKind(kind As EnvDTE80.vsCMDataTypeKind, allowModule As Boolean) As Boolean
Return kind = EnvDTE80.vsCMClassKind.vsCMClassKindMainClass OrElse
kind = EnvDTE80.vsCMClassKind.vsCMClassKindPartialClass OrElse
(allowModule AndAlso kind = EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindModule)
End Function
Public Overrides Function SetDataTypeKind(typeNode As SyntaxNode, kind As EnvDTE80.vsCMDataTypeKind) As SyntaxNode
Debug.Assert(TypeOf typeNode Is ClassBlockSyntax OrElse
TypeOf typeNode Is InterfaceBlockSyntax OrElse
TypeOf typeNode Is ModuleBlockSyntax OrElse
TypeOf typeNode Is StructureBlockSyntax)
Dim typeBlock = DirectCast(typeNode, TypeBlockSyntax)
If TypeOf typeBlock Is InterfaceBlockSyntax Then
Throw Exceptions.ThrowENotImpl()
End If
Dim allowModule = TypeOf typeBlock Is ClassBlockSyntax OrElse
TypeOf typeBlock Is ModuleBlockSyntax
If Not IsValidDataTypeKind(kind, allowModule) Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = typeBlock.GetModifierFlags()
flags = flags And Not ModifierFlags.Partial
If kind = EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindPartial Then
flags = flags Or ModifierFlags.Partial
End If
' VB supports changing a Module to a Class and vice versa.
If TypeOf typeBlock Is ModuleBlockSyntax Then
If kind = EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindMain OrElse
kind = EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindPartial Then
Dim moduleBlock = DirectCast(typeBlock, ModuleBlockSyntax)
typeBlock = SyntaxFactory.ClassBlock(
classStatement:=SyntaxFactory.ClassStatement(
attributeLists:=moduleBlock.ModuleStatement.AttributeLists,
modifiers:=moduleBlock.ModuleStatement.Modifiers,
classKeyword:=SyntaxFactory.Token(moduleBlock.ModuleStatement.ModuleKeyword.LeadingTrivia, SyntaxKind.ClassKeyword, moduleBlock.ModuleStatement.ModuleKeyword.TrailingTrivia),
identifier:=moduleBlock.ModuleStatement.Identifier,
typeParameterList:=moduleBlock.ModuleStatement.TypeParameterList),
[inherits]:=moduleBlock.Inherits,
[implements]:=moduleBlock.Implements,
members:=moduleBlock.Members,
endClassStatement:=SyntaxFactory.EndClassStatement(
endKeyword:=moduleBlock.EndModuleStatement.EndKeyword,
blockKeyword:=SyntaxFactory.Token(moduleBlock.EndModuleStatement.BlockKeyword.LeadingTrivia, SyntaxKind.ClassKeyword, moduleBlock.EndModuleStatement.BlockKeyword.TrailingTrivia)))
End If
ElseIf TypeOf typeBlock Is ClassBlockSyntax Then
If kind = EnvDTE80.vsCMDataTypeKind.vsCMDataTypeKindModule Then
flags = flags And Not ModifierFlags.Shared
Dim classBlock = DirectCast(typeBlock, ClassBlockSyntax)
typeBlock = SyntaxFactory.ModuleBlock(
moduleStatement:=SyntaxFactory.ModuleStatement(
attributeLists:=classBlock.ClassStatement.AttributeLists,
modifiers:=classBlock.ClassStatement.Modifiers,
moduleKeyword:=SyntaxFactory.Token(classBlock.ClassStatement.ClassKeyword.LeadingTrivia, SyntaxKind.ModuleKeyword, classBlock.ClassStatement.ClassKeyword.TrailingTrivia),
identifier:=classBlock.ClassStatement.Identifier,
typeParameterList:=classBlock.ClassStatement.TypeParameterList),
[inherits]:=Nothing,
[implements]:=Nothing,
members:=classBlock.Members,
endModuleStatement:=SyntaxFactory.EndModuleStatement(
endKeyword:=classBlock.EndClassStatement.EndKeyword,
blockKeyword:=SyntaxFactory.Token(classBlock.EndClassStatement.BlockKeyword.LeadingTrivia, SyntaxKind.ModuleKeyword, classBlock.EndClassStatement.BlockKeyword.TrailingTrivia)))
End If
End If
Return typeBlock.UpdateModifiers(flags)
End Function
Private Shared Function GetDocCommentNode(memberDeclaration As StatementSyntax) As DocumentationCommentTriviaSyntax
Dim docCommentTrivia = memberDeclaration _
.GetLeadingTrivia() _
.Reverse() _
.FirstOrDefault(Function(t) t.Kind = SyntaxKind.DocumentationCommentTrivia)
If docCommentTrivia.Kind <> SyntaxKind.DocumentationCommentTrivia Then
Return Nothing
End If
Return DirectCast(docCommentTrivia.GetStructure(), DocumentationCommentTriviaSyntax)
End Function
Public Overrides Function GetDocComment(node As SyntaxNode) As String
Debug.Assert(TypeOf node Is StatementSyntax)
Dim member = DirectCast(node, StatementSyntax)
Dim documentationComment = GetDocCommentNode(member)
If documentationComment Is Nothing Then
Return String.Empty
End If
Dim text = member.SyntaxTree.GetText(CancellationToken.None)
Dim newLine = GetNewLineCharacter(text)
Dim lines = documentationComment.ToString().Split({newLine}, StringSplitOptions.None)
' trim off leading whitespace and exterior trivia.
Dim lengthToStrip = lines(0).GetLeadingWhitespace().Length
Dim linesCount = lines.Length
For i = 1 To lines.Length - 1
Dim line = lines(i).TrimStart()
If line.StartsWith("'''", StringComparison.Ordinal) Then
lines(i) = line.Substring(3)
End If
Next
Return lines.Join(newLine).TrimEnd()
End Function
Public Overrides Function SetDocComment(node As SyntaxNode, value As String) As SyntaxNode
Debug.Assert(TypeOf node Is StatementSyntax)
Dim member = DirectCast(node, StatementSyntax)
Dim triviaList = CType(Nothing, SyntaxTriviaList)
If value IsNot Nothing Then
Dim text = member.SyntaxTree.GetText(CancellationToken.None)
Dim newLine = GetNewLineCharacter(text)
Dim builder = New StringBuilder()
For Each line In value.Split({vbCr, vbLf}, StringSplitOptions.RemoveEmptyEntries)
builder.Append("''' ")
builder.Append(line)
builder.Append(newLine)
Next
triviaList = SyntaxFactory.ParseLeadingTrivia(builder.ToString())
End If
Dim leadingTriviaList = member.GetLeadingTrivia().ToList()
Dim documentationComment = GetDocCommentNode(member)
If documentationComment IsNot Nothing Then
' In this case, we're going to replace the existing XML doc comment.
Dim index = leadingTriviaList.FindIndex(Function(t) t = documentationComment.ParentTrivia)
leadingTriviaList.RemoveAt(index)
For Each triviaElement In triviaList.Reverse()
leadingTriviaList.Insert(index, triviaElement)
Next
Else
' Otherwise, just add the XML doc comment to the end of the leading trivia.
leadingTriviaList.AddRange(triviaList)
End If
Return member.WithLeadingTrivia(leadingTriviaList)
End Function
Public Overrides Function GetFunctionKind(symbol As IMethodSymbol) As EnvDTE.vsCMFunction
If symbol.IsOverride AndAlso symbol.Name = "Finalize" Then
Return EnvDTE.vsCMFunction.vsCMFunctionDestructor
End If
Select Case symbol.MethodKind
Case MethodKind.Ordinary,
MethodKind.DeclareMethod
Return If(symbol.ReturnsVoid, EnvDTE.vsCMFunction.vsCMFunctionSub, EnvDTE.vsCMFunction.vsCMFunctionFunction)
Case MethodKind.Constructor,
MethodKind.StaticConstructor
Return EnvDTE.vsCMFunction.vsCMFunctionConstructor
Case MethodKind.UserDefinedOperator
Return EnvDTE.vsCMFunction.vsCMFunctionOperator
Case MethodKind.PropertyGet
Return EnvDTE.vsCMFunction.vsCMFunctionPropertyGet
Case MethodKind.PropertySet
Return EnvDTE.vsCMFunction.vsCMFunctionPropertySet
Case MethodKind.EventAdd
Return CType(EnvDTE80.vsCMFunction2.vsCMFunctionAddHandler, EnvDTE.vsCMFunction)
Case MethodKind.EventRemove
Return CType(EnvDTE80.vsCMFunction2.vsCMFunctionRemoveHandler, EnvDTE.vsCMFunction)
Case MethodKind.EventRaise
Return CType(EnvDTE80.vsCMFunction2.vsCMFunctionRaiseEvent, EnvDTE.vsCMFunction)
End Select
Throw Exceptions.ThrowEUnexpected()
End Function
Public Overrides Function GetInheritanceKind(typeNode As SyntaxNode, typeSymbol As INamedTypeSymbol) As EnvDTE80.vsCMInheritanceKind
Dim result As EnvDTE80.vsCMInheritanceKind = 0
If typeSymbol.IsSealed Then
result = result Or EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindSealed
ElseIf typeSymbol.IsAbstract Then
result = result Or EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindAbstract
End If
' Old VB code model had a special case to check other parts for Shadows, so we'll do that here..
Dim statements = typeSymbol.DeclaringSyntaxReferences _
.Select(Function(r) TryCast(r.GetSyntax(), StatementSyntax)) _
.Where(Function(s) s IsNot Nothing)
For Each statement In statements
Dim modifiers = SyntaxFactory.TokenList(statement.GetModifiers())
If modifiers.Any(SyntaxKind.ShadowsKeyword) Then
result = result Or EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNew
Exit For
End If
Next
Return result
End Function
Private Shared Function IsValidInheritanceKind(kind As EnvDTE80.vsCMInheritanceKind) As Boolean
Return kind = EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindAbstract OrElse
kind = EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNone OrElse
kind = EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindSealed OrElse
kind = EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNew OrElse
kind = (EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNew Or EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindAbstract) OrElse
kind = (EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNew Or EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindSealed)
End Function
Public Overrides Function SetInheritanceKind(typeNode As SyntaxNode, kind As EnvDTE80.vsCMInheritanceKind) As SyntaxNode
Debug.Assert(TypeOf typeNode Is ClassBlockSyntax OrElse
TypeOf typeNode Is ModuleBlockSyntax)
If TypeOf typeNode Is ModuleBlockSyntax Then
If kind = EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNone Then
Return typeNode
End If
Throw Exceptions.ThrowENotImpl()
End If
If Not IsValidInheritanceKind(kind) Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim member = TryCast(typeNode, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = member.GetModifierFlags()
flags = flags And Not (ModifierFlags.MustInherit Or ModifierFlags.NotInheritable Or ModifierFlags.Shadows)
If kind <> EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNone Then
If (kind And EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindAbstract) <> 0 Then
flags = flags Or ModifierFlags.MustInherit
ElseIf (kind And EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindSealed) <> 0 Then
flags = flags Or ModifierFlags.NotInheritable
End If
If (kind And EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNew) <> 0 Then
flags = flags Or ModifierFlags.Shadows
End If
End If
Return member.UpdateModifiers(flags)
End Function
Public Overrides Function GetMustImplement(memberNode As SyntaxNode) As Boolean
Debug.Assert(TypeOf memberNode Is StatementSyntax)
Dim member = TryCast(memberNode, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
If member.Parent.Kind = SyntaxKind.InterfaceBlock Then
Return True
End If
Dim flags = member.GetModifierFlags()
Return (flags And ModifierFlags.MustOverride) <> 0
End Function
Public Overrides Function SetMustImplement(memberNode As SyntaxNode, value As Boolean) As SyntaxNode
Dim overrideKind = If(value, EnvDTE80.vsCMOverrideKind.vsCMOverrideKindAbstract, EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNone)
Return SetOverrideKind(memberNode, overrideKind)
End Function
Public Overrides Function GetOverrideKind(memberNode As SyntaxNode) As EnvDTE80.vsCMOverrideKind
Debug.Assert(TypeOf memberNode Is DeclarationStatementSyntax)
Dim member = TryCast(memberNode, DeclarationStatementSyntax)
If member IsNot Nothing Then
Dim modifiers = SyntaxFactory.TokenList(member.GetModifiers())
Dim result As EnvDTE80.vsCMOverrideKind = 0
If modifiers.Any(SyntaxKind.ShadowsKeyword) Then
result = result Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNew
End If
If modifiers.Any(SyntaxKind.OverridesKeyword) Then
result = result Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindOverride
End If
If modifiers.Any(SyntaxKind.MustOverrideKeyword) Or member.IsParentKind(SyntaxKind.InterfaceBlock) Then
result = result Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindAbstract
End If
If modifiers.Any(SyntaxKind.OverridableKeyword) Then
result = result Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindVirtual
ElseIf modifiers.Any(SyntaxKind.NotOverridableKeyword) Then
result = result Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindSealed
End If
Return result
End If
Throw New InvalidOperationException
End Function
Private Shared Function IsValidOverrideKind(kind As EnvDTE80.vsCMOverrideKind) As Boolean
Return kind = EnvDTE80.vsCMOverrideKind.vsCMOverrideKindSealed OrElse
kind = EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNew OrElse
kind = EnvDTE80.vsCMOverrideKind.vsCMOverrideKindOverride OrElse
kind = (EnvDTE80.vsCMOverrideKind.vsCMOverrideKindOverride Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindSealed) OrElse
kind = (EnvDTE80.vsCMOverrideKind.vsCMOverrideKindVirtual Or EnvDTE80.vsCMInheritanceKind.vsCMInheritanceKindNew) OrElse
kind = EnvDTE80.vsCMOverrideKind.vsCMOverrideKindAbstract OrElse
kind = EnvDTE80.vsCMOverrideKind.vsCMOverrideKindVirtual OrElse
kind = EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNone
End Function
Public Overrides Function SetOverrideKind(memberNode As SyntaxNode, kind As EnvDTE80.vsCMOverrideKind) As SyntaxNode
Dim member = TryCast(memberNode, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
If TypeOf memberNode.Parent Is ModuleBlockSyntax OrElse
TypeOf memberNode.Parent Is InterfaceBlockSyntax OrElse
TypeOf memberNode.Parent Is PropertyBlockSyntax OrElse
TypeOf memberNode.Parent Is PropertyStatementSyntax Then
Throw Exceptions.ThrowENotImpl()
End If
If Not IsValidOverrideKind(kind) Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim flags = member.GetModifierFlags()
flags = flags And Not (ModifierFlags.NotOverridable Or ModifierFlags.Shadows Or ModifierFlags.Overrides Or ModifierFlags.MustOverride Or ModifierFlags.Overridable)
Select Case kind
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindSealed
flags = flags Or ModifierFlags.NotOverridable
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNew
flags = flags Or ModifierFlags.Shadows
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindOverride
flags = flags Or ModifierFlags.Overrides
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindAbstract
flags = flags Or ModifierFlags.MustOverride
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindVirtual
flags = flags Or ModifierFlags.Overridable
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindOverride Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindSealed
flags = flags Or ModifierFlags.NotOverridable Or ModifierFlags.Overrides
Case EnvDTE80.vsCMOverrideKind.vsCMOverrideKindVirtual Or EnvDTE80.vsCMOverrideKind.vsCMOverrideKindNew
flags = flags Or ModifierFlags.Overridable Or ModifierFlags.Shadows
End Select
Dim resultMember = member.UpdateModifiers(flags)
If (flags And ModifierFlags.MustOverride) <> 0 Then
If TypeOf resultMember Is MethodBlockBaseSyntax Then
resultMember = DirectCast(resultMember, MethodBlockBaseSyntax).BlockStatement
ElseIf TypeOf resultMember Is PropertyBlockSyntax Then
resultMember = DirectCast(resultMember, PropertyBlockSyntax).PropertyStatement
End If
Else
If TypeOf resultMember Is MethodStatementSyntax Then
If resultMember.Kind = SyntaxKind.FunctionStatement Then
resultMember = SyntaxFactory.FunctionBlock(
subOrFunctionStatement:=DirectCast(resultMember, MethodStatementSyntax),
statements:=Nothing,
endSubOrFunctionStatement:=SyntaxFactory.EndFunctionStatement())
ElseIf resultMember.Kind = SyntaxKind.SubStatement Then
resultMember = SyntaxFactory.SubBlock(
subOrFunctionStatement:=DirectCast(resultMember, MethodStatementSyntax),
statements:=Nothing,
endSubOrFunctionStatement:=SyntaxFactory.EndSubStatement())
End If
ElseIf TypeOf resultMember Is PropertyStatementSyntax Then
Dim propertyStatement = DirectCast(resultMember, PropertyStatementSyntax)
Dim parameterName = "value"
If propertyStatement.Identifier.GetTypeCharacter() <> TypeCharacter.None Then
parameterName &= propertyStatement.Identifier.GetTypeCharacter().GetTypeCharacterString()
End If
Dim returnType = propertyStatement.GetReturnType()
Dim asClauseText = If(returnType IsNot Nothing,
" As " & returnType.ToString(),
String.Empty)
resultMember = SyntaxFactory.PropertyBlock(
propertyStatement:=propertyStatement,
accessors:=SyntaxFactory.List(Of AccessorBlockSyntax)({
SyntaxFactory.GetAccessorBlock(
accessorStatement:=SyntaxFactory.GetAccessorStatement(),
statements:=Nothing,
endAccessorStatement:=SyntaxFactory.EndGetStatement()),
SyntaxFactory.SetAccessorBlock(
accessorStatement:=SyntaxFactory.SetAccessorStatement(
attributeLists:=Nothing,
modifiers:=Nothing,
parameterList:=SyntaxFactory.ParseParameterList("(" & parameterName & asClauseText & ")")),
statements:=Nothing,
endAccessorStatement:=SyntaxFactory.EndSetStatement())
}))
End If
End If
Return resultMember
End Function
Public Overrides Function GetIsAbstract(memberNode As SyntaxNode, symbol As ISymbol) As Boolean
Return symbol.IsAbstract
End Function
Public Overrides Function SetIsAbstract(memberNode As SyntaxNode, value As Boolean) As SyntaxNode
If TypeOf memberNode Is StructureBlockSyntax OrElse
TypeOf memberNode Is ModuleBlockSyntax Then
Throw Exceptions.ThrowENotImpl()
End If
Dim member = TryCast(memberNode, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = member.GetModifierFlags()
If value Then
If TypeOf memberNode Is TypeBlockSyntax Then
flags = flags Or ModifierFlags.MustInherit
Else
flags = flags Or ModifierFlags.MustOverride
End If
Else
If TypeOf memberNode Is TypeBlockSyntax Then
flags = flags And Not ModifierFlags.MustInherit
Else
flags = flags And Not ModifierFlags.MustOverride
End If
End If
Return member.UpdateModifiers(flags)
End Function
Public Overrides Function GetIsConstant(variableNode As SyntaxNode) As Boolean
If TypeOf variableNode Is EnumMemberDeclarationSyntax Then
Return True
End If
Dim member = TryCast(GetNodeWithModifiers(variableNode), StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim flags = member.GetModifierFlags()
' VB legacy code model returns True for both Const and ReadOnly fields
Return (flags And (ModifierFlags.Const Or ModifierFlags.ReadOnly)) <> 0
End Function
Public Overrides Function SetIsConstant(variableNode As SyntaxNode, value As Boolean) As SyntaxNode
Dim constKind = If(value, EnvDTE80.vsCMConstKind.vsCMConstKindConst, EnvDTE80.vsCMConstKind.vsCMConstKindNone)
Return SetConstKind(variableNode, constKind)
End Function
Public Overrides Function GetIsDefault(propertyNode As SyntaxNode) As Boolean
Debug.Assert(TypeOf propertyNode Is PropertyBlockSyntax OrElse
TypeOf propertyNode Is PropertyStatementSyntax)
If TypeOf propertyNode Is PropertyStatementSyntax Then
Return False
End If
Dim propertyBlock = TryCast(propertyNode, PropertyBlockSyntax)
If propertyBlock Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Return propertyBlock.PropertyStatement.Modifiers.Any(SyntaxKind.DefaultKeyword)
End Function
Public Overrides Function SetIsDefault(propertyNode As SyntaxNode, value As Boolean) As SyntaxNode
Debug.Assert(TypeOf propertyNode Is PropertyBlockSyntax OrElse
TypeOf propertyNode Is PropertyStatementSyntax)
Dim member = DirectCast(propertyNode, StatementSyntax)
Dim flags = member.GetModifierFlags()
flags = flags And Not ModifierFlags.Default
If value Then
flags = flags Or ModifierFlags.Default
End If
Return member.UpdateModifiers(flags)
End Function
Public Overrides Function GetIsGeneric(node As SyntaxNode) As Boolean
Debug.Assert(TypeOf node Is StatementSyntax)
Return DirectCast(node, StatementSyntax).GetArity() > 0
End Function
Public Overrides Function GetIsPropertyStyleEvent(eventNode As SyntaxNode) As Boolean
Debug.Assert(TypeOf eventNode Is EventStatementSyntax OrElse
TypeOf eventNode Is EventBlockSyntax)
Return TypeOf eventNode Is EventBlockSyntax
End Function
Public Overrides Function GetIsShared(memberNode As SyntaxNode, symbol As ISymbol) As Boolean
Return _
(symbol.Kind = SymbolKind.NamedType AndAlso DirectCast(symbol, INamedTypeSymbol).TypeKind = TypeKind.Module) OrElse
symbol.IsStatic
End Function
Public Overrides Function SetIsShared(memberNode As SyntaxNode, value As Boolean) As SyntaxNode
If TypeOf memberNode Is TypeBlockSyntax Then
Throw Exceptions.ThrowENotImpl()
End If
Dim member = TryCast(memberNode, StatementSyntax)
If member Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
Dim parentType = TryCast(member.Parent, DeclarationStatementSyntax)
If parentType Is Nothing Then
Throw Exceptions.ThrowEFail()
End If
If TypeOf parentType Is ModuleBlockSyntax OrElse
TypeOf parentType Is InterfaceBlockSyntax OrElse
TypeOf parentType Is EnumBlockSyntax Then
Throw Exceptions.ThrowENotImpl()
End If
Dim flags = member.GetModifierFlags() And Not ModifierFlags.Dim
If value Then
flags = flags Or ModifierFlags.Shared
Else
flags = flags And Not ModifierFlags.Shared
End If
If flags = 0 AndAlso member.IsKind(SyntaxKind.FieldDeclaration) Then
flags = flags Or ModifierFlags.Dim
End If
Return member.UpdateModifiers(flags)
End Function
Public Overrides Function GetReadWrite(memberNode As SyntaxNode) As EnvDTE80.vsCMPropertyKind
Debug.Assert(TypeOf memberNode Is PropertyBlockSyntax OrElse
TypeOf memberNode Is PropertyStatementSyntax)
Dim propertyStatement = TryCast(memberNode, PropertyStatementSyntax)
If propertyStatement Is Nothing Then
Dim propertyBlock = TryCast(memberNode, PropertyBlockSyntax)
If propertyBlock IsNot Nothing Then
propertyStatement = propertyBlock.PropertyStatement
End If
End If
If propertyStatement IsNot Nothing Then
If propertyStatement.Modifiers.Any(SyntaxKind.WriteOnlyKeyword) Then
Return EnvDTE80.vsCMPropertyKind.vsCMPropertyKindWriteOnly
ElseIf propertyStatement.Modifiers.Any(SyntaxKind.ReadOnlyKeyword) Then
Return EnvDTE80.vsCMPropertyKind.vsCMPropertyKindReadOnly
Else
Return EnvDTE80.vsCMPropertyKind.vsCMPropertyKindReadWrite
End If
End If
Throw Exceptions.ThrowEUnexpected()
End Function
Private Shared Function SetDelegateType(delegateStatement As DelegateStatementSyntax, typeSymbol As ITypeSymbol) As DelegateStatementSyntax
' Remove the leading and trailing trivia and save it for reattachment later.
Dim leadingTrivia = delegateStatement.GetLeadingTrivia()
Dim trailingTrivia = delegateStatement.GetTrailingTrivia()
delegateStatement = delegateStatement _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
If typeSymbol Is Nothing Then
' If no type is specified (e.g. CodeElement.Type = Nothing), we just convert to a Sub
' if it isn't one already.
If delegateStatement.IsKind(SyntaxKind.DelegateFunctionStatement) Then
delegateStatement = SyntaxFactory.DelegateSubStatement(
attributeLists:=delegateStatement.AttributeLists,
modifiers:=delegateStatement.Modifiers,
identifier:=delegateStatement.Identifier,
typeParameterList:=delegateStatement.TypeParameterList,
parameterList:=delegateStatement.ParameterList,
asClause:=Nothing)
End If
Else
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
' If this is a Sub, convert to a Function
If delegateStatement.IsKind(SyntaxKind.DelegateSubStatement) Then
delegateStatement = SyntaxFactory.DelegateFunctionStatement(
attributeLists:=delegateStatement.AttributeLists,
modifiers:=delegateStatement.Modifiers,
identifier:=delegateStatement.Identifier,
typeParameterList:=delegateStatement.TypeParameterList,
parameterList:=delegateStatement.ParameterList,
asClause:=delegateStatement.AsClause)
End If
If delegateStatement.AsClause IsNot Nothing Then
Debug.Assert(TypeOf delegateStatement.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(delegateStatement.AsClause, SimpleAsClauseSyntax).Type
delegateStatement = delegateStatement.ReplaceNode(oldType, newType)
Else
delegateStatement = delegateStatement.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
End If
Return delegateStatement _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetEventType(eventStatement As EventStatementSyntax, typeSymbol As ITypeSymbol) As EventStatementSyntax
If typeSymbol Is Nothing Then
Throw Exceptions.ThrowEInvalidArg()
End If
' Remove the leading and trailing trivia and save it for reattachment later.
Dim leadingTrivia = eventStatement.GetLeadingTrivia()
Dim trailingTrivia = eventStatement.GetTrailingTrivia()
eventStatement = eventStatement _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
' If the event has a parameter list, we need to remove it.
If eventStatement.ParameterList IsNot Nothing Then
eventStatement = eventStatement.WithParameterList(Nothing)
End If
If eventStatement.AsClause IsNot Nothing Then
Debug.Assert(TypeOf eventStatement.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(eventStatement.AsClause, SimpleAsClauseSyntax).Type
eventStatement = eventStatement.ReplaceNode(oldType, newType)
Else
eventStatement = eventStatement.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
Return eventStatement _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetEventType(eventBlock As EventBlockSyntax, typeSymbol As ITypeSymbol) As EventBlockSyntax
If typeSymbol Is Nothing Then
Throw Exceptions.ThrowEInvalidArg()
End If
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
' Update the event statement
Dim eventStatement = eventBlock.EventStatement
Dim leadingTrivia = eventStatement.GetLeadingTrivia()
Dim trailingTrivia = eventStatement.GetTrailingTrivia()
eventStatement = eventStatement _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
If eventStatement.AsClause IsNot Nothing Then
Debug.Assert(TypeOf eventStatement.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(eventStatement.AsClause, SimpleAsClauseSyntax).Type
eventStatement = eventStatement.ReplaceNode(oldType, newType)
Else
eventStatement = eventStatement.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
eventStatement = eventStatement _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
eventBlock = eventBlock.WithEventStatement(eventStatement)
For i = 0 To eventBlock.Accessors.Count - 1
Dim accessorBlock = eventBlock.Accessors(i)
Dim newAccessorBlock = accessorBlock
If accessorBlock.Kind = SyntaxKind.AddHandlerAccessorBlock OrElse
accessorBlock.Kind = SyntaxKind.RemoveHandlerAccessorBlock Then
' Update the first parameter of the AddHandler or RemoveHandler statements
Dim firstParameter = accessorBlock.BlockStatement.ParameterList.Parameters.FirstOrDefault()
If firstParameter IsNot Nothing Then
Dim newFirstParameter As ParameterSyntax
If firstParameter.AsClause IsNot Nothing Then
Debug.Assert(TypeOf firstParameter.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(firstParameter.AsClause, SimpleAsClauseSyntax).Type
newFirstParameter = firstParameter.ReplaceNode(oldType, newType)
Else
newFirstParameter = firstParameter.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
newFirstParameter = newFirstParameter _
.WithLeadingTrivia(firstParameter.GetLeadingTrivia()) _
.WithTrailingTrivia(firstParameter.GetTrailingTrivia())
newAccessorBlock = accessorBlock.ReplaceNode(firstParameter, newFirstParameter)
End If
ElseIf accessorBlock.Kind = SyntaxKind.RaiseEventAccessorBlock Then
' For RaiseEvent, we replace the whole signature with the delegate's invoke method
Dim namedTypeSymbol = TryCast(typeSymbol, INamedTypeSymbol)
If namedTypeSymbol IsNot Nothing Then
Dim invokeMethod = namedTypeSymbol.DelegateInvokeMethod
If invokeMethod IsNot Nothing Then
Dim parameterStrings = invokeMethod.Parameters.Select(Function(p) p.ToDisplayString(s_raiseEventSignatureFormat))
Dim parameterListString = "("c & String.Join(", ", parameterStrings) & ")"c
Dim newParameterList = SyntaxFactory.ParseParameterList(parameterListString)
newParameterList = newParameterList.WithTrailingTrivia(accessorBlock.BlockStatement.ParameterList.GetTrailingTrivia())
newAccessorBlock = accessorBlock.ReplaceNode(accessorBlock.BlockStatement.ParameterList, newParameterList)
End If
End If
End If
If accessorBlock IsNot newAccessorBlock Then
eventBlock = eventBlock.ReplaceNode(accessorBlock, newAccessorBlock)
End If
Next
Return eventBlock
End Function
Private Shared Function SetMethodType(declareStatement As DeclareStatementSyntax, typeSymbol As ITypeSymbol) As DeclareStatementSyntax
' Remove the leading and trailing trivia and save it for reattachment later.
Dim leadingTrivia = declareStatement.GetLeadingTrivia()
Dim trailingTrivia = declareStatement.GetTrailingTrivia()
declareStatement = declareStatement _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
If typeSymbol Is Nothing Then
' If no type is specified (e.g. CodeElement.Type = Nothing), we just convert to a Sub
' if it isn't one already.
If declareStatement.IsKind(SyntaxKind.DeclareFunctionStatement) Then
declareStatement = SyntaxFactory.DeclareSubStatement(
attributeLists:=declareStatement.AttributeLists,
modifiers:=declareStatement.Modifiers,
declareKeyword:=declareStatement.DeclareKeyword,
charsetKeyword:=declareStatement.CharsetKeyword,
subOrFunctionKeyword:=SyntaxFactory.Token(SyntaxKind.SubKeyword),
identifier:=declareStatement.Identifier,
libKeyword:=declareStatement.LibKeyword,
libraryName:=declareStatement.LibraryName,
aliasKeyword:=declareStatement.AliasKeyword,
aliasName:=declareStatement.AliasName,
parameterList:=declareStatement.ParameterList,
asClause:=Nothing)
End If
Else
Dim newType = SyntaxFactory.ParseTypeName(typeSymbol.ToDisplayString(s_setTypeFormat))
declareStatement = SyntaxFactory.DeclareFunctionStatement(
attributeLists:=declareStatement.AttributeLists,
modifiers:=declareStatement.Modifiers,
declareKeyword:=declareStatement.DeclareKeyword,
charsetKeyword:=declareStatement.CharsetKeyword,
subOrFunctionKeyword:=SyntaxFactory.Token(SyntaxKind.FunctionKeyword),
identifier:=declareStatement.Identifier,
libKeyword:=declareStatement.LibKeyword,
libraryName:=declareStatement.LibraryName,
aliasKeyword:=declareStatement.AliasKeyword,
aliasName:=declareStatement.AliasName,
parameterList:=declareStatement.ParameterList,
asClause:=declareStatement.AsClause)
If declareStatement.AsClause IsNot Nothing Then
Debug.Assert(TypeOf declareStatement.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(declareStatement.AsClause, SimpleAsClauseSyntax).Type
declareStatement = declareStatement.ReplaceNode(oldType, newType)
Else
declareStatement = declareStatement.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
End If
Return declareStatement.WithLeadingTrivia(leadingTrivia).WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetMethodType(methodStatement As MethodStatementSyntax, typeSymbol As ITypeSymbol) As MethodStatementSyntax
' Remove the leading and trailing trivia and save it for reattachment later.
Dim leadingTrivia = methodStatement.GetLeadingTrivia()
Dim trailingTrivia = methodStatement.GetTrailingTrivia()
methodStatement = methodStatement _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
If typeSymbol Is Nothing Then
' If no type is specified (e.g. CodeElement.Type = Nothing), we just convert to a Sub
' if it isn't one already.
If methodStatement.IsKind(SyntaxKind.FunctionStatement) Then
methodStatement = SyntaxFactory.SubStatement(
attributeLists:=methodStatement.AttributeLists,
modifiers:=methodStatement.Modifiers,
identifier:=methodStatement.Identifier,
typeParameterList:=methodStatement.TypeParameterList,
parameterList:=methodStatement.ParameterList,
asClause:=Nothing,
handlesClause:=methodStatement.HandlesClause,
implementsClause:=methodStatement.ImplementsClause)
End If
Else
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
' If this is a Sub, convert to a Function
If methodStatement.IsKind(SyntaxKind.SubStatement) Then
methodStatement = SyntaxFactory.FunctionStatement(
attributeLists:=methodStatement.AttributeLists,
modifiers:=methodStatement.Modifiers,
identifier:=methodStatement.Identifier,
typeParameterList:=methodStatement.TypeParameterList,
parameterList:=methodStatement.ParameterList,
asClause:=methodStatement.AsClause,
handlesClause:=methodStatement.HandlesClause,
implementsClause:=methodStatement.ImplementsClause)
End If
If methodStatement.AsClause IsNot Nothing Then
Debug.Assert(TypeOf methodStatement.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(methodStatement.AsClause, SimpleAsClauseSyntax).Type
methodStatement = methodStatement.ReplaceNode(oldType, newType)
Else
methodStatement = methodStatement.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
End If
Return methodStatement _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetMethodType(methodBlock As MethodBlockSyntax, typeSymbol As ITypeSymbol) As MethodBlockSyntax
' Remove the leading and trailing trivia and save it for reattachment later.
Dim leadingTrivia = methodBlock.GetLeadingTrivia()
Dim trailingTrivia = methodBlock.GetTrailingTrivia()
methodBlock = methodBlock _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim methodStatement = SetMethodType(DirectCast(methodBlock.BlockStatement, MethodStatementSyntax), typeSymbol)
Dim endMethodStatement = methodBlock.EndBlockStatement
If endMethodStatement IsNot Nothing AndAlso Not endMethodStatement.IsMissing Then
' Note that we don't have to remove/replace the trailing trivia for the end block statement
' because we're already doing that for the whole block.
If endMethodStatement.IsKind(SyntaxKind.EndSubStatement) AndAlso typeSymbol IsNot Nothing Then
endMethodStatement = SyntaxFactory.EndFunctionStatement()
ElseIf endMethodStatement.IsKind(SyntaxKind.EndFunctionStatement) AndAlso typeSymbol Is Nothing Then
endMethodStatement = SyntaxFactory.EndSubStatement()
End If
End If
methodBlock = methodBlock.Update(If(methodStatement.Kind = SyntaxKind.SubStatement, SyntaxKind.SubBlock, SyntaxKind.FunctionBlock),
methodStatement, methodBlock.Statements, endMethodStatement)
Return methodBlock _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetParameterType(parameter As ParameterSyntax, typeSymbol As ITypeSymbol) As ParameterSyntax
If typeSymbol Is Nothing Then
Return parameter
End If
' Remove the leading and trailing trivia and save it for reattachment later.\
Dim leadingTrivia = parameter.GetLeadingTrivia()
Dim trailingTrivia = parameter.GetTrailingTrivia()
parameter = parameter _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
If parameter.AsClause IsNot Nothing Then
Debug.Assert(TypeOf parameter.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(parameter.AsClause, SimpleAsClauseSyntax).Type
parameter = parameter.ReplaceNode(oldType, newType)
Else
parameter = parameter.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
Return parameter _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetPropertyType(propertyStatement As PropertyStatementSyntax, typeSymbol As ITypeSymbol) As PropertyStatementSyntax
If typeSymbol Is Nothing Then
Throw Exceptions.ThrowEInvalidArg()
End If
' Remove the leading and trailing trivia and save it for reattachment later.\
Dim leadingTrivia = propertyStatement.GetLeadingTrivia()
Dim trailingTrivia = propertyStatement.GetTrailingTrivia()
propertyStatement = propertyStatement _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
If propertyStatement.AsClause IsNot Nothing Then
Dim oldType = propertyStatement.AsClause.Type()
If oldType IsNot Nothing Then
propertyStatement = propertyStatement.ReplaceNode(oldType, newType)
End If
Else
propertyStatement = propertyStatement.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
Return propertyStatement _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetPropertyType(propertyBlock As PropertyBlockSyntax, typeSymbol As ITypeSymbol) As PropertyBlockSyntax
If typeSymbol Is Nothing Then
Throw Exceptions.ThrowEInvalidArg()
End If
' Remove the leading and trailing trivia and save it for reattachment later.\
Dim leadingTrivia = propertyBlock.GetLeadingTrivia()
Dim trailingTrivia = propertyBlock.GetTrailingTrivia()
propertyBlock = propertyBlock _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim propertyStatement = SetPropertyType(propertyBlock.PropertyStatement, typeSymbol)
propertyBlock = propertyBlock.WithPropertyStatement(propertyStatement)
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
For i = 0 To propertyBlock.Accessors.Count - 1
Dim accessorBlock = propertyBlock.Accessors(i)
Dim newAccessorBlock = accessorBlock
If accessorBlock.Kind = SyntaxKind.SetAccessorBlock Then
' Update the first parameter of the SetAccessor statement
Dim firstParameter = accessorBlock.BlockStatement.ParameterList.Parameters.FirstOrDefault()
If firstParameter IsNot Nothing Then
Dim newFirstParameter As ParameterSyntax
If firstParameter.AsClause IsNot Nothing Then
Debug.Assert(TypeOf firstParameter.AsClause Is SimpleAsClauseSyntax)
Dim oldType = DirectCast(firstParameter.AsClause, SimpleAsClauseSyntax).Type
newFirstParameter = firstParameter.ReplaceNode(oldType, newType)
Else
newFirstParameter = firstParameter.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
newFirstParameter = newFirstParameter _
.WithLeadingTrivia(firstParameter.GetLeadingTrivia()) _
.WithTrailingTrivia(firstParameter.GetTrailingTrivia())
newAccessorBlock = accessorBlock.ReplaceNode(firstParameter, newFirstParameter)
End If
End If
If accessorBlock IsNot newAccessorBlock Then
propertyBlock = propertyBlock.ReplaceNode(accessorBlock, newAccessorBlock)
End If
Next
Return propertyBlock _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Private Shared Function SetVariableType(variableDeclarator As VariableDeclaratorSyntax, typeSymbol As ITypeSymbol) As VariableDeclaratorSyntax
If typeSymbol Is Nothing Then
Throw Exceptions.ThrowEInvalidArg()
End If
' Remove the leading and trailing trivia and save it for reattachment later.\
Dim leadingTrivia = variableDeclarator.GetLeadingTrivia()
Dim trailingTrivia = variableDeclarator.GetTrailingTrivia()
variableDeclarator = variableDeclarator _
.WithLeadingTrivia(SyntaxTriviaList.Empty) _
.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim typeName = typeSymbol.ToDisplayString(s_setTypeFormat)
Dim newType = SyntaxFactory.ParseTypeName(typeName)
If variableDeclarator.AsClause IsNot Nothing Then
Dim oldType = variableDeclarator.AsClause.Type()
If oldType IsNot Nothing Then
variableDeclarator = variableDeclarator.ReplaceNode(oldType, newType)
End If
Else
variableDeclarator = variableDeclarator.WithAsClause(SyntaxFactory.SimpleAsClause(newType))
End If
Return variableDeclarator _
.WithLeadingTrivia(leadingTrivia) _
.WithTrailingTrivia(trailingTrivia)
End Function
Public Overrides Function SetType(node As SyntaxNode, typeSymbol As ITypeSymbol) As SyntaxNode
Debug.Assert(TypeOf node Is DelegateStatementSyntax OrElse
TypeOf node Is EventStatementSyntax OrElse
TypeOf node Is EventBlockSyntax OrElse
TypeOf node Is DeclareStatementSyntax OrElse
TypeOf node Is MethodStatementSyntax OrElse
TypeOf node Is MethodBlockBaseSyntax OrElse
TypeOf node Is ParameterSyntax OrElse
TypeOf node Is PropertyStatementSyntax OrElse
TypeOf node Is PropertyBlockSyntax OrElse
TypeOf node Is VariableDeclaratorSyntax)
If TypeOf node Is DelegateStatementSyntax Then
Return SetDelegateType(DirectCast(node, DelegateStatementSyntax), typeSymbol)
End If
If TypeOf node Is EventStatementSyntax Then
Return SetEventType(DirectCast(node, EventStatementSyntax), typeSymbol)
End If
If TypeOf node Is EventBlockSyntax Then
Return SetEventType(DirectCast(node, EventBlockSyntax), typeSymbol)
End If
If TypeOf node Is DeclareStatementSyntax Then
Return SetMethodType(DirectCast(node, DeclareStatementSyntax), typeSymbol)
End If
If TypeOf node Is MethodStatementSyntax Then
Return SetMethodType(DirectCast(node, MethodStatementSyntax), typeSymbol)
End If
If TypeOf node Is MethodBlockSyntax Then
Return SetMethodType(DirectCast(node, MethodBlockSyntax), typeSymbol)
End If
If TypeOf node Is ConstructorBlockSyntax Then
Return node
End If
If TypeOf node Is OperatorBlockSyntax Then
Return node
End If
If TypeOf node Is ParameterSyntax Then
Return SetParameterType(DirectCast(node, ParameterSyntax), typeSymbol)
End If
If TypeOf node Is PropertyStatementSyntax Then
Return SetPropertyType(DirectCast(node, PropertyStatementSyntax), typeSymbol)
End If
If TypeOf node Is PropertyBlockSyntax Then
Return SetPropertyType(DirectCast(node, PropertyBlockSyntax), typeSymbol)
End If
If TypeOf node Is VariableDeclaratorSyntax Then
Return SetVariableType(DirectCast(node, VariableDeclaratorSyntax), typeSymbol)
End If
Throw New NotImplementedException()
End Function
Public Overrides Function GetFullyQualifiedName(name As String, position As Integer, semanticModel As SemanticModel) As String
Dim typeName = SyntaxFactory.ParseTypeName(name)
If TypeOf typeName Is PredefinedTypeSyntax Then
Dim predefinedType As PredefinedType
If SyntaxFactsService.TryGetPredefinedType(DirectCast(typeName, PredefinedTypeSyntax).Keyword, predefinedType) Then
Dim specialType = predefinedType.ToSpecialType()
Return semanticModel.Compilation.GetSpecialType(specialType).GetEscapedFullName()
End If
Else
Dim symbols = semanticModel.LookupNamespacesAndTypes(position, name:=name)
If symbols.Length > 0 Then
Return symbols(0).GetEscapedFullName()
End If
End If
Return name
End Function
Public Overrides Function GetInitExpression(node As SyntaxNode) As String
Dim initializer As ExpressionSyntax = Nothing
Select Case node.Kind
Case SyntaxKind.Parameter
Dim parameter = DirectCast(node, ParameterSyntax)
If parameter.Default IsNot Nothing Then
initializer = parameter.Default.Value
End If
Case SyntaxKind.ModifiedIdentifier
Dim modifiedIdentifier = DirectCast(node, ModifiedIdentifierSyntax)
Dim variableDeclarator = DirectCast(modifiedIdentifier.Parent, VariableDeclaratorSyntax)
initializer = variableDeclarator.GetInitializer()
Case SyntaxKind.EnumMemberDeclaration
Dim enumMemberDeclaration = DirectCast(node, EnumMemberDeclarationSyntax)
If enumMemberDeclaration.Initializer IsNot Nothing Then
initializer = enumMemberDeclaration.Initializer.Value
End If
End Select
Return If(initializer IsNot Nothing,
initializer.ToString(),
Nothing)
End Function
Public Overrides Function AddInitExpression(node As SyntaxNode, value As String) As SyntaxNode
Select Case node.Kind
Case SyntaxKind.Parameter
Dim parameter = DirectCast(node, ParameterSyntax)
Dim parameterKind = GetParameterKind(parameter)
If Not (parameterKind And EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional) <> 0 Then
Throw Exceptions.ThrowEInvalidArg
End If
If String.IsNullOrWhiteSpace(value) Then
' Remove the Optional modifier
parameterKind = parameterKind And Not EnvDTE80.vsCMParameterKind.vsCMParameterKindOptional
parameter = DirectCast(SetParameterKind(parameter, parameterKind), ParameterSyntax)
If parameter.Default IsNot Nothing Then
parameter = parameter.RemoveNode(parameter.Default, SyntaxRemoveOptions.KeepNoTrivia)
End If
Return parameter
End If
Dim expression = SyntaxFactory.ParseExpression(value)
Dim equalsValueClause = If(parameter.Default IsNot Nothing AndAlso Not parameter.Default.IsMissing,
parameter.Default.WithValue(expression),
SyntaxFactory.EqualsValue(expression))
Return parameter.WithDefault(equalsValueClause)
Case SyntaxKind.VariableDeclarator
Dim variableDeclarator = DirectCast(node, VariableDeclaratorSyntax)
If String.IsNullOrWhiteSpace(value) Then
If variableDeclarator.Initializer IsNot Nothing Then
variableDeclarator = variableDeclarator.RemoveNode(variableDeclarator.Initializer, SyntaxRemoveOptions.KeepExteriorTrivia)
End If
Return variableDeclarator
End If
Dim trailingTrivia = variableDeclarator.GetTrailingTrivia()
variableDeclarator = variableDeclarator.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim expression = SyntaxFactory.ParseExpression(value)
Dim equalsValueClause = If(variableDeclarator.Initializer IsNot Nothing AndAlso Not variableDeclarator.Initializer.IsMissing,
variableDeclarator.Initializer.WithValue(expression),
SyntaxFactory.EqualsValue(expression)).WithTrailingTrivia(trailingTrivia)
Return variableDeclarator.WithInitializer(equalsValueClause)
Case SyntaxKind.EnumMemberDeclaration
Dim enumMemberDeclaration = DirectCast(node, EnumMemberDeclarationSyntax)
If String.IsNullOrWhiteSpace(value) Then
If enumMemberDeclaration.Initializer IsNot Nothing Then
enumMemberDeclaration = enumMemberDeclaration.RemoveNode(enumMemberDeclaration.Initializer, SyntaxRemoveOptions.KeepExteriorTrivia)
End If
Return enumMemberDeclaration
End If
Dim trailingTrivia = enumMemberDeclaration.GetTrailingTrivia()
enumMemberDeclaration = enumMemberDeclaration.WithTrailingTrivia(SyntaxTriviaList.Empty)
Dim expression = SyntaxFactory.ParseExpression(value)
Dim equalsValueClause = If(enumMemberDeclaration.Initializer IsNot Nothing AndAlso Not enumMemberDeclaration.Initializer.IsMissing,
enumMemberDeclaration.Initializer.WithValue(expression),
SyntaxFactory.EqualsValue(expression)).WithTrailingTrivia(trailingTrivia)
Return enumMemberDeclaration.WithInitializer(equalsValueClause)
Case Else
Throw Exceptions.ThrowEFail()
End Select
End Function
Public Overrides Function GetDestination(containerNode As SyntaxNode) As CodeGenerationDestination
Return VisualBasicCodeGenerationHelpers.GetDestination(containerNode)
End Function
Protected Overrides Function GetDefaultAccessibility(targetSymbolKind As SymbolKind, destination As CodeGenerationDestination) As Accessibility
If destination = CodeGenerationDestination.StructType Then
Return Accessibility.Public
End If
Select Case targetSymbolKind
Case SymbolKind.Field
Return Accessibility.Private
Case SymbolKind.Method,
SymbolKind.Property,
SymbolKind.Event,
SymbolKind.NamedType
Return Accessibility.Public
Case Else
Debug.Fail("Invalid symbol kind: " & targetSymbolKind)
Throw Exceptions.ThrowEFail()
End Select
End Function
Public Overrides Function GetTypeSymbolFromFullName(fullName As String, compilation As Compilation) As ITypeSymbol
Dim typeSymbol As ITypeSymbol = compilation.GetTypeByMetadataName(fullName)
If typeSymbol Is Nothing Then
Dim parsedTypeName = SyntaxFactory.ParseTypeName(fullName)
' Check to see if the name we parsed has any skipped text. If it does, don't bother trying to
' speculatively bind it because we'll likely just get the wrong thing since we found a bunch
' of non-sensical tokens.
' NOTE: There appears to be a VB parser issue where "ContainsSkippedText" does not return true
' even when there is clearly skipped token trivia present. We work around this by for a particularly
' common case by checking whether the trailing trivia contains any skipped token trivia.
' https://github.com/dotnet/roslyn/issues/7182 has been filed for the parser issue.
If parsedTypeName.ContainsSkippedText OrElse
parsedTypeName.GetTrailingTrivia().Any(SyntaxKind.SkippedTokensTrivia) Then
Return Nothing
End If
' If we couldn't get the name, we just grab the first tree in the compilation to
' speculatively bind at position zero. However, if there *aren't* any trees, we fork the
' compilation with an empty tree for the purposes of speculative binding.
'
' I'm a bad person.
Dim tree = compilation.SyntaxTrees.FirstOrDefault()
If tree Is Nothing Then
tree = s_emptyTree
compilation = compilation.AddSyntaxTrees(tree)
End If
Dim semanticModel = compilation.GetSemanticModel(tree)
typeSymbol = semanticModel.GetSpeculativeTypeInfo(0, parsedTypeName, SpeculativeBindingOption.BindAsTypeOrNamespace).Type
End If
If typeSymbol Is Nothing Then
Debug.Fail("Could not find type: " & fullName)
Throw New ArgumentException()
End If
Return typeSymbol
End Function
Protected Overrides Function GetTypeSymbolFromPartialName(partialName As String, semanticModel As SemanticModel, position As Integer) As ITypeSymbol
Dim parsedTypeName = SyntaxFactory.ParseTypeName(partialName)
Return semanticModel.GetSpeculativeTypeInfo(position, parsedTypeName, SpeculativeBindingOption.BindAsTypeOrNamespace).Type
End Function
Public Overrides Function CreateReturnDefaultValueStatement(type As ITypeSymbol) As SyntaxNode
Return SyntaxFactory.ReturnStatement(
SyntaxFactory.NothingLiteralExpression(
SyntaxFactory.Token(SyntaxKind.NothingKeyword)))
End Function
Protected Overrides Function IsCodeModelNode(node As SyntaxNode) As Boolean
Select Case CType(node.Kind, SyntaxKind)
Case SyntaxKind.ClassBlock,
SyntaxKind.ConstructorBlock,
SyntaxKind.DeclareFunctionStatement,
SyntaxKind.DeclareSubStatement,
SyntaxKind.DelegateFunctionStatement,
SyntaxKind.DelegateSubStatement,
SyntaxKind.EnumBlock,
SyntaxKind.EnumMemberDeclaration,
SyntaxKind.EventBlock,
SyntaxKind.EventStatement,
SyntaxKind.FieldDeclaration,
SyntaxKind.FunctionBlock,
SyntaxKind.InterfaceBlock,
SyntaxKind.ModuleBlock,
SyntaxKind.NamespaceBlock,
SyntaxKind.OperatorBlock,
SyntaxKind.PropertyBlock,
SyntaxKind.StructureBlock,
SyntaxKind.SubBlock,
SyntaxKind.SimpleImportsClause
Return True
Case Else
Return False
End Select
End Function
Protected Overrides Function GetFieldFromVariableNode(variableNode As SyntaxNode) As SyntaxNode
Return If(variableNode.Kind = SyntaxKind.ModifiedIdentifier,
variableNode.FirstAncestorOrSelf(Of FieldDeclarationSyntax)(),
variableNode)
End Function
Protected Overrides Function GetVariableFromFieldNode(fieldNode As SyntaxNode) As SyntaxNode
' Work around that the fact that VB code model really deals with fields as modified identifiers
Return If(TypeOf fieldNode Is FieldDeclarationSyntax,
DirectCast(fieldNode, FieldDeclarationSyntax).Declarators.Single().Names.Single(),
fieldNode)
End Function
Protected Overrides Function GetAttributeFromAttributeDeclarationNode(node As SyntaxNode) As SyntaxNode
Return If(TypeOf node Is AttributeListSyntax,
DirectCast(node, AttributeListSyntax).Attributes.First,
node)
End Function
Protected Overrides Function GetSpanToFormat(root As SyntaxNode, span As TextSpan) As TextSpan
Dim startToken = GetTokenWithoutAnnotation(root.FindToken(span.Start).GetPreviousToken(), Function(t) t.GetPreviousToken())
Dim endToken = GetTokenWithoutAnnotation(root.FindToken(span.End), Function(t) t.GetNextToken())
Return GetEncompassingSpan(root, startToken, endToken)
End Function
Protected Overrides Function InsertMemberNodeIntoContainer(index As Integer, member As SyntaxNode, container As SyntaxNode) As SyntaxNode
Dim declarationStatement = DirectCast(member, DeclarationStatementSyntax)
If TypeOf container Is CompilationUnitSyntax Then
Dim compilationUnit = DirectCast(container, CompilationUnitSyntax)
Return compilationUnit.WithMembers(compilationUnit.Members.Insert(index, declarationStatement))
ElseIf TypeOf container Is NamespaceBlockSyntax Then
Dim namespaceBlock = DirectCast(container, NamespaceBlockSyntax)
Return namespaceBlock.WithMembers(namespaceBlock.Members.Insert(index, declarationStatement))
ElseIf TypeOf container Is ClassBlockSyntax Then
Dim classBlock = DirectCast(container, ClassBlockSyntax)
Return classBlock.WithMembers(classBlock.Members.Insert(index, declarationStatement))
ElseIf TypeOf container Is InterfaceBlockSyntax Then
Dim interfaceBlock = DirectCast(container, InterfaceBlockSyntax)
Return interfaceBlock.WithMembers(interfaceBlock.Members.Insert(index, declarationStatement))
ElseIf TypeOf container Is StructureBlockSyntax Then
Dim structureBlock = DirectCast(container, StructureBlockSyntax)
Return structureBlock.WithMembers(structureBlock.Members.Insert(index, declarationStatement))
ElseIf TypeOf container Is ModuleBlockSyntax Then
Dim moduleBlock = DirectCast(container, ModuleBlockSyntax)
Return moduleBlock.WithMembers(moduleBlock.Members.Insert(index, declarationStatement))
ElseIf TypeOf container Is EnumBlockSyntax Then
Dim enumBlock = DirectCast(container, EnumBlockSyntax)
Return enumBlock.WithMembers(enumBlock.Members.Insert(index, declarationStatement))
End If
Throw Exceptions.ThrowEFail()
End Function
Protected Overrides Function InsertAttributeArgumentIntoContainer(index As Integer, attributeArgument As SyntaxNode, container As SyntaxNode) As SyntaxNode
If TypeOf container Is AttributeSyntax Then
Dim attribute = DirectCast(container, AttributeSyntax)
Dim argumentList = attribute.ArgumentList
Dim newArgumentList As ArgumentListSyntax
If argumentList Is Nothing Then
newArgumentList = SyntaxFactory.ArgumentList(
SyntaxFactory.SingletonSeparatedList(
DirectCast(attributeArgument, ArgumentSyntax)))
Else
Dim newArguments = argumentList.Arguments.Insert(index, DirectCast(attributeArgument, ArgumentSyntax))
newArgumentList = argumentList.WithArguments(newArguments)
End If
Return attribute.WithArgumentList(newArgumentList)
End If
Throw Exceptions.ThrowEFail()
End Function
Private Shared Function InsertAttributeListInto(attributes As SyntaxList(Of AttributesStatementSyntax), index As Integer, attribute As AttributesStatementSyntax) As SyntaxList(Of AttributesStatementSyntax)
' we need to explicitly add end of line trivia here since both of them (with or without) are valid but parsed differently
If index = 0 Then
Return attributes.Insert(index, attribute)
End If
Dim previousAttribute = attributes(index - 1)
If previousAttribute.GetTrailingTrivia().Any(Function(t) t.Kind = SyntaxKind.EndOfLineTrivia) Then
Return attributes.Insert(index, attribute)
End If
attributes = attributes.Replace(previousAttribute, previousAttribute.WithAppendedTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed))
Return attributes.Insert(index, attribute)
End Function
Protected Overrides Function InsertAttributeListIntoContainer(index As Integer, list As SyntaxNode, container As SyntaxNode) As SyntaxNode
' If the attribute is being inserted at the first index and the container is not the compilation unit, copy leading trivia
' to the attribute that is being inserted.
If index = 0 AndAlso TypeOf container IsNot CompilationUnitSyntax Then
Dim firstToken = container.GetFirstToken()
If firstToken.HasLeadingTrivia Then
Dim trivia = firstToken.LeadingTrivia
container = container.ReplaceToken(firstToken, firstToken.WithLeadingTrivia(SyntaxTriviaList.Empty))
list = list.WithLeadingTrivia(trivia)
End If
End If
' If the attribute to be inserted does not have a trailing line break, add one (unless this is a parameter).
If TypeOf container IsNot ParameterSyntax AndAlso
(Not list.HasTrailingTrivia OrElse Not list.GetTrailingTrivia().Any(SyntaxKind.EndOfLineTrivia)) Then
list = list.WithAppendedTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed)
End If
Dim attributeList = DirectCast(list, AttributeListSyntax)
If TypeOf container Is CompilationUnitSyntax Then
Dim compilationUnit = DirectCast(container, CompilationUnitSyntax)
Dim attributesStatement = SyntaxFactory.AttributesStatement(SyntaxFactory.SingletonList(attributeList))
Dim attributeStatements = InsertAttributeListInto(compilationUnit.Attributes, index, attributesStatement)
Return compilationUnit.WithAttributes(attributeStatements)
ElseIf TypeOf container Is ModuleBlockSyntax Then
Dim moduleBlock = DirectCast(container, ModuleBlockSyntax)
Dim attributeLists = moduleBlock.ModuleStatement.AttributeLists.Insert(index, attributeList)
Return moduleBlock.WithBlockStatement(moduleBlock.ModuleStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf container Is StructureBlockSyntax Then
Dim structureBlock = DirectCast(container, StructureBlockSyntax)
Dim attributeLists = structureBlock.StructureStatement.AttributeLists.Insert(index, attributeList)
Return structureBlock.WithStructureStatement(structureBlock.StructureStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf container Is InterfaceBlockSyntax Then
Dim interfaceBlock = DirectCast(container, InterfaceBlockSyntax)
Dim attributeLists = interfaceBlock.InterfaceStatement.AttributeLists.Insert(index, attributeList)
Return interfaceBlock.WithInterfaceStatement(interfaceBlock.InterfaceStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf container Is ClassBlockSyntax Then
Dim classBlock = DirectCast(container, ClassBlockSyntax)
Dim attributeLists = classBlock.ClassStatement.AttributeLists.Insert(index, attributeList)
Dim begin = classBlock.ClassStatement.WithAttributeLists(attributeLists)
Return classBlock.WithClassStatement(begin)
ElseIf TypeOf container Is EnumBlockSyntax Then
Dim enumBlock = DirectCast(container, EnumBlockSyntax)
Dim attributeLists = enumBlock.EnumStatement.AttributeLists.Insert(index, attributeList)
Return enumBlock.WithEnumStatement(enumBlock.EnumStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf container Is EnumMemberDeclarationSyntax Then
Dim enumMember = DirectCast(container, EnumMemberDeclarationSyntax)
Dim attributeLists = enumMember.AttributeLists.Insert(index, attributeList)
Return enumMember.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is DelegateStatementSyntax Then
Dim delegateStatement = DirectCast(container, DelegateStatementSyntax)
Dim attributeLists = delegateStatement.AttributeLists.Insert(index, attributeList)
Return delegateStatement.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is DeclareStatementSyntax Then
Dim declareStatement = DirectCast(container, DeclareStatementSyntax)
Dim attributeLists = declareStatement.AttributeLists.Insert(index, attributeList)
Return declareStatement.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is MethodStatementSyntax Then
Dim methodStatement = DirectCast(container, MethodStatementSyntax)
Dim attributeLists = methodStatement.AttributeLists.Insert(index, attributeList)
Return methodStatement.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is MethodBlockBaseSyntax Then
Dim method = DirectCast(container, MethodBlockBaseSyntax)
If TypeOf method.BlockStatement Is SubNewStatementSyntax Then
Dim constructor = DirectCast(method.BlockStatement, SubNewStatementSyntax)
Dim attributeLists = constructor.AttributeLists.Insert(index, attributeList)
Return DirectCast(method, ConstructorBlockSyntax).WithBlockStatement(constructor.WithAttributeLists(attributeLists))
ElseIf TypeOf method.BlockStatement Is OperatorStatementSyntax Then
Dim operatorStatement = DirectCast(method.BlockStatement, OperatorStatementSyntax)
Dim attributeLists = operatorStatement.AttributeLists.Insert(index, attributeList)
Return DirectCast(method, OperatorBlockSyntax).WithBlockStatement(operatorStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf method.BlockStatement Is MethodStatementSyntax Then
Dim methodStatement = DirectCast(method.BlockStatement, MethodStatementSyntax)
Dim attributeLists = methodStatement.AttributeLists.Insert(index, attributeList)
Return DirectCast(method, MethodBlockSyntax).WithBlockStatement(methodStatement.WithAttributeLists(attributeLists))
End If
ElseIf TypeOf container Is PropertyStatementSyntax Then
Dim propertyStatement = DirectCast(container, PropertyStatementSyntax)
Dim attributeLists = propertyStatement.AttributeLists.Insert(index, attributeList)
Return propertyStatement.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is PropertyBlockSyntax Then
Dim propertyBlock = DirectCast(container, PropertyBlockSyntax)
Dim attributeLists = propertyBlock.PropertyStatement.AttributeLists.Insert(index, attributeList)
Return propertyBlock.WithPropertyStatement(propertyBlock.PropertyStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf container Is EventStatementSyntax Then
Dim eventStatement = DirectCast(container, EventStatementSyntax)
Dim attributeLists = eventStatement.AttributeLists.Insert(index, attributeList)
Return eventStatement.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is EventBlockSyntax Then
Dim eventBlock = DirectCast(container, EventBlockSyntax)
Dim attributeLists = eventBlock.EventStatement.AttributeLists.Insert(index, attributeList)
Return eventBlock.WithEventStatement(eventBlock.EventStatement.WithAttributeLists(attributeLists))
ElseIf TypeOf container Is FieldDeclarationSyntax Then
Dim field = DirectCast(container, FieldDeclarationSyntax)
Dim attributeLists = field.AttributeLists.Insert(index, attributeList)
Return field.WithAttributeLists(attributeLists)
ElseIf TypeOf container Is ParameterSyntax Then
Dim parameter = DirectCast(container, ParameterSyntax)
Dim attributeLists = parameter.AttributeLists.Insert(index, attributeList)
Return parameter.WithAttributeLists(attributeLists)
End If
Throw Exceptions.ThrowEUnexpected()
End Function
Protected Overrides Function InsertImportIntoContainer(index As Integer, importNode As SyntaxNode, container As SyntaxNode) As SyntaxNode
If TypeOf container IsNot CompilationUnitSyntax Then
Throw Exceptions.ThrowEUnexpected()
End If
Dim compilationUnit = DirectCast(container, CompilationUnitSyntax)
Dim importsStatement = DirectCast(importNode, ImportsStatementSyntax)
Dim lastToken = importsStatement.GetLastToken()
If lastToken.Kind <> SyntaxKind.EndOfLineTrivia Then
importsStatement = importsStatement.ReplaceToken(lastToken, lastToken.WithAppendedTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed))
End If
Dim importsList = compilationUnit.Imports.Insert(index, importsStatement)
Return compilationUnit.WithImports(importsList)
End Function
Private Shared Function InsertParameterIntoParameterList(index As Integer, parameter As ParameterSyntax, list As ParameterListSyntax) As ParameterListSyntax
If list Is Nothing Then
Return SyntaxFactory.ParameterList(SyntaxFactory.SingletonSeparatedList(parameter)) _
.WithAdditionalAnnotations(Formatter.Annotation)
End If
Dim parameters = list.Parameters.Insert(index, parameter)
Return list.WithParameters(parameters)
End Function
Protected Overrides Function InsertParameterIntoContainer(index As Integer, parameter As SyntaxNode, container As SyntaxNode) As SyntaxNode
Dim parameterNode = DirectCast(parameter, ParameterSyntax)
If TypeOf container Is MethodBaseSyntax Then
Dim methodStatement = DirectCast(container, MethodBaseSyntax)
Dim parameterList = InsertParameterIntoParameterList(index, parameterNode, methodStatement.ParameterList)
Return methodStatement.WithParameterList(parameterList)
ElseIf TypeOf container Is MethodBlockBaseSyntax Then
Dim methodBlock = DirectCast(container, MethodBlockBaseSyntax)
Dim methodStatement = methodBlock.BlockStatement
Dim parameterList = InsertParameterIntoParameterList(index, parameterNode, methodStatement.ParameterList)
methodStatement = methodStatement.WithParameterList(parameterList)
Select Case methodBlock.Kind
Case SyntaxKind.SubBlock, SyntaxKind.FunctionBlock
Return DirectCast(methodBlock, MethodBlockSyntax).WithBlockStatement(DirectCast(methodStatement, MethodStatementSyntax))
Case SyntaxKind.ConstructorBlock
Return DirectCast(methodBlock, ConstructorBlockSyntax).WithBlockStatement(DirectCast(methodStatement, SubNewStatementSyntax))
Case SyntaxKind.OperatorBlock
Return DirectCast(methodBlock, OperatorBlockSyntax).WithBlockStatement(DirectCast(methodStatement, OperatorStatementSyntax))
Case Else
Return DirectCast(methodBlock, AccessorBlockSyntax).WithBlockStatement(DirectCast(methodStatement, AccessorStatementSyntax))
End Select
ElseIf TypeOf container Is PropertyBlockSyntax Then
Dim propertyBlock = DirectCast(container, PropertyBlockSyntax)
Dim propertyStatement = propertyBlock.PropertyStatement
Dim parameterList = InsertParameterIntoParameterList(index, parameterNode, propertyStatement.ParameterList)
propertyStatement = propertyStatement.WithParameterList(parameterList)
Return propertyBlock.WithPropertyStatement(propertyStatement)
End If
Throw Exceptions.ThrowEUnexpected()
End Function
Public Overrides Function IsNamespace(node As SyntaxNode) As Boolean
Return TypeOf node Is NamespaceBlockSyntax
End Function
Public Overrides Function IsType(node As SyntaxNode) As Boolean
Return TypeOf node Is TypeBlockSyntax OrElse
TypeOf node Is EnumBlockSyntax
End Function
Public Overrides Function GetMethodXml(node As SyntaxNode, semanticModel As SemanticModel) As String
Dim methodBlock = TryCast(node, MethodBlockBaseSyntax)
If methodBlock Is Nothing Then
Throw Exceptions.ThrowEUnexpected()
End If
Return MethodXmlBuilder.Generate(methodBlock, semanticModel)
End Function
Private Shared Function GetMethodStatement(method As SyntaxNode) As MethodStatementSyntax
Dim methodBlock = TryCast(method, MethodBlockBaseSyntax)
If methodBlock Is Nothing Then
Return Nothing
End If
Return TryCast(methodBlock.BlockStatement, MethodStatementSyntax)
End Function
Private Overloads Shared Function GetHandledEventNames(methodStatement As MethodStatementSyntax) As IList(Of String)
If methodStatement Is Nothing OrElse
methodStatement.HandlesClause Is Nothing OrElse
methodStatement.HandlesClause.Events.Count = 0 Then
Return SpecializedCollections.EmptyList(Of String)()
End If
Dim eventCount = methodStatement.HandlesClause.Events.Count
Dim result(eventCount - 1) As String
For i = 0 To eventCount - 1
Dim handlesItem = methodStatement.HandlesClause.Events(i)
result(i) = handlesItem.EventContainer.ToString() & "."c & handlesItem.EventMember.ToString()
Next
Return result
End Function
Private Shared Function EscapeIfNotMeMyBaseOrMyClass(identifier As String) As String
Select Case SyntaxFacts.GetKeywordKind(identifier)
Case SyntaxKind.MeKeyword,
SyntaxKind.MyBaseKeyword,
SyntaxKind.MyClassKeyword,
SyntaxKind.None
Return identifier
Case Else
Return "["c & identifier & "]"c
End Select
End Function
Private Shared Function MakeHandledEventName(parentName As String, eventName As String) As String
If eventName.Length >= parentName.Length Then
If CaseInsensitiveComparison.Equals(eventName.Substring(0, parentName.Length), parentName) Then
Return "MyBase" & eventName.Substring(parentName.Length)
End If
End If
' If eventName starts with an unescaped keyword other than Me, MyBase or MyClass, we need to escape it.
If Not eventName.StartsWith("[", StringComparison.Ordinal) Then
Dim dotIndex = eventName.IndexOf("."c)
If dotIndex >= 0 Then
Return EscapeIfNotMeMyBaseOrMyClass(eventName.Substring(0, dotIndex)) & eventName.Substring(dotIndex)
Else
EscapeIfNotMeMyBaseOrMyClass(eventName)
End If
End If
Return eventName
End Function
Public Overrides Function AddHandlesClause(document As Document, eventName As String, method As SyntaxNode, cancellationToken As CancellationToken) As Document
Dim methodStatement = GetMethodStatement(method)
Dim parentTypeBlock = TryCast(method.Parent, TypeBlockSyntax)
If parentTypeBlock Is Nothing Then
Throw Exceptions.ThrowEUnexpected()
End If
Dim parentName = parentTypeBlock.BlockStatement.Identifier.ToString()
Dim newEventName = MakeHandledEventName(parentName, eventName)
Dim position As Integer
Dim textToInsert As String
If methodStatement.HandlesClause Is Nothing Then
position = methodStatement.ParameterList.CloseParenToken.Span.End
textToInsert = " Handles " & newEventName
Else
position = methodStatement.HandlesClause.Span.End
textToInsert = ", " & newEventName
End If
Dim text = document.GetTextSynchronously(cancellationToken)
text = text.Replace(position, 0, textToInsert)
Return document.WithText(text)
End Function
Public Overrides Function RemoveHandlesClause(document As Document, eventName As String, method As SyntaxNode, cancellationToken As CancellationToken) As Document
Dim methodStatement = GetMethodStatement(method)
Dim parentTypeBlock = TryCast(method.Parent, TypeBlockSyntax)
If parentTypeBlock Is Nothing Then
Throw Exceptions.ThrowEUnexpected()
End If
Dim parentName = parentTypeBlock.BlockStatement.Identifier.ToString()
Dim newEventName = MakeHandledEventName(parentName, eventName)
If methodStatement.HandlesClause Is Nothing Then
Throw Exceptions.ThrowEUnexpected()
End If
Dim indexOfDot = newEventName.IndexOf("."c)
If indexOfDot = -1 Then
Throw Exceptions.ThrowEUnexpected()
End If
Dim containerName = newEventName.Substring(0, indexOfDot)
Dim memberName = newEventName.Substring(indexOfDot + 1)
Dim clauseItemToRemove As HandlesClauseItemSyntax = Nothing
For Each handlesClauseItem In methodStatement.HandlesClause.Events
If handlesClauseItem.EventContainer.ToString() = containerName AndAlso
handlesClauseItem.EventMember.ToString() = memberName Then
clauseItemToRemove = handlesClauseItem
Exit For
End If
Next
If clauseItemToRemove Is Nothing Then
Throw Exceptions.ThrowEUnexpected()
End If
Dim text = document.GetTextSynchronously(cancellationToken)
If methodStatement.HandlesClause.Events.Count = 1 Then
' Easy case, delete the whole clause
text = text.Replace(methodStatement.HandlesClause.Span, String.Empty)
Else
' Harder case, remove it from the list. If it's the first one, remove the following
' comma, else remove the preceding comma.
Dim index = methodStatement.HandlesClause.Events.IndexOf(clauseItemToRemove)
If index = 0 Then
text = text.Replace(TextSpan.FromBounds(clauseItemToRemove.SpanStart, methodStatement.HandlesClause.Events.GetSeparator(0).Span.End), String.Empty)
Else
text = text.Replace(TextSpan.FromBounds(methodStatement.HandlesClause.Events.GetSeparator(index - 1).SpanStart, clauseItemToRemove.Span.End), String.Empty)
End If
End If
Return document.WithText(text)
End Function
Public Overloads Overrides Function GetHandledEventNames(method As SyntaxNode, semanticModel As SemanticModel) As IList(Of String)
Dim methodStatement = GetMethodStatement(method)
Return GetHandledEventNames(methodStatement)
End Function
Public Overrides Function HandlesEvent(eventName As String, method As SyntaxNode, semanticModel As SemanticModel) As Boolean
Dim methodStatement = GetMethodStatement(method)
Dim handledEventNames = GetHandledEventNames(methodStatement)
For Each handledEventName In handledEventNames
If CaseInsensitiveComparison.Equals(eventName, handledEventName) Then
Return True
End If
Next
Return False
End Function
Public Overrides Function GetFunctionExtenderNames() As String()
Return {ExtenderNames.VBPartialMethodExtender}
End Function
Public Overrides Function GetFunctionExtender(name As String, node As SyntaxNode, symbol As ISymbol) As Object
If Not TypeOf node Is MethodBlockBaseSyntax AndAlso
Not TypeOf node Is MethodStatementSyntax AndAlso
Not TypeOf symbol Is IMethodSymbol Then
Throw Exceptions.ThrowEUnexpected()
End If
If StringComparer.OrdinalIgnoreCase.Equals(name, ExtenderNames.VBPartialMethodExtender) Then
Dim methodSymbol = DirectCast(symbol, IMethodSymbol)
Dim isPartial = methodSymbol.PartialDefinitionPart IsNot Nothing OrElse methodSymbol.PartialImplementationPart IsNot Nothing
Dim isDeclaration = If(isPartial,
methodSymbol.PartialDefinitionPart Is Nothing,
False)
Return PartialMethodExtender.Create(isDeclaration, isPartial)
End If
Throw Exceptions.ThrowEFail()
End Function
Public Overrides Function GetPropertyExtenderNames() As String()
Return {ExtenderNames.VBAutoPropertyExtender}
End Function
Public Overrides Function GetPropertyExtender(name As String, node As SyntaxNode, symbol As ISymbol) As Object
If Not TypeOf node Is PropertyBlockSyntax AndAlso
Not TypeOf node Is PropertyStatementSyntax AndAlso
Not TypeOf symbol Is IPropertySymbol Then
Throw Exceptions.ThrowEUnexpected()
End If
If StringComparer.OrdinalIgnoreCase.Equals(name, ExtenderNames.VBAutoPropertyExtender) Then
Dim isAutoImplemented = TypeOf node Is PropertyStatementSyntax AndAlso
Not TypeOf node.Parent Is InterfaceBlockSyntax
Return AutoPropertyExtender.Create(isAutoImplemented)
End If
Throw Exceptions.ThrowEFail()
End Function
Public Overrides Function GetExternalTypeExtenderNames() As String()
Return {ExtenderNames.ExternalLocation}
End Function
Public Overrides Function GetExternalTypeExtender(name As String, externalLocation As String) As Object
Debug.Assert(externalLocation IsNot Nothing)
If StringComparer.OrdinalIgnoreCase.Equals(name, ExtenderNames.ExternalLocation) Then
Return CodeTypeLocationExtender.Create(externalLocation)
End If
Throw Exceptions.ThrowEFail()
End Function
Public Overrides Function GetTypeExtenderNames() As String()
Return {ExtenderNames.VBGenericExtender}
End Function
Public Overrides Function GetTypeExtender(name As String, codeType As AbstractCodeType) As Object
If codeType Is Nothing Then
Throw Exceptions.ThrowEUnexpected()
End If
If StringComparer.OrdinalIgnoreCase.Equals(name, ExtenderNames.VBGenericExtender) Then
Return GenericExtender.Create(codeType)
End If
Throw Exceptions.ThrowEFail()
End Function
Protected Overrides Function AddBlankLineToMethodBody(node As SyntaxNode, newNode As SyntaxNode) As Boolean
Return TypeOf node Is SyntaxNode AndAlso
node.IsKind(SyntaxKind.SubStatement, SyntaxKind.FunctionStatement) AndAlso
TypeOf newNode Is SyntaxNode AndAlso
newNode.IsKind(SyntaxKind.SubBlock, SyntaxKind.FunctionBlock)
End Function
Public Overrides Function IsValidBaseType(node As SyntaxNode, typeSymbol As ITypeSymbol) As Boolean
If node.IsKind(SyntaxKind.ClassBlock) Then
Return typeSymbol.TypeKind = TypeKind.Class
ElseIf node.IsKind(SyntaxKind.InterfaceBlock) Then
Return typeSymbol.TypeKind = TypeKind.Interface
End If
Return False
End Function
Public Overrides Function AddBase(node As SyntaxNode, typeSymbol As ITypeSymbol, semanticModel As SemanticModel, position As Integer?) As SyntaxNode
If Not node.IsKind(SyntaxKind.ClassBlock, SyntaxKind.InterfaceBlock) Then
Throw Exceptions.ThrowENotImpl()
End If
Dim typeBlock = DirectCast(node, TypeBlockSyntax)
Dim baseCount = typeBlock.Inherits.Count
If typeBlock.IsKind(SyntaxKind.ClassBlock) AndAlso baseCount > 0 Then
Throw Exceptions.ThrowEFail()
End If
Dim typeBlockPosition = typeBlock.SpanStart
Dim inheritsStatement =
SyntaxFactory.InheritsStatement(
SyntaxFactory.ParseTypeName(
typeSymbol.ToMinimalDisplayString(semanticModel, typeBlockPosition)))
inheritsStatement = inheritsStatement.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed)
Dim inheritsStatements = typeBlock.Inherits.Insert(0, inheritsStatement)
Return typeBlock.WithInherits(inheritsStatements)
End Function
Public Overrides Function RemoveBase(node As SyntaxNode, typeSymbol As ITypeSymbol, semanticModel As SemanticModel) As SyntaxNode
If Not node.IsKind(SyntaxKind.ClassBlock, SyntaxKind.InterfaceBlock) Then
Throw Exceptions.ThrowENotImpl()
End If
Dim typeBlock = DirectCast(node, TypeBlockSyntax)
If typeBlock.Inherits.Count = 0 Then
Throw Exceptions.ThrowEFail()
End If
Dim inheritsStatements = typeBlock.Inherits
For Each inheritsStatement In inheritsStatements
For Each inheritsType In inheritsStatement.Types
Dim typeInfo = semanticModel.GetTypeInfo(inheritsType, CancellationToken.None)
If typeInfo.Type IsNot Nothing AndAlso
typeInfo.Type.Equals(typeSymbol) Then
If inheritsStatement.Types.Count = 1 Then
inheritsStatements = inheritsStatements.Remove(inheritsStatement)
Else
Dim newInheritsStatement = inheritsStatement.RemoveNode(inheritsType, SyntaxRemoveOptions.KeepEndOfLine)
inheritsStatements = inheritsStatements.Replace(inheritsStatement, newInheritsStatement)
End If
Exit For
End If
Next
Next
Return typeBlock.WithInherits(inheritsStatements)
End Function
Public Overrides Function IsValidInterfaceType(node As SyntaxNode, typeSymbol As ITypeSymbol) As Boolean
If node.IsKind(SyntaxKind.ClassBlock, SyntaxKind.StructureBlock) Then
Return typeSymbol.TypeKind = TypeKind.Interface
End If
Return False
End Function
Public Overrides Function AddImplementedInterface(node As SyntaxNode, typeSymbol As ITypeSymbol, semanticModel As SemanticModel, position As Integer?) As SyntaxNode
If Not node.IsKind(SyntaxKind.ClassBlock, SyntaxKind.StructureBlock) Then
Throw Exceptions.ThrowENotImpl()
End If
Dim typeBlock = DirectCast(node, TypeBlockSyntax)
Dim baseCount = typeBlock.Implements.Count
Dim insertionIndex As Integer
If position IsNot Nothing Then
insertionIndex = position.Value
If insertionIndex > baseCount Then
Throw Exceptions.ThrowEInvalidArg()
End If
Else
insertionIndex = baseCount
End If
Dim typeBlockPosition = typeBlock.SpanStart
Dim implementsStatement =
SyntaxFactory.ImplementsStatement(
SyntaxFactory.ParseTypeName(
typeSymbol.ToMinimalDisplayString(semanticModel, typeBlockPosition)))
implementsStatement = implementsStatement.WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed)
Dim implementsStatements = typeBlock.Implements.Insert(insertionIndex, implementsStatement)
Return typeBlock.WithImplements(implementsStatements)
End Function
Public Overrides Function RemoveImplementedInterface(node As SyntaxNode, typeSymbol As ITypeSymbol, semanticModel As SemanticModel) As SyntaxNode
If Not node.IsKind(SyntaxKind.ClassBlock, SyntaxKind.StructureBlock) Then
Throw Exceptions.ThrowENotImpl()
End If
Dim typeBlock = DirectCast(node, TypeBlockSyntax)
If typeBlock.Implements.Count = 0 Then
Throw Exceptions.ThrowEFail()
End If
Dim implementsStatements = typeBlock.Implements
For Each implementsStatement In implementsStatements
For Each inheritsType In implementsStatement.Types
Dim typeInfo = semanticModel.GetTypeInfo(inheritsType, CancellationToken.None)
If typeInfo.Type IsNot Nothing AndAlso
typeInfo.Type.Equals(typeSymbol) Then
If implementsStatement.Types.Count = 1 Then
implementsStatements = implementsStatements.Remove(implementsStatement)
Else
Dim newImplementsStatement = implementsStatement.RemoveNode(inheritsType, SyntaxRemoveOptions.KeepEndOfLine)
implementsStatements = implementsStatements.Replace(implementsStatement, newImplementsStatement)
End If
Exit For
End If
Next
Next
Return typeBlock.WithImplements(implementsStatements)
End Function
Public Overrides Sub AttachFormatTrackingToBuffer(buffer As ITextBuffer)
_commitBufferManagerFactory.CreateForBuffer(buffer).AddReferencingView()
End Sub
Public Overrides Sub DetachFormatTrackingToBuffer(buffer As ITextBuffer)
_commitBufferManagerFactory.CreateForBuffer(buffer).RemoveReferencingView()
End Sub
Public Overrides Sub EnsureBufferFormatted(buffer As ITextBuffer)
_commitBufferManagerFactory.CreateForBuffer(buffer).CommitDirty(isExplicitFormat:=False, cancellationToken:=Nothing)
End Sub
End Class
End Namespace
|