From 0361857c98e76a8b48698613ecc3c476ac0380c9 Mon Sep 17 00:00:00 2001 From: Balaji Soundrarajan Date: Wed, 8 Apr 2015 14:17:18 -0700 Subject: [PATCH] Visual Basic CodeModelService should handle Declare Function and Sub for StartPoint and EndPoint Fix #1839 : Visual Basic CodeModelService not handles Declare Function and Sub for StartPoint and EndPoint. --- .../VisualBasic/CodeFunctionTests.vb | 268 ++++++++++++++++++ ...VisualBasicCodeModelService.NodeLocator.vb | 72 +++++ 2 files changed, 340 insertions(+) diff --git a/src/VisualStudio/Core/Test/CodeModel/VisualBasic/CodeFunctionTests.vb b/src/VisualStudio/Core/Test/CodeModel/VisualBasic/CodeFunctionTests.vb index ab4da609d4a..1d848032bfe 100644 --- a/src/VisualStudio/Core/Test/CodeModel/VisualBasic/CodeFunctionTests.vb +++ b/src/VisualStudio/Core/Test/CodeModel/VisualBasic/CodeFunctionTests.vb @@ -76,6 +76,140 @@ End Class TextPoint(line:=2, lineOffset:=5, absoluteOffset:=25, lineLength:=31))) End Sub + + + Public Sub GetStartPoint_DeclareFunction_WithoutAttribute() + Dim code = + +Public Class C1 + Declare Function $$getUserName Lib "My1.dll" () As String +End Class + + + TestGetStartPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=2, lineOffset:=22, absoluteOffset:=38, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=59))) + End Sub + + + + Public Sub GetStartPoint_DeclareFunction_WithAttribute() + Dim code = + +Public Class C1 + <System.CLSCompliant(True)> + Declare Function $$getUserName Lib "My1.dll" () As String +End Class + + + TestGetStartPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=3, lineOffset:=22, absoluteOffset:=70, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31))) + End Sub + + + + Public Sub GetStartPoint_DeclareSub_WithoutAttribute() + Dim code = + +Public Class C1 + Public Declare Sub $$MethodName Lib "My1.dll" +End Class + + + TestGetStartPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=2, lineOffset:=24, absoluteOffset:=40, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=47))) + End Sub + + + + Public Sub GetStartPoint_DeclareSub_WithAttribute() + Dim code = + +Public Class C1 + <System.CLSCompliant(True)> + Public Declare Sub $$MethodName Lib "My1.dll" +End Class + + + TestGetStartPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=3, lineOffset:=24, absoluteOffset:=72, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=3, lineOffset:=5, absoluteOffset:=53, lineLength:=47)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=2, lineOffset:=5, absoluteOffset:=21, lineLength:=31))) + End Sub + #End Region #Region "GetEndPoint() tests" @@ -145,6 +279,140 @@ End Class TextPoint(line:=3, lineOffset:=25, absoluteOffset:=77, lineLength:=24))) End Sub + + + Public Sub GetEndPoint_DeclareFunction_WithoutAttribute() + Dim code = + +Public Class C1 + Declare Function $$getUserName Lib "My1.dll" () As String +End Class + + + TestGetEndPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=2, lineOffset:=33, absoluteOffset:=49, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=2, lineOffset:=60, absoluteOffset:=76, lineLength:=59))) + End Sub + + + + Public Sub GetEndPoint_DeclareFunction_WithAttribute() + Dim code = + +Public Class C1 + <System.CLSCompliant(True)> + Declare Function $$getUserName Lib "My1.dll" () As String +End Class + + + TestGetEndPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + TextPoint(line:=2, lineOffset:=32, absoluteOffset:=48, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + TextPoint(line:=2, lineOffset:=32, absoluteOffset:=48, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=3, lineOffset:=33, absoluteOffset:=81, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=3, lineOffset:=60, absoluteOffset:=108, lineLength:=59))) + End Sub + + + + Public Sub GetEndPoint_DeclareSub_WithoutAttribute() + Dim code = + +Public Class C1 + Declare Sub $$getUserName Lib "My1.dll" () +End Class + + + TestGetEndPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + NullTextPoint), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=2, lineOffset:=28, absoluteOffset:=44, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=2, lineOffset:=45, absoluteOffset:=61, lineLength:=44))) + End Sub + + + + Public Sub GetEndPoint_DeclareSub_WithAttribute() + Dim code = + +Public Class C1 + <System.CLSCompliant(True)> + Declare Sub $$getUserName Lib "My1.dll" () +End Class + + + TestGetEndPoint(code, + Part(EnvDTE.vsCMPart.vsCMPartAttributes, + TextPoint(line:=2, lineOffset:=32, absoluteOffset:=48, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter, + TextPoint(line:=2, lineOffset:=32, absoluteOffset:=48, lineLength:=31)), + Part(EnvDTE.vsCMPart.vsCMPartBody, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartHeader, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartName, + TextPoint(line:=3, lineOffset:=28, absoluteOffset:=76, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartNavigate, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartWhole, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44)), + Part(EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + TextPoint(line:=3, lineOffset:=45, absoluteOffset:=93, lineLength:=44))) + End Sub + #End Region #Region "Access tests" diff --git a/src/VisualStudio/VisualBasic/Impl/CodeModel/VisualBasicCodeModelService.NodeLocator.vb b/src/VisualStudio/VisualBasic/Impl/CodeModel/VisualBasicCodeModelService.NodeLocator.vb index 67f9a00c987..99f3e81ff22 100644 --- a/src/VisualStudio/VisualBasic/Impl/CodeModel/VisualBasicCodeModelService.NodeLocator.vb +++ b/src/VisualStudio/VisualBasic/Impl/CodeModel/VisualBasicCodeModelService.NodeLocator.vb @@ -71,6 +71,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel Return GetMethodStatementStartPoint(text, DirectCast(node, MethodStatementSyntax), part) End If + Case SyntaxKind.DeclareFunctionStatement, + SyntaxKind.DeclareSubStatement + Return GetDeclareStatementStartPoint(text, DirectCast(node, DeclareStatementSyntax), part) Case SyntaxKind.PropertyBlock Return GetPropertyBlockStartPoint(text, DirectCast(node, PropertyBlockSyntax), part) Case SyntaxKind.PropertyStatement @@ -158,6 +161,9 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel Return GetMethodStatementEndPoint(text, DirectCast(node, MethodStatementSyntax), part) End If + Case SyntaxKind.DeclareFunctionStatement, + SyntaxKind.DeclareSubStatement + Return GetDeclareStatementEndPoint(text, DirectCast(node, DeclareStatementSyntax), part) Case SyntaxKind.PropertyBlock Return GetPropertyBlockEndPoint(text, DirectCast(node, PropertyBlockSyntax), part) Case SyntaxKind.PropertyStatement @@ -501,6 +507,72 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel Return New VirtualTreePoint(methodBlock.SyntaxTree, text, startPosition) End Function + Private Function GetDeclareStatementStartPoint(text As SourceText, declareStatement As DeclareStatementSyntax, part As EnvDTE.vsCMPart) As VirtualTreePoint? + Dim startPosition As Integer + + Select Case part + Case EnvDTE.vsCMPart.vsCMPartName + startPosition = declareStatement.Identifier.SpanStart + + Case EnvDTE.vsCMPart.vsCMPartAttributes, + EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter + + Return GetAttributesStartPoint(text, declareStatement.AttributeLists, part) + + Case EnvDTE.vsCMPart.vsCMPartHeader, + EnvDTE.vsCMPart.vsCMPartWhole, + EnvDTE.vsCMPart.vsCMPartNavigate, + EnvDTE.vsCMPart.vsCMPartBody, + EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter + + If declareStatement.AttributeLists.Count > 0 Then + startPosition = declareStatement.AttributeLists.Last().GetLastToken().GetNextToken().SpanStart + Else + startPosition = declareStatement.SpanStart + End If + + Case EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + EnvDTE.vsCMPart.vsCMPartWholeWithAttributes + + startPosition = declareStatement.SpanStart + + Case Else + Throw Exceptions.ThrowEFail() + End Select + + Return New VirtualTreePoint(declareStatement.SyntaxTree, text, startPosition) + End Function + + + Private Function GetDeclareStatementEndPoint(text As SourceText, declareStatement As DeclareStatementSyntax, part As EnvDTE.vsCMPart) As VirtualTreePoint? + Dim endPosition As Integer + + Select Case part + Case EnvDTE.vsCMPart.vsCMPartName + endPosition = declareStatement.Identifier.Span.End + + Case EnvDTE.vsCMPart.vsCMPartAttributes, + EnvDTE.vsCMPart.vsCMPartAttributesWithDelimiter + + Return GetAttributesEndPoint(text, declareStatement.AttributeLists, part) + + Case EnvDTE.vsCMPart.vsCMPartHeaderWithAttributes, + EnvDTE.vsCMPart.vsCMPartWholeWithAttributes, + EnvDTE.vsCMPart.vsCMPartHeader, + EnvDTE.vsCMPart.vsCMPartWhole, + EnvDTE.vsCMPart.vsCMPartNavigate, + EnvDTE.vsCMPart.vsCMPartBody, + EnvDTE.vsCMPart.vsCMPartBodyWithDelimiter + + endPosition = declareStatement.Span.End + + Case Else + Throw Exceptions.ThrowEFail() + End Select + + Return New VirtualTreePoint(declareStatement.SyntaxTree, text, endPosition) + End Function + Private Function GetMethodStatementStartPoint(text As SourceText, methodStatement As MethodStatementSyntax, part As EnvDTE.vsCMPart) As VirtualTreePoint? Dim startPosition As Integer -- GitLab