VisualBasicSyntaxFactsService.vb 72.0 KB
Newer Older
1
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.
P
Pilchie 已提交
2

3
Imports System.Collections.Immutable
4
Imports System.Composition
B
brettv 已提交
5
Imports System.Text
P
Pilchie 已提交
6 7
Imports System.Threading
Imports Microsoft.CodeAnalysis
8
Imports Microsoft.CodeAnalysis.Collections
B
brettv 已提交
9
Imports Microsoft.CodeAnalysis.FindSymbols
10
Imports Microsoft.CodeAnalysis.Host
11
Imports Microsoft.CodeAnalysis.Host.Mef
P
Pilchie 已提交
12 13 14 15 16 17 18
Imports Microsoft.CodeAnalysis.LanguageServices
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.VisualBasic.SyntaxFacts

Namespace Microsoft.CodeAnalysis.VisualBasic

19
    <ExportLanguageServiceFactory(GetType(ISyntaxFactsService), LanguageNames.VisualBasic), [Shared]>
A
AdamSpeight2008 已提交
20
    Friend Class VisualBasicSyntaxFactsServiceFactory
21
        Implements ILanguageServiceFactory
22
        Private Shared ReadOnly Property Instance As New VisualBasicSyntaxFactsService
23
        Public Sub New()
24

25 26
        End Sub
        Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService
27 28 29 30 31
            Return Instance
        End Function

        Friend Shared Function GetService() As VisualBasicSyntaxFactsService
            Return Instance
P
Pilchie 已提交
32 33
        End Function

34

35 36
        Friend Class VisualBasicSyntaxFactsService
            Inherits AbstractSyntaxFactsService
37
            Implements ISyntaxFactsService, ILanguageService
P
Pilchie 已提交
38

39
            Friend Sub New()
40
            End Sub
P
Pilchie 已提交
41

