提交 6d058848 编写于 作者: D Dustin Campbell

Fix Code Model's GetTypeFromFullName to better handle situations where...

Fix Code Model's GetTypeFromFullName to better handle situations where unsupported name formats are passed

`GetTypeFromFullName` first attempts to treat the specified type name as a metadata name. Failing
that, it parses the type name and tries to speculatively bind it. However, it was entirely possible
that a type name could be provided that we don't support, such as an assembly-qualified name. So, we
now check to see if the parsed type name includes an skipped token trivia (e.g. a trailing "Foo, 0.0.0.0")
and does not attempt to bind in that case. Otherwise, speculative binding could return something
non-sensical.
上级 673a6de4
......@@ -3027,6 +3027,15 @@ public override ITypeSymbol GetTypeSymbolFromFullName(string fullName, Compilati
{
var parsedTypeName = SyntaxFactory.ParseTypeName(fullName);
// Check to see if the name we parsed has any skipped text. If it does, don't bother trying to
// speculatively bind it because we'll likely just get the wrong thing since we found a bunch
// of non-sensical tokens.
if (parsedTypeName.ContainsSkippedText)
{
return null;
}
// If we couldn't get the name, we just grab the first tree in the compilation to
// speculatively bind at position zero. However, if there *aren't* any trees, we fork the
// compilation with an empty tree for the purposes of speculative binding.
......
......@@ -28,7 +28,7 @@ class Foo { }
#End Region
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestDotNetNameFromLanguageSpecific() As Task
Public Async Function TestDotNetNameFromLanguageSpecific1() As Task
Dim code =
<code>
using N.M;
......@@ -49,6 +49,23 @@ namespace N
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestDotNetNameFromLanguageSpecific2() As Task
Await TestRootCodeModelWithCodeFile(<code></code>,
Sub(rootCodeModel)
Dim dotNetName = rootCodeModel.DotNetNameFromLanguageSpecific("System.Collections.Generic.List<int>")
Assert.Equal("System.Collections.Generic.List`1[System.Int32]", dotNetName)
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestDotNetNameFromLanguageSpecificWithAssemblyQualifiedName() As Task
Await TestRootCodeModelWithCodeFile(<code></code>,
Sub(rootCodeModel)
Assert.Throws(Of ArgumentException)(Sub() rootCodeModel.DotNetNameFromLanguageSpecific("System.Collections.Generic.List<int>, mscorlib"))
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestExternalNamespaceChildren() As Task
Dim code =
......
......@@ -231,7 +231,7 @@ End Namespace
#End Region
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestDotNetNameFromLanguageSpecific() As Task
Public Async Function TestDotNetNameFromLanguageSpecific1() As Task
Dim code =
<code>
Imports N.M
......@@ -251,6 +251,23 @@ End Namespace
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestDotNetNameFromLanguageSpecific2() As Task
Await TestRootCodeModelWithCodeFile(<code></code>,
Sub(rootCodeModel)
Dim dotNetName = rootCodeModel.DotNetNameFromLanguageSpecific("System.Collections.Generic.List(Of Integer)")
Assert.Equal("System.Collections.Generic.List`1[System.Int32]", dotNetName)
End Sub)
End Function
<ConditionalWpfFact(GetType(x86)), Trait(Traits.Feature, Traits.Features.CodeModel)>
Public Async Function TestDotNetNameFromLanguageSpecificWithAssemblyQualifiedName() As Task
Await TestRootCodeModelWithCodeFile(<code></code>,
Sub(rootCodeModel)
Assert.Throws(Of ArgumentException)(Sub() rootCodeModel.DotNetNameFromLanguageSpecific("System.Collections.Generic.List(Of Integer), mscorlib"))
End Sub)
End Function
Protected Overrides ReadOnly Property LanguageName As String
Get
Return LanguageNames.VisualBasic
......
......@@ -3564,6 +3564,21 @@ Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.CodeModel
If typeSymbol Is Nothing Then
Dim parsedTypeName = SyntaxFactory.ParseTypeName(fullName)
' Check to see if the name we parsed has any skipped text. If it does, don't bother trying to
' speculatively bind it because we'll likely just get the wrong thing since we found a bunch
' of non-sensical tokens.
' NOTE: There appears to be a VB parser issue where "ContainsSkippedText" does not return true
' even when there is clearly skipped token trivia present. We work around this by for a particularly
' common case by checking whether the trailing trivia contains any skipped token trivia.
' https://github.com/dotnet/roslyn/issues/7182 has been filed for the parser issue.
If parsedTypeName.ContainsSkippedText OrElse
parsedTypeName.GetTrailingTrivia().Any(SyntaxKind.SkippedTokensTrivia) Then
Return Nothing
End If
' If we couldn't get the name, we just grab the first tree in the compilation to
' speculatively bind at position zero. However, if there *aren't* any trees, we fork the
' compilation with an empty tree for the purposes of speculative binding.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册