| File: Debugging\BreakpointResolver.vb | Web Access |
| Project: src\roslyn\src\Features\VisualBasic\Portable\Microsoft.CodeAnalysis.VisualBasic.Features.vbproj (Microsoft.CodeAnalysis.VisualBasic.Features) |
' 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.Threading Imports Microsoft.CodeAnalysis Imports Microsoft.CodeAnalysis.Collections Imports Microsoft.CodeAnalysis.Debugging Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Debugging Friend Class BreakpointResolver Inherits AbstractBreakpointResolver Private Shared ReadOnly s_identifierComparer As IEqualityComparer(Of String) = CaseInsensitiveComparison.Comparer Public Sub New(solution As Solution, text As String) MyBase.New(solution, text, LanguageNames.VisualBasic, s_identifierComparer) End Sub Protected Overrides Function GetMembers(type As INamedTypeSymbol, name As String) As IEnumerable(Of ISymbol) Dim members = type.GetMembers(name) Return If(s_identifierComparer.Equals(name, SyntaxFacts.GetText(SyntaxKind.NewKeyword)), members.Concat(type.Constructors), members) End Function Protected Overrides Function HasMethodBody(method As IMethodSymbol, cancellationToken As CancellationToken) As Boolean Dim location = method.Locations.First(Function(loc) loc.IsInSource) Dim tree = location.SourceTree Dim token = tree.GetRoot(cancellationToken).FindToken(location.SourceSpan.Start) Dim methodBlock = token.GetAncestor(Of MethodBlockBaseSyntax)() ' If there is no syntactic body then, obviously, False... If methodBlock Is Nothing Then Return False End If ' In VB, Partial method definitions have a syntactic body, but for the purpose of setting breakpoints in code, ' they should not be considered to have a body (because there is no executable code associated with them). If methodBlock.BlockStatement.Modifiers.Any(Function(t) t.IsKind(SyntaxKind.PartialKeyword)) Then Return False End If Return True End Function Protected Overrides Sub ParseText(ByRef nameParts As IList(Of NameAndArity), ByRef parameterCount As Integer?) Dim text As String = Me.Text Debug.Assert(text IsNot Nothing) Dim name = SyntaxFactory.ParseName(Me.Text, consumeFullText:=False) Dim lengthOfParsedText = name.FullSpan.End Dim parameterList = ParseParameterList(Me.Text, lengthOfParsedText) Dim foundIncompleteParameterList = False parameterCount = Nothing If parameterList IsNot Nothing Then If (parameterList.OpenParenToken.IsMissing OrElse parameterList.CloseParenToken.IsMissing) Then foundIncompleteParameterList = True Else lengthOfParsedText += parameterList.FullSpan.End parameterCount = parameterList.Parameters.Count End If End If ' It's not obvious, but this method can handle the case were name "IsMissing" (no suitable name was be parsed). Dim parts = name.GetNameParts() ' If we could not parse a valid parameter list or there was additional trailing text that could not be ' interpreted, don't return any names or parameters. ' Also, "Break at Function" doesn't seem to support names prefixed with "Global" with the old language service. ' Since it doesn't seem necessary to disambiguate symbols in this scenario (there's UI to do it), I'm going to ' explicitly ignore names with a Global namespace prefix. If we want to correctly support Global, we'd need to ' also modify the logic in FindMembersAsync to support exact matches on type name. "Global" prefixes on ' parameters will be accepted, but we still only validate parameter count (as the old implementation did). If Not foundIncompleteParameterList AndAlso (lengthOfParsedText = Me.Text.Length) AndAlso Not parts.Where(Function(p) p.IsKind(SyntaxKind.GlobalName)).Any() Then nameParts = parts.Cast(Of SimpleNameSyntax)().Select(Function(p) New NameAndArity(p.Identifier.ValueText, p.Arity)).ToList() Else nameParts = SpecializedCollections.EmptyList(Of NameAndArity)() End If End Sub ' TODO: This method can go away once https://roslyn.codeplex.com/workitem/231 is fixed. Private Shared Function ParseParameterList(text As String, offset As Integer) As ParameterListSyntax Return If(SyntaxFactory.ParseToken(text, offset).IsKind(SyntaxKind.OpenParenToken), SyntaxFactory.ParseParameterList(text, offset, consumeFullText:=False), Nothing) End Function End Class End Namespace