From 198b167bc4d7ecb4b38599131467fffdc5187429 Mon Sep 17 00:00:00 2001 From: David Poeschl Date: Mon, 3 Aug 2015 10:51:07 -0700 Subject: [PATCH] Fix VB TypeInferrer after ArgumentList Fixes #3518 When trying to figure out which Argument of an ArgumentList was being inferred, we found the index and then returned "(index + 1) \ 2" without checking if the index was out of bounds. When the index is out of bounds its value is -1, so the above expression results in an index of 0, and the rest of the system continues as though we're really trying to infer the type of the first Argument (but really, the token we've passed is the close paren for the entire invocation). --- ...ompletionListTagCompletionProviderTests.vb | 27 +++++++++++++++++++ .../TypeInferrer/TypeInferrerTests.vb | 15 +++++++++++ ...lBasicTypeInferenceService.TypeInferrer.vb | 15 ++++++++++- 3 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/CompletionListTagCompletionProviderTests.vb b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/CompletionListTagCompletionProviderTests.vb index 089c81cfdce..97f316ca70f 100644 --- a/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/CompletionListTagCompletionProviderTests.vb +++ b/src/EditorFeatures/VisualBasicTest/Completion/CompletionProviders/CompletionListTagCompletionProviderTests.vb @@ -368,6 +368,33 @@ End Class VerifyNoItemsExist(markup) End Sub + + + Public Sub NotAfterInvocationWithCompletionListTagTypeAsFirstParameter() + Dim markup = +Public Class Type1 +End Class + +Public Class Type2 + Public Shared A As Type1 + Public Shared B As Type1 +End Class +]]>.Value + VerifyNoItemsExist(markup) + End Sub + + Friend Overrides Function CreateCompletionProvider() As CompletionListProvider Return New CompletionListTagCompletionProvider() End Function diff --git a/src/EditorFeatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb b/src/EditorFeatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb index 113826d1195..601d2d605bb 100644 --- a/src/EditorFeatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb +++ b/src/EditorFeatures/VisualBasicTest/TypeInferrer/TypeInferrerTests.vb @@ -710,5 +710,20 @@ Module M End Module" Test(text, "Global.System.Threading.Tasks.Task(Of System.Boolean)", testPosition:=True) End Sub + + + + Public Sub NoTypeAfterInvocationWithCompletionListTagTypeAsFirstParameter() + Dim text = "Class C + Sub Test() + M(5) + [|x|] + End Sub + + Sub M(x As Integer) + End Sub +End Class" + Test(text, "System.Object", testNode:=False, testPosition:=True) + End Sub End Class End Namespace diff --git a/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb b/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb index adfa5ba390b..74601db1858 100644 --- a/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb +++ b/src/Workspaces/VisualBasic/Portable/LanguageServices/VisualBasicTypeInferenceService.TypeInferrer.vb @@ -217,6 +217,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic index = GetArgumentListIndex(argumentList, previousToken) End If + If index < 0 Then + Return SpecializedCollections.EmptyEnumerable(Of ITypeSymbol)() + End If + Dim info = _semanticModel.GetSymbolInfo(invocation) ' Check all the methods that have at least enough arguments to support being ' called with argument at this position. Note: if they're calling an extension @@ -259,6 +263,11 @@ Namespace Microsoft.CodeAnalysis.VisualBasic Else index = GetArgumentListIndex(argumentList, previousToken) End If + + If index < 0 Then + Return SpecializedCollections.EmptyEnumerable(Of ITypeSymbol)() + End If + Dim constructors = namedType.InstanceConstructors.Where(Function(m) m.Parameters.Length > index) Return InferTypeInArgument(argumentOpt, index, constructors) End If @@ -279,6 +288,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic index = GetArgumentListIndex(argumentList, previousToken) End If + If index < 0 Then + Return SpecializedCollections.EmptyEnumerable(Of ITypeSymbol)() + End If + Dim info = _semanticModel.GetSymbolInfo(attribute) Dim symbols = info.GetBestOrAllSymbols() If symbols.Any() Then @@ -838,7 +851,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic End If Dim index = argumentList.Arguments.GetWithSeparators().IndexOf(previousToken) - Return (index + 1) \ 2 + Return If(index >= 0, (index + 1) \ 2, -1) End Function Private Function InferTypeInCollectionInitializerExpression( -- GitLab