42 43 44
            Public Function IsAwaitKeyword(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsAwaitKeyword
                Return token.Kind = SyntaxKind.AwaitKeyword
            End Function
P
Pilchie 已提交
45

46 47 48
            Public Function IsIdentifier(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsIdentifier
                Return token.Kind = SyntaxKind.IdentifierToken
            End Function
P
Pilchie 已提交
49

50 51 52
            Public Function IsGlobalNamespaceKeyword(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsGlobalNamespaceKeyword
                Return token.Kind = SyntaxKind.GlobalKeyword
            End Function
P
Pilchie 已提交
53

54
            Public Function IsVerbatimIdentifier(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsVerbatimIdentifier
P
Pilchie 已提交
55
                Return False
56
            End Function
P
Pilchie 已提交
57

58 59 60 61
            Public Function IsOperator(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsOperator
                Return (IsUnaryExpressionOperatorToken(CType(token.Kind, SyntaxKind)) AndAlso (TypeOf token.Parent Is UnaryExpressionSyntax OrElse TypeOf token.Parent Is OperatorStatementSyntax)) OrElse
                       (IsBinaryExpressionOperatorToken(CType(token.Kind, SyntaxKind)) AndAlso (TypeOf token.Parent Is BinaryExpressionSyntax OrElse TypeOf token.Parent Is OperatorStatementSyntax))
            End Function
P
Pilchie 已提交
62

63 64 65
            Public Function IsContextualKeyword(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsContextualKeyword
                Return token.IsContextualKeyword()
            End Function
66

67 68 69
            Public Function IsKeyword(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsKeyword
                Return token.IsKeyword()
            End Function
70

71 72 73
            Public Function IsPreprocessorKeyword(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsPreprocessorKeyword
                Return token.IsPreprocessorKeyword()
            End Function
P
Pilchie 已提交
74

75 76 77
            Public Function IsHashToken(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsHashToken
                Return token.Kind = SyntaxKind.HashToken
            End Function
P
Pilchie 已提交
78

79
            Public Function TryGetCorrespondingOpenBrace(token As SyntaxToken, ByRef openBrace As SyntaxToken) As Boolean Implements ISyntaxFactsService.TryGetCorrespondingOpenBrace
P
Pilchie 已提交
80

81 82 83 84 85
                If token.Kind = SyntaxKind.CloseBraceToken Then
                    Dim tuples = token.Parent.GetBraces()
                    openBrace = tuples.Item1
                    Return openBrace.Kind = SyntaxKind.OpenBraceToken
                End If
P
Pilchie 已提交
86

87 88
                Return False
            End Function
P
Pilchie 已提交
89

90 91 92 93 94
            Public Function IsInInactiveRegion(syntaxTree As SyntaxTree, position As Integer, cancellationToken As CancellationToken) As Boolean Implements ISyntaxFactsService.IsInInactiveRegion
                Dim vbTree = TryCast(syntaxTree, SyntaxTree)
                If vbTree Is Nothing Then
                    Return False
                End If
P
Pilchie 已提交
95

96 97
                Return vbTree.IsInInactiveRegion(position, cancellationToken)
            End Function
98

99 100 101 102 103
            Public Function IsInNonUserCode(syntaxTree As SyntaxTree, position As Integer, cancellationToken As CancellationToken) As Boolean Implements ISyntaxFactsService.IsInNonUserCode
                Dim vbTree = TryCast(syntaxTree, SyntaxTree)
                If vbTree Is Nothing Then
                    Return False
                End If
P
Pilchie 已提交
104

105 106
                Return vbTree.IsInNonUserCode(position, cancellationToken)
            End Function
P
Pilchie 已提交
107

108 109 110 111 112
            Public Function IsEntirelyWithinStringOrCharOrNumericLiteral(syntaxTree As SyntaxTree, position As Integer, cancellationToken As CancellationToken) As Boolean Implements ISyntaxFactsService.IsEntirelyWithinStringOrCharOrNumericLiteral
                Dim vbTree = TryCast(syntaxTree, SyntaxTree)
                If vbTree Is Nothing Then
                    Return False
                End If
P
Pilchie 已提交
113

114 115
                Return vbTree.IsEntirelyWithinStringOrCharOrNumericLiteral(position, cancellationToken)
            End Function
P
Pilchie 已提交
116

117 118 119
            Public Function IsDirective(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsDirective
                Return TypeOf node Is DirectiveTriviaSyntax
            End Function
P
Pilchie 已提交
120

121 122 123 124 125
            Public Function TryGetExternalSourceInfo(node As SyntaxNode, ByRef info As ExternalSourceInfo) As Boolean Implements ISyntaxFactsService.TryGetExternalSourceInfo
                Select Case node.Kind
                    Case SyntaxKind.ExternalSourceDirectiveTrivia
                        info = New ExternalSourceInfo(CInt(DirectCast(node, ExternalSourceDirectiveTriviaSyntax).LineStart.Value), False)
                        Return True
P
Pilchie 已提交
126

127 128 129 130
                    Case SyntaxKind.EndExternalSourceDirectiveTrivia
                        info = New ExternalSourceInfo(Nothing, True)
                        Return True
                End Select
P
Pilchie 已提交
131 132

                Return False
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
            End Function

            Public Function IsObjectCreationExpressionType(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsObjectCreationExpressionType
                Return node.IsParentKind(SyntaxKind.ObjectCreationExpression) AndAlso
                    DirectCast(node.Parent, ObjectCreationExpressionSyntax).Type Is node
            End Function

            Public Function IsAttributeName(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsAttributeName
                Return node.IsParentKind(SyntaxKind.Attribute) AndAlso
                    DirectCast(node.Parent, AttributeSyntax).Name Is node
            End Function

            Public Function IsRightSideOfQualifiedName(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsRightSideOfQualifiedName
                Dim vbNode = TryCast(node, SimpleNameSyntax)
                Return vbNode IsNot Nothing AndAlso vbNode.IsRightSideOfQualifiedName()
            End Function

            Public Function IsMemberAccessExpressionName(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsMemberAccessExpressionName
                Dim vbNode = TryCast(node, SimpleNameSyntax)
                Return vbNode IsNot Nothing AndAlso vbNode.IsMemberAccessExpressionName()
            End Function

            Public Function IsConditionalMemberAccessExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsConditionalMemberAccessExpression
                Return TypeOf node Is ConditionalAccessExpressionSyntax
            End Function

            Public Function IsInvocationExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsInvocationExpression
                Return TypeOf node Is InvocationExpressionSyntax
            End Function

            Public Function IsAnonymousFunction(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsAnonymousFunction
                Return TypeOf node Is LambdaExpressionSyntax
            End Function

            Public Function IsGenericName(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsGenericName
                Return TypeOf node Is GenericNameSyntax
            End Function

            Public Function IsNamedParameter(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsNamedParameter
                Return node.CheckParent(Of SimpleArgumentSyntax)(Function(p) p.IsNamed AndAlso p.NameColonEquals.Name Is node)
            End Function

            Public Function IsSkippedTokensTrivia(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsSkippedTokensTrivia
                Return TypeOf node Is SkippedTokensTriviaSyntax
            End Function

            Public Function HasIncompleteParentMember(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.HasIncompleteParentMember
                Return node.IsParentKind(SyntaxKind.IncompleteMember)
            End Function

            Public Function GetIdentifierOfGenericName(genericName As SyntaxNode) As SyntaxToken Implements ISyntaxFactsService.GetIdentifierOfGenericName
                Dim vbGenericName = TryCast(genericName, GenericNameSyntax)
                Return If(vbGenericName IsNot Nothing, vbGenericName.Identifier, Nothing)
            End Function

            Public ReadOnly Property IsCaseSensitive As Boolean Implements ISyntaxFactsService.IsCaseSensitive
                Get
                    Return False
                End Get
            End Property

            Public Function IsUsingDirectiveName(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsUsingDirectiveName
                Return node.IsParentKind(SyntaxKind.SimpleImportsClause) AndAlso
                       DirectCast(node.Parent, SimpleImportsClauseSyntax).Name Is node
            End Function

            Public Function IsForEachStatement(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsForEachStatement
                Return TypeOf node Is ForEachStatementSyntax
            End Function

            Public Function IsLockStatement(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsLockStatement
                Return TypeOf node Is SyncLockStatementSyntax
            End Function

            Public Function IsUsingStatement(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsUsingStatement
                Return TypeOf node Is UsingStatementSyntax
            End Function

            Public Function IsThisConstructorInitializer(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsThisConstructorInitializer
                If TypeOf token.Parent Is IdentifierNameSyntax AndAlso token.HasMatchingText(SyntaxKind.NewKeyword) Then
                    Dim memberAccess = TryCast(token.Parent.Parent, MemberAccessExpressionSyntax)
                    Return memberAccess.IsThisConstructorInitializer()
                End If
P
Pilchie 已提交
216

217 218
                Return False
            End Function
P
Pilchie 已提交
219

220 221 222 223 224
            Public Function IsBaseConstructorInitializer(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsBaseConstructorInitializer
                If TypeOf token.Parent Is IdentifierNameSyntax AndAlso token.HasMatchingText(SyntaxKind.NewKeyword) Then
                    Dim memberAccess = TryCast(token.Parent.Parent, MemberAccessExpressionSyntax)
                    Return memberAccess.IsBaseConstructorInitializer()
                End If
P
Pilchie 已提交
225

226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405
                Return False
            End Function

            Public Function IsQueryExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsQueryExpression
                Return TypeOf node Is QueryExpressionSyntax
            End Function

            Public Function IsPredefinedType(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsPredefinedType
                Dim actualType As PredefinedType = PredefinedType.None
                Return TryGetPredefinedType(token, actualType) AndAlso actualType <> PredefinedType.None
            End Function

            Public Function IsPredefinedType(token As SyntaxToken, type As PredefinedType) As Boolean Implements ISyntaxFactsService.IsPredefinedType
                Dim actualType As PredefinedType = PredefinedType.None
                Return TryGetPredefinedType(token, actualType) AndAlso actualType = type
            End Function

            Public Function TryGetPredefinedType(token As SyntaxToken, ByRef type As PredefinedType) As Boolean Implements ISyntaxFactsService.TryGetPredefinedType
                type = GetPredefinedType(token)
                Return type <> PredefinedType.None
            End Function

            Private Function GetPredefinedType(token As SyntaxToken) As PredefinedType
                Select Case token.Kind
                    Case SyntaxKind.BooleanKeyword
                        Return PredefinedType.Boolean
                    Case SyntaxKind.ByteKeyword
                        Return PredefinedType.Byte
                    Case SyntaxKind.SByteKeyword
                        Return PredefinedType.SByte
                    Case SyntaxKind.IntegerKeyword
                        Return PredefinedType.Int32
                    Case SyntaxKind.UIntegerKeyword
                        Return PredefinedType.UInt32
                    Case SyntaxKind.ShortKeyword
                        Return PredefinedType.Int16
                    Case SyntaxKind.UShortKeyword
                        Return PredefinedType.UInt16
                    Case SyntaxKind.LongKeyword
                        Return PredefinedType.Int64
                    Case SyntaxKind.ULongKeyword
                        Return PredefinedType.UInt64
                    Case SyntaxKind.SingleKeyword
                        Return PredefinedType.Single
                    Case SyntaxKind.DoubleKeyword
                        Return PredefinedType.Double
                    Case SyntaxKind.DecimalKeyword
                        Return PredefinedType.Decimal
                    Case SyntaxKind.StringKeyword
                        Return PredefinedType.String
                    Case SyntaxKind.CharKeyword
                        Return PredefinedType.Char
                    Case SyntaxKind.ObjectKeyword
                        Return PredefinedType.Object
                    Case SyntaxKind.DateKeyword
                        Return PredefinedType.DateTime
                    Case Else
                        Return PredefinedType.None
                End Select
            End Function

            Public Function IsPredefinedOperator(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsPredefinedOperator
                Dim actualOp As PredefinedOperator = PredefinedOperator.None
                Return TryGetPredefinedOperator(token, actualOp) AndAlso actualOp <> PredefinedOperator.None
            End Function

            Public Function IsPredefinedOperator(token As SyntaxToken, op As PredefinedOperator) As Boolean Implements ISyntaxFactsService.IsPredefinedOperator
                Dim actualOp As PredefinedOperator = PredefinedOperator.None
                Return TryGetPredefinedOperator(token, actualOp) AndAlso actualOp = op
            End Function

            Public Function TryGetPredefinedOperator(token As SyntaxToken, ByRef op As PredefinedOperator) As Boolean Implements ISyntaxFactsService.TryGetPredefinedOperator
                op = GetPredefinedOperator(token)
                Return op <> PredefinedOperator.None
            End Function

            Private Function GetPredefinedOperator(token As SyntaxToken) As PredefinedOperator
                Select Case token.Kind
                    Case SyntaxKind.PlusToken, SyntaxKind.PlusEqualsToken
                        Return PredefinedOperator.Addition

                    Case SyntaxKind.MinusToken, SyntaxKind.MinusEqualsToken
                        Return PredefinedOperator.Subtraction

                    Case SyntaxKind.AndKeyword, SyntaxKind.AndAlsoKeyword
                        Return PredefinedOperator.BitwiseAnd

                    Case SyntaxKind.OrKeyword, SyntaxKind.OrElseKeyword
                        Return PredefinedOperator.BitwiseOr

                    Case SyntaxKind.AmpersandToken, SyntaxKind.AmpersandEqualsToken
                        Return PredefinedOperator.Concatenate

                    Case SyntaxKind.SlashToken, SyntaxKind.SlashEqualsToken
                        Return PredefinedOperator.Division

                    Case SyntaxKind.EqualsToken
                        Return PredefinedOperator.Equality

                    Case SyntaxKind.XorKeyword
                        Return PredefinedOperator.ExclusiveOr

                    Case SyntaxKind.CaretToken, SyntaxKind.CaretEqualsToken
                        Return PredefinedOperator.Exponent

                    Case SyntaxKind.GreaterThanToken
                        Return PredefinedOperator.GreaterThan

                    Case SyntaxKind.GreaterThanEqualsToken
                        Return PredefinedOperator.GreaterThanOrEqual

                    Case SyntaxKind.LessThanGreaterThanToken
                        Return PredefinedOperator.Inequality

                    Case SyntaxKind.BackslashToken, SyntaxKind.BackslashEqualsToken
                        Return PredefinedOperator.IntegerDivision

                    Case SyntaxKind.LessThanLessThanToken, SyntaxKind.LessThanLessThanEqualsToken
                        Return PredefinedOperator.LeftShift

                    Case SyntaxKind.LessThanToken
                        Return PredefinedOperator.LessThan

                    Case SyntaxKind.LessThanEqualsToken
                        Return PredefinedOperator.LessThanOrEqual

                    Case SyntaxKind.LikeKeyword
                        Return PredefinedOperator.Like

                    Case SyntaxKind.NotKeyword
                        Return PredefinedOperator.Complement

                    Case SyntaxKind.ModKeyword
                        Return PredefinedOperator.Modulus

                    Case SyntaxKind.AsteriskToken, SyntaxKind.AsteriskEqualsToken
                        Return PredefinedOperator.Multiplication

                    Case SyntaxKind.GreaterThanGreaterThanToken, SyntaxKind.GreaterThanGreaterThanEqualsToken
                        Return PredefinedOperator.RightShift

                    Case Else
                        Return PredefinedOperator.None
                End Select
            End Function

            Public Function GetText(kind As Integer) As String Implements ISyntaxFactsService.GetText
                Return SyntaxFacts.GetText(CType(kind, SyntaxKind))
            End Function

            Public Function IsIdentifierPartCharacter(c As Char) As Boolean Implements ISyntaxFactsService.IsIdentifierPartCharacter
                Return SyntaxFacts.IsIdentifierPartCharacter(c)
            End Function

            Public Function IsIdentifierStartCharacter(c As Char) As Boolean Implements ISyntaxFactsService.IsIdentifierStartCharacter
                Return SyntaxFacts.IsIdentifierStartCharacter(c)
            End Function

            Public Function IsIdentifierEscapeCharacter(c As Char) As Boolean Implements ISyntaxFactsService.IsIdentifierEscapeCharacter
                Return c = "["c OrElse c = "]"c
            End Function

            Public Function IsValidIdentifier(identifier As String) As Boolean Implements ISyntaxFactsService.IsValidIdentifier
                Dim token = SyntaxFactory.ParseToken(identifier)
                ' TODO: There is no way to get the diagnostics to see if any are actually errors?
                Return IsIdentifier(token) AndAlso Not token.ContainsDiagnostics AndAlso token.ToString().Length = identifier.Length
            End Function

            Public Function IsVerbatimIdentifier(identifier As String) As Boolean Implements ISyntaxFactsService.IsVerbatimIdentifier
                Return IsValidIdentifier(identifier) AndAlso MakeHalfWidthIdentifier(identifier.First()) = "[" AndAlso MakeHalfWidthIdentifier(identifier.Last()) = "]"
            End Function

            Public Function IsTypeCharacter(c As Char) As Boolean Implements ISyntaxFactsService.IsTypeCharacter
                Return c = "%"c OrElse
                       c = "&"c OrElse
                       c = "@"c OrElse
                       c = "!"c OrElse
                       c = "#"c OrElse
                       c = "$"c
            End Function
P
Pilchie 已提交
406

407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427
            Public Function IsStartOfUnicodeEscapeSequence(c As Char) As Boolean Implements ISyntaxFactsService.IsStartOfUnicodeEscapeSequence
                Return False ' VB does not support identifiers with escaped unicode characters 
            End Function

            Public Function IsLiteral(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsLiteral
                Select Case token.Kind()
                    Case _
                            SyntaxKind.IntegerLiteralToken,
                            SyntaxKind.CharacterLiteralToken,
                            SyntaxKind.DecimalLiteralToken,
                            SyntaxKind.FloatingLiteralToken,
                            SyntaxKind.DateLiteralToken,
                            SyntaxKind.StringLiteralToken,
                            SyntaxKind.DollarSignDoubleQuoteToken,
                            SyntaxKind.DoubleQuoteToken,
                            SyntaxKind.InterpolatedStringTextToken,
                            SyntaxKind.TrueKeyword,
                            SyntaxKind.FalseKeyword,
                            SyntaxKind.NothingKeyword
                        Return True
                End Select
P
Pilchie 已提交
428

429 430
                Return False
            End Function
P
Pilchie 已提交
431

432 433 434
            Public Function IsStringLiteralOrInterpolatedStringLiteral(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsStringLiteralOrInterpolatedStringLiteral
                Return token.IsKind(SyntaxKind.StringLiteralToken, SyntaxKind.InterpolatedStringTextToken)
            End Function
P
Pilchie 已提交
435

436 437 438
            Public Function IsNumericLiteralExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsNumericLiteralExpression
                Return If(node Is Nothing, False, node.IsKind(SyntaxKind.NumericLiteralExpression))
            End Function
P
Pilchie 已提交
439

440 441 442 443 444
            Public Function IsBindableToken(token As Microsoft.CodeAnalysis.SyntaxToken) As Boolean Implements ISyntaxFactsService.IsBindableToken
                Return Me.IsWord(token) OrElse
                    Me.IsLiteral(token) OrElse
                    Me.IsOperator(token)
            End Function
P
Pilchie 已提交
445

446 447 448 449
            Public Function IsMemberAccessExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsMemberAccessExpression
                Return TypeOf node Is MemberAccessExpressionSyntax AndAlso
                    DirectCast(node, MemberAccessExpressionSyntax).Kind = SyntaxKind.SimpleMemberAccessExpression
            End Function
P
Pilchie 已提交
450

451 452 453
            Public Function IsPointerMemberAccessExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsPointerMemberAccessExpression
                Return False
            End Function
P
Pilchie 已提交
454

455 456 457 458 459 460 461
            Public Sub GetNameAndArityOfSimpleName(node As SyntaxNode, ByRef name As String, ByRef arity As Integer) Implements ISyntaxFactsService.GetNameAndArityOfSimpleName
                Dim simpleName = TryCast(node, SimpleNameSyntax)
                If simpleName IsNot Nothing Then
                    name = simpleName.Identifier.ValueText
                    arity = simpleName.Arity
                End If
            End Sub
P
Pilchie 已提交
462

463 464 465
            Public Function GetExpressionOfMemberAccessExpression(node As SyntaxNode) As Microsoft.CodeAnalysis.SyntaxNode Implements ISyntaxFactsService.GetExpressionOfMemberAccessExpression
                Return TryCast(node, MemberAccessExpressionSyntax)?.GetExpressionOfMemberAccessExpression()
            End Function
P
Pilchie 已提交
466

467 468 469
            Public Function GetExpressionOfConditionalMemberAccessExpression(node As SyntaxNode) As SyntaxNode Implements ISyntaxFactsService.GetExpressionOfConditionalMemberAccessExpression
                Return TryCast(node, ConditionalAccessExpressionSyntax)?.Expression
            End Function
P
Pilchie 已提交
470

471 472 473
            Public Function GetExpressionOfInterpolation(node As SyntaxNode) As SyntaxNode Implements ISyntaxFactsService.GetExpressionOfInterpolation
                Return TryCast(node, InterpolationSyntax)?.Expression
            End Function
P
Pilchie 已提交
474

475 476 477
            Public Function IsInNamespaceOrTypeContext(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsInNamespaceOrTypeContext
                Return SyntaxFacts.IsInNamespaceOrTypeContext(node)
            End Function
P
Pilchie 已提交
478

479 480 481
            Public Function IsInStaticContext(node As Microsoft.CodeAnalysis.SyntaxNode) As Boolean Implements ISyntaxFactsService.IsInStaticContext
                Return node.IsInStaticContext()
            End Function
P
Pilchie 已提交
482

483 484 485
            Public Function GetExpressionOfArgument(node As Microsoft.CodeAnalysis.SyntaxNode) As Microsoft.CodeAnalysis.SyntaxNode Implements ISyntaxFactsService.GetExpressionOfArgument
                Return TryCast(node, ArgumentSyntax).GetArgumentExpression()
            End Function
P
Pilchie 已提交
486

487 488 489 490
            Public Function GetRefKindOfArgument(node As Microsoft.CodeAnalysis.SyntaxNode) As Microsoft.CodeAnalysis.RefKind Implements ISyntaxFactsService.GetRefKindOfArgument
                ' TODO(cyrusn): Consider the method this argument is passed to, to determine this.
                Return RefKind.None
            End Function
P
Pilchie 已提交
491

492 493 494
            Public Function IsInConstantContext(node As Microsoft.CodeAnalysis.SyntaxNode) As Boolean Implements ISyntaxFactsService.IsInConstantContext
                Return node.IsInConstantContext()
            End Function
P
Pilchie 已提交
495

496 497 498
            Public Function IsInConstructor(node As Microsoft.CodeAnalysis.SyntaxNode) As Boolean Implements ISyntaxFactsService.IsInConstructor
                Return node.GetAncestors(Of StatementSyntax).Any(Function(s) s.Kind = SyntaxKind.ConstructorBlock)
            End Function
P
Pilchie 已提交
499

500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523
            Public Function IsUnsafeContext(node As Microsoft.CodeAnalysis.SyntaxNode) As Boolean Implements ISyntaxFactsService.IsUnsafeContext
                Return False
            End Function

            Public Function GetNameOfAttribute(node As Microsoft.CodeAnalysis.SyntaxNode) As Microsoft.CodeAnalysis.SyntaxNode Implements ISyntaxFactsService.GetNameOfAttribute
                Return DirectCast(node, AttributeSyntax).Name
            End Function

            Public Function IsAttribute(node As Microsoft.CodeAnalysis.SyntaxNode) As Boolean Implements ISyntaxFactsService.IsAttribute
                Return TypeOf node Is AttributeSyntax
            End Function

            Public Function IsAttributeNamedArgumentIdentifier(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsAttributeNamedArgumentIdentifier
                Dim identifierName = TryCast(node, IdentifierNameSyntax)
                Return identifierName.IsParentKind(SyntaxKind.NameColonEquals) AndAlso
                    identifierName.Parent.IsParentKind(SyntaxKind.SimpleArgument) AndAlso
                    identifierName.Parent.Parent.IsParentKind(SyntaxKind.ArgumentList) AndAlso
                    identifierName.Parent.Parent.Parent.IsParentKind(SyntaxKind.Attribute)
            End Function

            Public Function GetContainingTypeDeclaration(root As SyntaxNode, position As Integer) As SyntaxNode Implements ISyntaxFactsService.GetContainingTypeDeclaration
                If root Is Nothing Then
                    Throw New ArgumentNullException(NameOf(root))
                End If
P
Pilchie 已提交
524

525 526 527
                If position < 0 OrElse position > root.Span.End Then
                    Throw New ArgumentOutOfRangeException(NameOf(position))
                End If
P
Pilchie 已提交
528

529 530 531 532 533
                Return root.
                    FindToken(position).
                    GetAncestors(Of SyntaxNode)().
                    FirstOrDefault(Function(n) TypeOf n Is TypeBlockSyntax OrElse TypeOf n Is DelegateStatementSyntax)
            End Function
P
Pilchie 已提交
534

535 536 537 538
            Public Function GetContainingVariableDeclaratorOfFieldDeclaration(node As SyntaxNode) As SyntaxNode Implements ISyntaxFactsService.GetContainingVariableDeclaratorOfFieldDeclaration
                If node Is Nothing Then
                    Throw New ArgumentNullException(NameOf(node))
                End If
P
Pilchie 已提交
539

540
                Dim parent = node.Parent
P
Pilchie 已提交
541

542 543 544 545
                While node IsNot Nothing
                    If node.Kind = SyntaxKind.VariableDeclarator AndAlso node.IsParentKind(SyntaxKind.FieldDeclaration) Then
                        Return node
                    End If
P
Pilchie 已提交
546

547 548
                    node = node.Parent
                End While
P
Pilchie 已提交
549

550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594
                Return Nothing
            End Function

            Public Function FindTokenOnLeftOfPosition(node As SyntaxNode,
                                                      position As Integer,
                                                      Optional includeSkipped As Boolean = True,
                                                      Optional includeDirectives As Boolean = False,
                                                      Optional includeDocumentationComments As Boolean = False) As SyntaxToken Implements ISyntaxFactsService.FindTokenOnLeftOfPosition
                Return node.FindTokenOnLeftOfPosition(position, includeSkipped, includeDirectives, includeDocumentationComments)
            End Function

            Public Function FindTokenOnRightOfPosition(node As SyntaxNode,
                                                       position As Integer,
                                                       Optional includeSkipped As Boolean = True,
                                                       Optional includeDirectives As Boolean = False,
                                                       Optional includeDocumentationComments As Boolean = False) As SyntaxToken Implements ISyntaxFactsService.FindTokenOnRightOfPosition
                Return node.FindTokenOnRightOfPosition(position, includeSkipped, includeDirectives, includeDocumentationComments)
            End Function

            Public Function IsObjectCreationExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsObjectCreationExpression
                Return TypeOf node Is ObjectCreationExpressionSyntax
            End Function

            Public Function IsObjectInitializerNamedAssignmentIdentifier(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsObjectInitializerNamedAssignmentIdentifier
                Dim identifier = TryCast(node, IdentifierNameSyntax)
                Return If(identifier?.IsChildNode(Of NamedFieldInitializerSyntax)(Function(n) n.Name), False)
            End Function

            Public Function IsElementAccessExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsElementAccessExpression
                ' VB doesn't have a specialized node for element access.  Instead, it just uses an
                ' invocation expression or dictionary access expression.
                Return node.Kind = SyntaxKind.InvocationExpression OrElse node.Kind = SyntaxKind.DictionaryAccessExpression
            End Function

            Public Function ToIdentifierToken(name As String) As SyntaxToken Implements ISyntaxFactsService.ToIdentifierToken
                Return name.ToIdentifierToken()
            End Function

            Public Function Parenthesize(expression As SyntaxNode, Optional includeElasticTrivia As Boolean = True) As SyntaxNode Implements ISyntaxFactsService.Parenthesize
                Return DirectCast(expression, ExpressionSyntax).Parenthesize()
            End Function

            Public Function IsTypeNamedVarInVariableOrFieldDeclaration(token As SyntaxToken, parent As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsTypeNamedVarInVariableOrFieldDeclaration
                Return False
            End Function
P
Pilchie 已提交
595

596 597 598
            Public Function IsTypeNamedDynamic(token As SyntaxToken, parent As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsTypeNamedDynamic
                Return False
            End Function
P
Pilchie 已提交
599

600 601 602
            Public Function IsIndexerMemberCRef(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsIndexerMemberCRef
                Return False
            End Function
P
Pilchie 已提交
603

604 605 606
            Public Function GetContainingMemberDeclaration(root As SyntaxNode, position As Integer, Optional useFullSpan As Boolean = True) As SyntaxNode Implements ISyntaxFactsService.GetContainingMemberDeclaration
                Contract.ThrowIfNull(root, NameOf(root))
                Contract.ThrowIfTrue(position < 0 OrElse position > root.FullSpan.End, NameOf(position))
P
Pilchie 已提交
607

608 609 610 611 612
                Dim [end] = root.FullSpan.End
                If [end] = 0 Then
                    ' empty file
                    Return Nothing
                End If
P
Pilchie 已提交
613

614 615
                ' make sure position doesn't touch end of root
                position = Math.Min(position, [end] - 1)
P
Pilchie 已提交
616

617 618 619
                Dim node = root.FindToken(position).Parent
                While node IsNot Nothing
                    If useFullSpan OrElse node.Span.Contains(position) Then
P
Pilchie 已提交
620

621 622 623
                        If TypeOf node Is MethodBlockBaseSyntax AndAlso Not TypeOf node.Parent Is PropertyBlockSyntax Then
                            Return node
                        End If
P
Pilchie 已提交
624

625 626 627
                        If TypeOf node Is PropertyStatementSyntax AndAlso Not TypeOf node.Parent Is PropertyBlockSyntax Then
                            Return node
                        End If
P
Pilchie 已提交
628

629 630 631
                        If TypeOf node Is EventStatementSyntax AndAlso Not TypeOf node.Parent Is EventBlockSyntax Then
                            Return node
                        End If
P
Pilchie 已提交
632

633 634 635 636 637 638 639 640 641
                        If TypeOf node Is PropertyBlockSyntax OrElse
                           TypeOf node Is TypeBlockSyntax OrElse
                           TypeOf node Is EnumBlockSyntax OrElse
                           TypeOf node Is NamespaceBlockSyntax OrElse
                           TypeOf node Is EventBlockSyntax OrElse
                           TypeOf node Is FieldDeclarationSyntax Then
                            Return node
                        End If
                    End If
P
Pilchie 已提交
642

643 644
                    node = node.Parent
                End While
P
Pilchie 已提交
645

646 647
                Return Nothing
            End Function
P
Pilchie 已提交
648

649
            Public Function IsMethodLevelMember(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsMethodLevelMember
P
Pilchie 已提交
650

651 652 653 654
                ' Note: Derived types of MethodBaseSyntax are expanded explicitly, since PropertyStatementSyntax and
                ' EventStatementSyntax will NOT be parented by MethodBlockBaseSyntax.  Additionally, there are things
                ' like AccessorStatementSyntax and DelegateStatementSyntax that we never want to tread as method level
                ' members.
P
Pilchie 已提交
655

656
                If TypeOf node Is MethodStatementSyntax AndAlso Not TypeOf node.Parent Is MethodBlockBaseSyntax Then
657
                    Return True
P
Pilchie 已提交
658 659
                End If

660 661 662
                If TypeOf node Is SubNewStatementSyntax AndAlso Not TypeOf node.Parent Is MethodBlockBaseSyntax Then
                    Return True
                End If
P
Pilchie 已提交
663

664 665 666
                If TypeOf node Is OperatorStatementSyntax AndAlso Not TypeOf node.Parent Is MethodBlockBaseSyntax Then
                    Return True
                End If
667

668 669 670
                If TypeOf node Is PropertyStatementSyntax AndAlso Not TypeOf node.Parent Is PropertyBlockSyntax Then
                    Return True
                End If
671

672 673 674
                If TypeOf node Is EventStatementSyntax AndAlso Not TypeOf node.Parent Is EventBlockSyntax Then
                    Return True
                End If
675

676 677 678
                If TypeOf node Is DeclareStatementSyntax Then
                    Return True
                End If
679

680 681 682
                Return TypeOf node Is ConstructorBlockSyntax OrElse
                       TypeOf node Is MethodBlockSyntax OrElse
                       TypeOf node Is OperatorBlockSyntax OrElse
683
                       TypeOf node Is EventBlockSyntax OrElse
684 685 686 687 688 689 690 691 692
                       TypeOf node Is PropertyBlockSyntax OrElse
                       TypeOf node Is EnumMemberDeclarationSyntax OrElse
                       TypeOf node Is FieldDeclarationSyntax
            End Function

            Public Function GetMemberBodySpanForSpeculativeBinding(node As SyntaxNode) As TextSpan Implements ISyntaxFactsService.GetMemberBodySpanForSpeculativeBinding
                Dim member = GetContainingMemberDeclaration(node, node.SpanStart)
                If member Is Nothing Then
                    Return Nothing
P
Pilchie 已提交
693 694
                End If

695 696 697 698 699 700
                ' TODO: currently we only support method for now
                Dim method = TryCast(member, MethodBlockBaseSyntax)
                If method IsNot Nothing Then
                    If method.BlockStatement Is Nothing OrElse method.EndBlockStatement Is Nothing Then
                        Return Nothing
                    End If
P
Pilchie 已提交
701

702 703 704 705
                    ' We don't want to include the BlockStatement or any trailing trivia up to and including its statement
                    ' terminator in the span. Instead, we use the start of the first statement's leading trivia (if any) up
                    ' to the start of the EndBlockStatement. If there aren't any statements in the block, we use the start
                    ' of the EndBlockStatements leading trivia.
P
Pilchie 已提交
706

707 708 709 710
                    Dim firstStatement = method.Statements.FirstOrDefault()
                    Dim spanStart = If(firstStatement IsNot Nothing,
                                       firstStatement.FullSpan.Start,
                                       method.EndBlockStatement.FullSpan.Start)
711

712 713
                    Return TextSpan.FromBounds(spanStart, method.EndBlockStatement.SpanStart)
                End If
P
Pilchie 已提交
714 715

                Return Nothing
716
            End Function
P
Pilchie 已提交
717

718 719 720 721
            Public Function ContainsInMemberBody(node As SyntaxNode, span As TextSpan) As Boolean Implements ISyntaxFactsService.ContainsInMemberBody
                Dim method = TryCast(node, MethodBlockBaseSyntax)
                If method IsNot Nothing Then
                    Return method.Statements.Count > 0 AndAlso ContainsExclusively(GetSyntaxListSpan(method.Statements), span)
P
Pilchie 已提交
722 723
                End If

724 725 726 727
                Dim [event] = TryCast(node, EventBlockSyntax)
                If [event] IsNot Nothing Then
                    Return [event].Accessors.Count > 0 AndAlso ContainsExclusively(GetSyntaxListSpan([event].Accessors), span)
                End If
728

729 730 731 732
                Dim [property] = TryCast(node, PropertyBlockSyntax)
                If [property] IsNot Nothing Then
                    Return [property].Accessors.Count > 0 AndAlso ContainsExclusively(GetSyntaxListSpan([property].Accessors), span)
                End If
733

734 735 736 737
                Dim field = TryCast(node, FieldDeclarationSyntax)
                If field IsNot Nothing Then
                    Return field.Declarators.Count > 0 AndAlso ContainsExclusively(GetSeparatedSyntaxListSpan(field.Declarators), span)
                End If
P
Pilchie 已提交
738

739 740 741 742
                Dim [enum] = TryCast(node, EnumMemberDeclarationSyntax)
                If [enum] IsNot Nothing Then
                    Return [enum].Initializer IsNot Nothing AndAlso ContainsExclusively([enum].Initializer.Span, span)
                End If
P
Pilchie 已提交
743

744 745 746 747
                Dim propStatement = TryCast(node, PropertyStatementSyntax)
                If propStatement IsNot Nothing Then
                    Return propStatement.Initializer IsNot Nothing AndAlso ContainsExclusively(propStatement.Initializer.Span, span)
                End If
P
Pilchie 已提交
748

749 750
                Return False
            End Function
P
Pilchie 已提交
751

752 753 754 755
            Private Function ContainsExclusively(outerSpan As TextSpan, innerSpan As TextSpan) As Boolean
                If innerSpan.IsEmpty Then
                    Return outerSpan.Contains(innerSpan.Start)
                End If
P
Pilchie 已提交
756

757 758
                Return outerSpan.Contains(innerSpan)
            End Function
P
Pilchie 已提交
759

760 761 762 763
            Private Function GetSyntaxListSpan(Of T As SyntaxNode)(list As SyntaxList(Of T)) As TextSpan
                Contract.Requires(list.Count > 0)
                Return TextSpan.FromBounds(list.First.SpanStart, list.Last.Span.End)
            End Function
P
Pilchie 已提交
764

765 766 767 768
            Private Function GetSeparatedSyntaxListSpan(Of T As SyntaxNode)(list As SeparatedSyntaxList(Of T)) As TextSpan
                Contract.Requires(list.Count > 0)
                Return TextSpan.FromBounds(list.First.SpanStart, list.Last.Span.End)
            End Function
P
Pilchie 已提交
769

770 771 772 773 774
            Public Function GetMethodLevelMembers(root As SyntaxNode) As List(Of SyntaxNode) Implements ISyntaxFactsService.GetMethodLevelMembers
                Dim list = New List(Of SyntaxNode)()
                AppendMethodLevelMembers(root, list)
                Return list
            End Function
P
Pilchie 已提交
775

776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837
            Public Function IsTopLevelNodeWithMembers(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsTopLevelNodeWithMembers
                Return TypeOf node Is NamespaceBlockSyntax OrElse
                       TypeOf node Is TypeBlockSyntax OrElse
                       TypeOf node Is EnumBlockSyntax
            End Function

            Public Function TryGetDeclaredSymbolInfo(node As SyntaxNode, ByRef declaredSymbolInfo As DeclaredSymbolInfo) As Boolean Implements ISyntaxFactsService.TryGetDeclaredSymbolInfo
                Select Case node.Kind()
                    Case SyntaxKind.ClassBlock
                        Dim classDecl = CType(node, ClassBlockSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            classDecl.ClassStatement.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.Class, classDecl.ClassStatement.Identifier.Span,
                            GetInheritanceNames(classDecl))
                        Return True
                    Case SyntaxKind.ConstructorBlock
                        Dim constructor = CType(node, ConstructorBlockSyntax)
                        Dim typeBlock = TryCast(constructor.Parent, TypeBlockSyntax)
                        If typeBlock IsNot Nothing Then
                            declaredSymbolInfo = New DeclaredSymbolInfo(
                                typeBlock.BlockStatement.Identifier.ValueText,
                                GetContainerDisplayName(node.Parent),
                                GetFullyQualifiedContainerName(node.Parent),
                                DeclaredSymbolInfoKind.Constructor,
                                constructor.SubNewStatement.NewKeyword.Span,
                                ImmutableArray(Of String).Empty,
                                parameterCount:=CType(If(constructor.SubNewStatement.ParameterList?.Parameters.Count, 0), UShort))

                            Return True
                        End If
                    Case SyntaxKind.DelegateFunctionStatement, SyntaxKind.DelegateSubStatement
                        Dim delegateDecl = CType(node, DelegateStatementSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            delegateDecl.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.Delegate, delegateDecl.Identifier.Span,
                            ImmutableArray(Of String).Empty)
                        Return True
                    Case SyntaxKind.EnumBlock
                        Dim enumDecl = CType(node, EnumBlockSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            enumDecl.EnumStatement.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.Enum, enumDecl.EnumStatement.Identifier.Span,
                            ImmutableArray(Of String).Empty)
                        Return True
                    Case SyntaxKind.EnumMemberDeclaration
                        Dim enumMember = CType(node, EnumMemberDeclarationSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            enumMember.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.EnumMember, enumMember.Identifier.Span,
                            ImmutableArray(Of String).Empty)
                        Return True
                    Case SyntaxKind.EventStatement
                        Dim eventDecl = CType(node, EventStatementSyntax)
                        Dim eventParent = If(TypeOf node.Parent Is EventBlockSyntax, node.Parent.Parent, node.Parent)
838
                        declaredSymbolInfo = New DeclaredSymbolInfo(
839 840 841 842 843 844 845 846 847 848
                            eventDecl.Identifier.ValueText,
                            GetContainerDisplayName(eventParent),
                            GetFullyQualifiedContainerName(eventParent),
                            DeclaredSymbolInfoKind.Event, eventDecl.Identifier.Span,
                            ImmutableArray(Of String).Empty)
                        Return True
                    Case SyntaxKind.FunctionBlock, SyntaxKind.SubBlock
                        Dim funcDecl = CType(node, MethodBlockSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            funcDecl.SubOrFunctionStatement.Identifier.ValueText,
849 850
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
851 852
                            DeclaredSymbolInfoKind.Method,
                            funcDecl.SubOrFunctionStatement.Identifier.Span,
853
                            ImmutableArray(Of String).Empty,
854 855
                            parameterCount:=CType(If(funcDecl.SubOrFunctionStatement.ParameterList?.Parameters.Count, 0), UShort),
                            typeParameterCount:=CType(If(funcDecl.SubOrFunctionStatement.TypeParameterList?.Parameters.Count, 0), UShort))
856
                        Return True
857 858
                    Case SyntaxKind.InterfaceBlock
                        Dim interfaceDecl = CType(node, InterfaceBlockSyntax)
859
                        declaredSymbolInfo = New DeclaredSymbolInfo(
860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898
                            interfaceDecl.InterfaceStatement.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.Interface, interfaceDecl.InterfaceStatement.Identifier.Span,
                            GetInheritanceNames(interfaceDecl))
                        Return True
                    Case SyntaxKind.ModifiedIdentifier
                        Dim modifiedIdentifier = CType(node, ModifiedIdentifierSyntax)
                        Dim variableDeclarator = TryCast(modifiedIdentifier.Parent, VariableDeclaratorSyntax)
                        Dim fieldDecl = TryCast(variableDeclarator?.Parent, FieldDeclarationSyntax)
                        If fieldDecl IsNot Nothing Then
                            Dim kind = If(fieldDecl.Modifiers.Any(Function(m) m.Kind() = SyntaxKind.ConstKeyword),
                                DeclaredSymbolInfoKind.Constant,
                                DeclaredSymbolInfoKind.Field)
                            declaredSymbolInfo = New DeclaredSymbolInfo(
                                modifiedIdentifier.Identifier.ValueText,
                                GetContainerDisplayName(fieldDecl.Parent),
                                GetFullyQualifiedContainerName(fieldDecl.Parent),
                                kind, modifiedIdentifier.Identifier.Span,
                                ImmutableArray(Of String).Empty)
                            Return True
                        End If
                    Case SyntaxKind.ModuleBlock
                        Dim moduleDecl = CType(node, ModuleBlockSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            moduleDecl.ModuleStatement.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.Module, moduleDecl.ModuleStatement.Identifier.Span,
                            GetInheritanceNames(moduleDecl))
                        Return True
                    Case SyntaxKind.PropertyStatement
                        Dim propertyDecl = CType(node, PropertyStatementSyntax)
                        Dim propertyParent = If(TypeOf node.Parent Is PropertyBlockSyntax, node.Parent.Parent, node.Parent)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            propertyDecl.Identifier.ValueText,
                            GetContainerDisplayName(propertyParent),
                            GetFullyQualifiedContainerName(propertyParent),
                            DeclaredSymbolInfoKind.Property, propertyDecl.Identifier.Span,
899
                            ImmutableArray(Of String).Empty)
B
brettv 已提交
900
                        Return True
901 902 903 904 905 906 907 908 909 910
                    Case SyntaxKind.StructureBlock
                        Dim structDecl = CType(node, StructureBlockSyntax)
                        declaredSymbolInfo = New DeclaredSymbolInfo(
                            structDecl.StructureStatement.Identifier.ValueText,
                            GetContainerDisplayName(node.Parent),
                            GetFullyQualifiedContainerName(node.Parent),
                            DeclaredSymbolInfoKind.Struct, structDecl.StructureStatement.Identifier.Span,
                            GetInheritanceNames(structDecl))
                        Return True
                End Select
911

912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951
                declaredSymbolInfo = Nothing
                Return False
            End Function

            Private Function GetInheritanceNames(typeBlock As TypeBlockSyntax) As ImmutableArray(Of String)
                Dim builder = ImmutableArray.CreateBuilder(Of String)

                Dim aliasMap = GetAliasMap(typeBlock)
                Try
                    For Each inheritsStatement In typeBlock.Inherits
                        AddInheritanceNames(builder, inheritsStatement.Types, aliasMap)
                    Next

                    For Each implementsStatement In typeBlock.Implements
                        AddInheritanceNames(builder, implementsStatement.Types, aliasMap)
                    Next

                    Return builder.ToImmutable()
                Finally
                    FreeAliasMap(aliasMap)
                End Try
            End Function

            Private Function GetAliasMap(typeBlock As TypeBlockSyntax) As Dictionary(Of String, String)
                Dim compilationUnit = typeBlock.SyntaxTree.GetCompilationUnitRoot()

                Dim aliasMap As Dictionary(Of String, String) = Nothing
                For Each import In compilationUnit.Imports
                    For Each clause In import.ImportsClauses
                        If clause.IsKind(SyntaxKind.SimpleImportsClause) Then
                            Dim simpleImport = DirectCast(clause, SimpleImportsClauseSyntax)
                            If simpleImport.Alias IsNot Nothing Then
                                Dim mappedName = GetTypeName(simpleImport.Name)
                                If mappedName IsNot Nothing Then
                                    aliasMap = If(aliasMap, AllocateAliasMap())
                                    aliasMap(simpleImport.Alias.Identifier.ValueText) = mappedName
                                End If
                            End If
                        End If
                    Next
952 953
                Next

954 955
                Return aliasMap
            End Function
956

957 958 959 960
            Private Sub AddInheritanceNames(
                    builder As ImmutableArray(Of String).Builder,
                    types As SeparatedSyntaxList(Of TypeSyntax),
                    aliasMap As Dictionary(Of String, String))
961

962 963
                For Each typeSyntax In types
                    AddInheritanceName(builder, typeSyntax, aliasMap)
964
                Next
965
            End Sub
966

967 968 969 970 971 972 973
            Private Sub AddInheritanceName(
                    builder As ImmutableArray(Of String).Builder,
                    typeSyntax As TypeSyntax,
                    aliasMap As Dictionary(Of String, String))
                Dim name = GetTypeName(typeSyntax)
                If name IsNot Nothing Then
                    builder.Add(name)
974

975 976 977 978 979 980 981
                    Dim mappedName As String = Nothing
                    If aliasMap?.TryGetValue(name, mappedName) = True Then
                        ' Looks Like this could be an alias.  Also include the name the alias points to
                        builder.Add(mappedName)
                    End If
                End If
            End Sub
982

983 984 985 986 987
            Private Function GetTypeName(typeSyntax As TypeSyntax) As String
                If TypeOf typeSyntax Is SimpleNameSyntax Then
                    Return GetSimpleName(DirectCast(typeSyntax, SimpleNameSyntax))
                ElseIf TypeOf typeSyntax Is QualifiedNameSyntax Then
                    Return GetSimpleName(DirectCast(typeSyntax, QualifiedNameSyntax).Right)
988 989
                End If

990 991
                Return Nothing
            End Function
992

993 994 995
            Private Function GetSimpleName(simpleName As SimpleNameSyntax) As String
                Return simpleName.Identifier.ValueText
            End Function
996

997 998 999
            Private Function GetContainerDisplayName(node As SyntaxNode) As String
                Return GetDisplayName(node, DisplayNameOptions.IncludeTypeParameters)
            End Function
1000

1001 1002 1003
            Private Function GetFullyQualifiedContainerName(node As SyntaxNode) As String
                Return GetDisplayName(node, DisplayNameOptions.IncludeNamespaces)
            End Function
1004

1005
            Private Const s_dotToken As String = "."
1006

1007 1008 1009 1010
            Public Function GetDisplayName(node As SyntaxNode, options As DisplayNameOptions, Optional rootNamespace As String = Nothing) As String Implements ISyntaxFactsService.GetDisplayName
                If node Is Nothing Then
                    Return String.Empty
                End If
1011

1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022
                Dim pooled = PooledStringBuilder.GetInstance()
                Dim builder = pooled.Builder

                ' member keyword (if any)
                Dim memberDeclaration = TryCast(node, DeclarationStatementSyntax)
                If (options And DisplayNameOptions.IncludeMemberKeyword) <> 0 Then
                    Dim keywordToken = memberDeclaration.GetMemberKeywordToken()
                    If keywordToken <> Nothing AndAlso Not keywordToken.IsMissing Then
                        builder.Append(keywordToken.Text)
                        builder.Append(" "c)
                    End If
1023
                End If
1024 1025 1026 1027 1028 1029

                Dim names = ArrayBuilder(Of String).GetInstance()
                ' containing type(s)
                Dim parent = node.Parent
                While TypeOf parent Is TypeBlockSyntax
                    names.Push(GetName(parent, options, containsGlobalKeyword:=False))
1030 1031
                    parent = parent.Parent
                End While
1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043
                If (options And DisplayNameOptions.IncludeNamespaces) <> 0 Then
                    ' containing namespace(s) in source (if any)
                    Dim containsGlobalKeyword As Boolean = False
                    While parent IsNot Nothing AndAlso parent.Kind() = SyntaxKind.NamespaceBlock
                        names.Push(GetName(parent, options, containsGlobalKeyword))
                        parent = parent.Parent
                    End While
                    ' root namespace (if any)
                    If Not containsGlobalKeyword AndAlso Not String.IsNullOrEmpty(rootNamespace) Then
                        builder.Append(rootNamespace)
                        builder.Append(s_dotToken)
                    End If
1044
                End If
1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059
                While Not names.IsEmpty()
                    Dim name = names.Pop()
                    If name IsNot Nothing Then
                        builder.Append(name)
                        builder.Append(s_dotToken)
                    End If
                End While
                names.Free()

                ' name (include generic type parameters)
                builder.Append(GetName(node, options, containsGlobalKeyword:=False))

                ' parameter list (if any)
                If (options And DisplayNameOptions.IncludeParameters) <> 0 Then
                    builder.Append(memberDeclaration.GetParameterList())
1060
                End If
1061 1062 1063 1064 1065 1066 1067 1068

                ' As clause (if any)
                If (options And DisplayNameOptions.IncludeType) <> 0 Then
                    Dim asClause = memberDeclaration.GetAsClause()
                    If asClause IsNot Nothing Then
                        builder.Append(" "c)
                        builder.Append(asClause)
                    End If
1069
                End If
1070

1071 1072
                Return pooled.ToStringAndFree()
            End Function
1073

1074 1075
            Private Shared Function GetName(node As SyntaxNode, options As DisplayNameOptions, ByRef containsGlobalKeyword As Boolean) As String
                Const missingTokenPlaceholder As String = "?"
1076

1077 1078
                Select Case node.Kind()
                    Case SyntaxKind.CompilationUnit
1079
                        Return Nothing
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115
                    Case SyntaxKind.IdentifierName
                        Dim identifier = DirectCast(node, IdentifierNameSyntax).Identifier
                        Return If(identifier.IsMissing, missingTokenPlaceholder, identifier.Text)
                    Case SyntaxKind.IncompleteMember
                        Return missingTokenPlaceholder
                    Case SyntaxKind.NamespaceBlock
                        Dim nameSyntax = CType(node, NamespaceBlockSyntax).NamespaceStatement.Name
                        If nameSyntax.Kind() = SyntaxKind.GlobalName Then
                            containsGlobalKeyword = True
                            Return Nothing
                        Else
                            Return GetName(nameSyntax, options, containsGlobalKeyword)
                        End If
                    Case SyntaxKind.QualifiedName
                        Dim qualified = CType(node, QualifiedNameSyntax)
                        If qualified.Left.Kind() = SyntaxKind.GlobalName Then
                            containsGlobalKeyword = True
                            Return GetName(qualified.Right, options, containsGlobalKeyword) ' don't use the Global prefix if specified
                        Else
                            Return GetName(qualified.Left, options, containsGlobalKeyword) + s_dotToken + GetName(qualified.Right, options, containsGlobalKeyword)
                        End If
                End Select

                Dim name As String = Nothing
                Dim memberDeclaration = TryCast(node, DeclarationStatementSyntax)
                If memberDeclaration IsNot Nothing Then
                    Dim nameToken = memberDeclaration.GetNameToken()
                    If nameToken <> Nothing Then
                        name = If(nameToken.IsMissing, missingTokenPlaceholder, nameToken.Text)
                        If (options And DisplayNameOptions.IncludeTypeParameters) <> 0 Then
                            Dim pooled = PooledStringBuilder.GetInstance()
                            Dim builder = pooled.Builder
                            builder.Append(name)
                            AppendTypeParameterList(builder, memberDeclaration.GetTypeParameterList())
                            name = pooled.ToStringAndFree()
                        End If
1116 1117
                    End If
                End If
1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130
                Debug.Assert(name IsNot Nothing, "Unexpected node type " + node.Kind().ToString())
                Return name
            End Function

            Private Shared Sub AppendTypeParameterList(builder As StringBuilder, typeParameterList As TypeParameterListSyntax)
                If typeParameterList IsNot Nothing AndAlso typeParameterList.Parameters.Count > 0 Then
                    builder.Append("(Of ")
                    builder.Append(typeParameterList.Parameters(0).Identifier.Text)
                    For i = 1 To typeParameterList.Parameters.Count - 1
                        builder.Append(", ")
                        builder.Append(typeParameterList.Parameters(i).Identifier.Text)
                    Next
                    builder.Append(")"c)
P
Pilchie 已提交
1131
                End If
1132
            End Sub
P
Pilchie 已提交
1133

1134 1135 1136 1137 1138 1139
            Private Sub AppendMethodLevelMembers(node As SyntaxNode, list As List(Of SyntaxNode))
                For Each member In node.GetMembers()
                    If IsTopLevelNodeWithMembers(member) Then
                        AppendMethodLevelMembers(member, list)
                        Continue For
                    End If
P
Pilchie 已提交
1140

1141 1142 1143 1144 1145
                    If IsMethodLevelMember(member) Then
                        list.Add(member)
                    End If
                Next
            End Sub
P
Pilchie 已提交
1146

1147 1148
            Public Function GetMethodLevelMemberId(root As SyntaxNode, node As SyntaxNode) As Integer Implements ISyntaxFactsService.GetMethodLevelMemberId
                Contract.Requires(root.SyntaxTree Is node.SyntaxTree)
P
Pilchie 已提交
1149

1150 1151 1152
                Dim currentId As Integer = Nothing
                Dim currentNode As SyntaxNode = Nothing
                Contract.ThrowIfFalse(TryGetMethodLevelMember(root, Function(n, i) n Is node, currentId, currentNode))
P
Pilchie 已提交
1153

1154 1155
                Contract.ThrowIfFalse(currentId >= 0)
                CheckMemberId(root, node, currentId)
P
Pilchie 已提交
1156

1157 1158
                Return currentId
            End Function
1159

1160 1161 1162
            Public Function GetMethodLevelMember(root As SyntaxNode, memberId As Integer) As SyntaxNode Implements ISyntaxFactsService.GetMethodLevelMember
                Dim currentId As Integer = Nothing
                Dim currentNode As SyntaxNode = Nothing
P
Pilchie 已提交
1163

1164 1165 1166
                If Not TryGetMethodLevelMember(root, Function(n, i) i = memberId, currentId, currentNode) Then
                    Return Nothing
                End If
P
Pilchie 已提交
1167

1168 1169
                Contract.ThrowIfNull(currentNode)
                CheckMemberId(root, currentNode, memberId)
P
Pilchie 已提交
1170

1171 1172
                Return currentNode
            End Function
P
Pilchie 已提交
1173

1174 1175 1176 1177 1178 1179 1180 1181
            Private Function TryGetMethodLevelMember(node As SyntaxNode, predicate As Func(Of SyntaxNode, Integer, Boolean), ByRef currentId As Integer, ByRef currentNode As SyntaxNode) As Boolean
                For Each member In node.GetMembers()
                    If TypeOf member Is NamespaceBlockSyntax OrElse
                       TypeOf member Is TypeBlockSyntax OrElse
                       TypeOf member Is EnumBlockSyntax Then
                        If TryGetMethodLevelMember(member, predicate, currentId, currentNode) Then
                            Return True
                        End If
P
Pilchie 已提交
1182

1183
                        Continue For
P
Pilchie 已提交
1184 1185
                    End If

1186 1187 1188 1189 1190
                    If IsMethodLevelMember(member) Then
                        If predicate(member, currentId) Then
                            currentNode = member
                            Return True
                        End If
P
Pilchie 已提交
1191

1192 1193 1194
                        currentId = currentId + 1
                    End If
                Next
P
Pilchie 已提交
1195

1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219
                currentNode = Nothing
                Return False
            End Function

            <Conditional("DEBUG")>
            Private Sub CheckMemberId(root As SyntaxNode, node As SyntaxNode, memberId As Integer)
                Dim list = GetMethodLevelMembers(root)
                Dim index = list.IndexOf(node)
                Contract.ThrowIfFalse(index = memberId)
            End Sub

            Public Function GetBindableParent(token As SyntaxToken) As SyntaxNode Implements ISyntaxFactsService.GetBindableParent
                Dim node = token.Parent
                While node IsNot Nothing
                    Dim parent = node.Parent

                    ' If this node is on the left side of a member access expression, don't ascend
                    ' further or we'll end up binding to something else.
                    Dim memberAccess = TryCast(parent, MemberAccessExpressionSyntax)
                    If memberAccess IsNot Nothing Then
                        If memberAccess.Expression Is node Then
                            Exit While
                        End If
                    End If
P
Pilchie 已提交
1220

1221 1222 1223 1224 1225 1226 1227 1228
                    ' If this node is on the left side of a qualified name, don't ascend
                    ' further or we'll end up binding to something else.
                    Dim qualifiedName = TryCast(parent, QualifiedNameSyntax)
                    If qualifiedName IsNot Nothing Then
                        If qualifiedName.Left Is node Then
                            Exit While
                        End If
                    End If
P
Pilchie 已提交
1229

1230 1231 1232 1233 1234 1235 1236 1237
                    ' If this node is the type of an object creation expression, return the
                    ' object creation expression.
                    Dim objectCreation = TryCast(parent, ObjectCreationExpressionSyntax)
                    If objectCreation IsNot Nothing Then
                        If objectCreation.Type Is node Then
                            node = parent
                            Exit While
                        End If
P
Pilchie 已提交
1238 1239
                    End If

1240 1241 1242 1243
                    ' The inside of an interpolated string is treated as its own token so we
                    ' need to force navigation to the parent expression syntax.
                    If TypeOf node Is InterpolatedStringTextSyntax AndAlso TypeOf parent Is InterpolatedStringExpressionSyntax Then
                        node = parent
P
Pilchie 已提交
1244 1245 1246
                        Exit While
                    End If

1247 1248 1249
                    ' If this node is not parented by a name, we're done.
                    Dim name = TryCast(parent, NameSyntax)
                    If name Is Nothing Then
P
Pilchie 已提交
1250 1251 1252
                        Exit While
                    End If

1253
                    node = parent
1254 1255 1256 1257
                End While

                Return node
            End Function
1258

1259 1260 1261 1262
            Public Function GetConstructors(root As SyntaxNode, cancellationToken As CancellationToken) As IEnumerable(Of SyntaxNode) Implements ISyntaxFactsService.GetConstructors
                Dim compilationUnit = TryCast(root, CompilationUnitSyntax)
                If compilationUnit Is Nothing Then
                    Return SpecializedCollections.EmptyEnumerable(Of SyntaxNode)()
P
Pilchie 已提交
1263 1264
                End If

1265 1266 1267 1268
                Dim constructors = New List(Of SyntaxNode)()
                AppendConstructors(compilationUnit.Members, constructors, cancellationToken)
                Return constructors
            End Function
P
Pilchie 已提交
1269

1270 1271 1272
            Private Sub AppendConstructors(members As SyntaxList(Of StatementSyntax), constructors As List(Of SyntaxNode), cancellationToken As CancellationToken)
                For Each member As StatementSyntax In members
                    cancellationToken.ThrowIfCancellationRequested()
P
Pilchie 已提交
1273

1274 1275 1276 1277 1278
                    Dim constructor = TryCast(member, ConstructorBlockSyntax)
                    If constructor IsNot Nothing Then
                        constructors.Add(constructor)
                        Continue For
                    End If
P
Pilchie 已提交
1279

1280 1281 1282 1283
                    Dim [namespace] = TryCast(member, NamespaceBlockSyntax)
                    If [namespace] IsNot Nothing Then
                        AppendConstructors([namespace].Members, constructors, cancellationToken)
                    End If
P
Pilchie 已提交
1284

1285 1286 1287 1288
                    Dim [class] = TryCast(member, ClassBlockSyntax)
                    If [class] IsNot Nothing Then
                        AppendConstructors([class].Members, constructors, cancellationToken)
                    End If
P
Pilchie 已提交
1289

1290 1291 1292 1293 1294 1295
                    Dim [struct] = TryCast(member, StructureBlockSyntax)
                    If [struct] IsNot Nothing Then
                        AppendConstructors([struct].Members, constructors, cancellationToken)
                    End If
                Next
            End Sub
P
Pilchie 已提交
1296

1297 1298 1299 1300
            Public Function GetInactiveRegionSpanAroundPosition(tree As SyntaxTree, position As Integer, cancellationToken As CancellationToken) As TextSpan Implements ISyntaxFactsService.GetInactiveRegionSpanAroundPosition
                Dim trivia = tree.FindTriviaToLeft(position, cancellationToken)
                If trivia.Kind = SyntaxKind.DisabledTextTrivia Then
                    Return trivia.FullSpan
P
Pilchie 已提交
1301 1302
                End If

1303 1304
                Return Nothing
            End Function
P
Pilchie 已提交
1305

1306 1307 1308
            Public Function GetNameForArgument(argument As SyntaxNode) As String Implements ISyntaxFactsService.GetNameForArgument
                If TryCast(argument, ArgumentSyntax)?.IsNamed Then
                    Return DirectCast(argument, SimpleArgumentSyntax).NameColonEquals.Name.Identifier.ValueText
P
Pilchie 已提交
1309
                End If
1310

1311 1312
                Return String.Empty
            End Function
1313

1314 1315 1316
            Public Function IsLeftSideOfDot(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsLeftSideOfDot
                Return TryCast(node, ExpressionSyntax).IsLeftSideOfDot()
            End Function
1317

1318 1319 1320 1321
            Public Function GetRightSideOfDot(node As SyntaxNode) As SyntaxNode Implements ISyntaxFactsService.GetRightSideOfDot
                Return If(TryCast(node, QualifiedNameSyntax)?.Right,
                          TryCast(node, MemberAccessExpressionSyntax)?.Name)
            End Function
1322

1323 1324 1325
            Public Function IsLeftSideOfAssignment(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsLeftSideOfAssignment
                Return TryCast(node, ExpressionSyntax).IsLeftSideOfAnyAssignStatement
            End Function
1326

1327 1328 1329
            Public Function IsLeftSideOfAnyAssignment(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsLeftSideOfAnyAssignment
                Return TryCast(node, ExpressionSyntax).IsLeftSideOfAnyAssignStatement
            End Function
1330

1331 1332 1333
            Public Function GetRightHandSideOfAssignment(node As SyntaxNode) As SyntaxNode Implements ISyntaxFactsService.GetRightHandSideOfAssignment
                Return TryCast(node, AssignmentStatementSyntax)?.Right
            End Function
1334

1335 1336 1337
            Public Function IsInferredAnonymousObjectMemberDeclarator(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsInferredAnonymousObjectMemberDeclarator
                Return node.IsKind(SyntaxKind.InferredFieldInitializer)
            End Function
1338

1339 1340 1341
            Public Function IsOperandOfIncrementExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsOperandOfIncrementExpression
                Return False
            End Function
1342

1343 1344 1345
            Public Function IsOperandOfIncrementOrDecrementExpression(node As SyntaxNode) As Boolean Implements ISyntaxFactsService.IsOperandOfIncrementOrDecrementExpression
                Return False
            End Function
1346

1347 1348 1349
            Public Function GetContentsOfInterpolatedString(interpolatedString As SyntaxNode) As SyntaxList(Of SyntaxNode) Implements ISyntaxFactsService.GetContentsOfInterpolatedString
                Return (TryCast(interpolatedString, InterpolatedStringExpressionSyntax)?.Contents).Value
            End Function
1350

1351 1352 1353
            Public Function IsStringLiteral(token As SyntaxToken) As Boolean Implements ISyntaxFactsService.IsStringLiteral
                Return token.IsKind(SyntaxKind.StringLiteralToken)
            End Function
1354

1355 1356 1357
            Public Function GetArgumentsForInvocationExpression(invocationExpression As SyntaxNode) As SeparatedSyntaxList(Of SyntaxNode) Implements ISyntaxFactsService.GetArgumentsForInvocationExpression
                Return (TryCast(invocationExpression, InvocationExpressionSyntax)?.ArgumentList.Arguments).Value
            End Function
1358

1359 1360 1361 1362
            Public Function ConvertToSingleLine(node As SyntaxNode, Optional useElasticTrivia As Boolean = False) As SyntaxNode Implements ISyntaxFactsService.ConvertToSingleLine
                Return node.ConvertToSingleLine(useElasticTrivia)
            End Function
        End Class
1363

C
CyrusNajmabadi 已提交
1364
    End Class
1365

1366
End Namespace