/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Compilers/VisualBasic/Portable/Binding/DocumentationCommentCrefBinder_Compat.vb
456 строк
21 KB
AlekseyTs
Merge remote-tracking branch 'dotnet/master' into UsedAssemblies_13
24 янв 2020, 03:48
24 янв 2020, 03:48
5f06615
Код
Авторство
О чём код?
' 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.Collections.Immutable Imports Microsoft.CodeAnalysis.PooledObjects Imports Microsoft.CodeAnalysis.Text Imports Microsoft.CodeAnalysis.VisualBasic.Symbols Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Imports System.Runtime.InteropServices Namespace Microsoft.CodeAnalysis.VisualBasic Partial Friend NotInheritable Class DocumentationCommentCrefBinder Inherits DocumentationCommentBinder Private Shared Function CrefReferenceIsLegalForLegacyMode(nameFromCref As TypeSyntax) As Boolean Select Case nameFromCref.Kind Case SyntaxKind.QualifiedName, SyntaxKind.IdentifierName, SyntaxKind.GenericName, SyntaxKind.PredefinedType Return True Case Else Return False End Select End Function Private Function BindNameInsideCrefReferenceInLegacyMode(nameFromCref As TypeSyntax, preserveAliases As Boolean, <[In], Out> ByRef useSiteInfo As CompoundUseSiteInfo(Of AssemblySymbol)) As ImmutableArray(Of Symbol) ' This binding mode is used for cref-references without signatures and ' emulate Dev11 behavior If Not CrefReferenceIsLegalForLegacyMode(nameFromCref) Then Return ImmutableArray(Of Symbol).Empty End If ' The name which is either an upper-level (parent is the cref attribute) ' or is part of upper-level qualified name should be searched. All other ' names will be bound using regular BindType calls Dim name As VisualBasicSyntaxNode = nameFromCref.Parent While name IsNot Nothing And name.Kind <> SyntaxKind.CrefReference If name.Kind <> SyntaxKind.QualifiedName Then ' Not a top-level name or a top-level qualified name part Dim result As Symbol = If(preserveAliases, BindTypeOrAliasSyntax(nameFromCref, BindingDiagnosticBag.Discarded), BindTypeSyntax(nameFromCref, BindingDiagnosticBag.Discarded)) Return ImmutableArray.Create(Of Symbol)(result) End If name = name.Parent End While Debug.Assert(name IsNot Nothing) ' This is an upper-level name, we check is it has any ' diagnostics and if it does we return empty symbol set If nameFromCref.ContainsDiagnostics() Then Return ImmutableArray(Of Symbol).Empty End If Dim symbols = ArrayBuilder(Of Symbol).GetInstance() Select Case nameFromCref.Kind Case SyntaxKind.IdentifierName, SyntaxKind.GenericName BindSimpleNameForCref(DirectCast(nameFromCref, SimpleNameSyntax), symbols, preserveAliases, useSiteInfo, False) Case SyntaxKind.PredefinedType BindPredefinedTypeForCref(DirectCast(nameFromCref, PredefinedTypeSyntax), symbols) Case SyntaxKind.QualifiedName BindQualifiedNameForCref(DirectCast(nameFromCref, QualifiedNameSyntax), symbols, preserveAliases, useSiteInfo) Case Else Throw ExceptionUtilities.UnexpectedValue(nameFromCref.Kind) End Select RemoveOverriddenMethodsAndProperties(symbols) Return symbols.ToImmutableAndFree() End Function Private Sub BindQualifiedNameForCref(node As QualifiedNameSyntax, symbols As ArrayBuilder(Of Symbol), preserveAliases As Boolean, <[In], Out> ByRef useSiteInfo As CompoundUseSiteInfo(Of AssemblySymbol)) Dim allowColorColor As Boolean = True Dim left As NameSyntax = node.Left Select Case left.Kind Case SyntaxKind.IdentifierName, SyntaxKind.GenericName BindSimpleNameForCref(DirectCast(left, SimpleNameSyntax), symbols, preserveAliases, useSiteInfo, True) Case SyntaxKind.QualifiedName BindQualifiedNameForCref(DirectCast(left, QualifiedNameSyntax), symbols, preserveAliases, useSiteInfo) allowColorColor = False Case SyntaxKind.GlobalName symbols.Add(Me.Compilation.GlobalNamespace) Case Else Throw ExceptionUtilities.UnexpectedValue(left.Kind) End Select If symbols.Count <> 1 Then ' This is an error, we don't know what symbol to search for the right name ' It does not matter if the ambiguous symbols were actually found symbols.Clear() Return End If Dim singleSymbol As Symbol = symbols(0) symbols.Clear() ' We found one single symbol, we need to search for the 'right' ' name in the context of this symbol Dim right As SimpleNameSyntax = node.Right If right.Kind = SyntaxKind.GenericName Then ' Generic name Dim genericName = DirectCast(right, GenericNameSyntax) BindSimpleNameForCref(genericName.Identifier.ValueText, genericName.TypeArgumentList.Arguments.Count, symbols, preserveAliases, useSiteInfo, containingSymbol:=singleSymbol, allowColorColor:=allowColorColor) If symbols.Count <> 1 Then ' Don't do any construction in case nothing was found or ' there is ambiguity Return End If symbols(0) = ConstructGenericSymbolWithTypeArgumentsForCref(symbols(0), genericName) Else ' Simple identifier name Debug.Assert(right.Kind = SyntaxKind.IdentifierName) Dim identifierName As String = DirectCast(right, IdentifierNameSyntax).Identifier.ValueText ' Search for 0 arity first BindSimpleNameForCref(identifierName, 0, symbols, preserveAliases, useSiteInfo, containingSymbol:=singleSymbol, allowColorColor:=allowColorColor) If symbols.Count > 0 Then Return End If ' Search with any arity, if we find the single result, it is going to be ' selected as the right one, otherwise we will return ambiguous result BindSimpleNameForCref(identifierName, -1, symbols, preserveAliases, useSiteInfo, containingSymbol:=singleSymbol, allowColorColor:=allowColorColor) End If End Sub Private Sub LookupSimpleNameInContainingSymbol(containingSymbol As Symbol, allowColorColor As Boolean, name As String, arity As Integer, preserveAliases As Boolean, lookupResult As LookupResult, options As LookupOptions, <[In], Out> ByRef useSiteInfo As CompoundUseSiteInfo(Of AssemblySymbol)) lAgain: Select Case containingSymbol.Kind Case SymbolKind.Namespace LookupMember(lookupResult, DirectCast(containingSymbol, NamespaceSymbol), name, arity, options, useSiteInfo) Case SymbolKind.Alias If Not preserveAliases Then containingSymbol = DirectCast(containingSymbol, AliasSymbol).Target GoTo lAgain End If Case SymbolKind.NamedType, SymbolKind.ArrayType LookupMember(lookupResult, DirectCast(containingSymbol, TypeSymbol), name, arity, options, useSiteInfo) Case SymbolKind.Property If allowColorColor Then ' Check for Color Color case Dim [property] = DirectCast(containingSymbol, PropertySymbol) Dim propertyType As TypeSymbol = [property].Type If IdentifierComparison.Equals([property].Name, propertyType.Name) Then containingSymbol = propertyType GoTo lAgain End If End If Case SymbolKind.Field If allowColorColor Then ' Check for Color Color case Dim field = DirectCast(containingSymbol, FieldSymbol) Dim fieldType As TypeSymbol = field.Type If IdentifierComparison.Equals(field.Name, fieldType.Name) Then containingSymbol = fieldType GoTo lAgain End If End If Case SymbolKind.Method If allowColorColor Then ' Check for Color Color case Dim method = DirectCast(containingSymbol, MethodSymbol) If Not method.IsSub Then Dim returnType As TypeSymbol = method.ReturnType If IdentifierComparison.Equals(method.Name, returnType.Name) Then containingSymbol = returnType GoTo lAgain End If End If End If Case Else ' Nothing can be found in context of these symbols End Select End Sub Private Sub BindSimpleNameForCref(name As String, arity As Integer, symbols As ArrayBuilder(Of Symbol), preserveAliases As Boolean, <[In], Out> ByRef useSiteInfo As CompoundUseSiteInfo(Of AssemblySymbol), Optional containingSymbol As Symbol = Nothing, Optional allowColorColor As Boolean = False, Optional typeOrNamespaceOnly As Boolean = False) Debug.Assert(Not String.IsNullOrEmpty(name)) If String.IsNullOrEmpty(name) Then ' Return an empty symbol collection in error scenario Return End If Dim options = LookupOptions.UseBaseReferenceAccessibility Or LookupOptions.MustNotBeReturnValueVariable Or LookupOptions.IgnoreExtensionMethods Or LookupOptions.MustNotBeLocalOrParameter Or LookupOptions.NoSystemObjectLookupForInterfaces Or LookupOptions.IgnoreAccessibility If arity < 0 Then options = options Or LookupOptions.AllMethodsOfAnyArity End If If typeOrNamespaceOnly Then options = options Or LookupOptions.NamespacesOrTypesOnly End If Dim lookupResult As LookupResult = LookupResult.GetInstance() If containingSymbol Is Nothing Then Me.Lookup(lookupResult, name, arity, options, useSiteInfo) Else LookupSimpleNameInContainingSymbol(containingSymbol, allowColorColor, name, arity, preserveAliases, lookupResult, options, useSiteInfo) End If If Not lookupResult.IsGoodOrAmbiguous OrElse Not lookupResult.HasSymbol Then lookupResult.Free() Return End If CreateGoodOrAmbiguousFromLookupResultAndFree(lookupResult, symbols, preserveAliases) End Sub Private Sub BindSimpleNameForCref(node As SimpleNameSyntax, symbols As ArrayBuilder(Of Symbol), preserveAliases As Boolean, <[In], Out> ByRef useSiteInfo As CompoundUseSiteInfo(Of AssemblySymbol), typeOrNamespaceOnly As Boolean) ' Name syntax of Cref should not have diagnostics If node.ContainsDiagnostics Then ' Return an empty symbol collection in case there is any syntax diagnostics Return End If If node.Kind = SyntaxKind.GenericName Then ' Generic name Dim genericName = DirectCast(node, GenericNameSyntax) BindSimpleNameForCref(genericName.Identifier.ValueText, genericName.TypeArgumentList.Arguments.Count, symbols, preserveAliases, useSiteInfo, typeOrNamespaceOnly:=typeOrNamespaceOnly) If symbols.Count <> 1 Then ' Don't do any construction in case nothing was found or there is an ambiguity Return End If symbols(0) = ConstructGenericSymbolWithTypeArgumentsForCref(symbols(0), genericName) Else ' Simple identifier name Debug.Assert(node.Kind = SyntaxKind.IdentifierName) Dim identifier As SyntaxToken = DirectCast(node, IdentifierNameSyntax).Identifier Dim identifierName As String = identifier.ValueText ' Search for 0 arity first BindSimpleNameForCref(identifierName, 0, symbols, preserveAliases, useSiteInfo, typeOrNamespaceOnly:=typeOrNamespaceOnly) If symbols.Count > 0 Then Return End If ' Search with any arity, if we find the single result, it is going to be ' selected as the right one, otherwise we will return ambiguous result BindSimpleNameForCref(identifierName, -1, symbols, preserveAliases, useSiteInfo, typeOrNamespaceOnly:=typeOrNamespaceOnly) End If End Sub Private Sub BindPredefinedTypeForCref(node As PredefinedTypeSyntax, symbols As ArrayBuilder(Of Symbol)) ' Name syntax of Cref should not have diagnostics If node.ContainsDiagnostics Then ' Return an empty symbol collection in case there is any syntax diagnostics Return End If Dim type As SpecialType Select Case node.Keyword.Kind Case SyntaxKind.ObjectKeyword type = SpecialType.System_Object Case SyntaxKind.BooleanKeyword type = SpecialType.System_Boolean Case SyntaxKind.DateKeyword type = SpecialType.System_DateTime Case SyntaxKind.CharKeyword type = SpecialType.System_Char Case SyntaxKind.StringKeyword type = SpecialType.System_String Case SyntaxKind.DecimalKeyword type = SpecialType.System_Decimal Case SyntaxKind.ByteKeyword type = SpecialType.System_Byte Case SyntaxKind.SByteKeyword type = SpecialType.System_SByte Case SyntaxKind.UShortKeyword type = SpecialType.System_UInt16 Case SyntaxKind.ShortKeyword type = SpecialType.System_Int16 Case SyntaxKind.UIntegerKeyword type = SpecialType.System_UInt32 Case SyntaxKind.IntegerKeyword type = SpecialType.System_Int32 Case SyntaxKind.ULongKeyword type = SpecialType.System_UInt64 Case SyntaxKind.LongKeyword type = SpecialType.System_Int64 Case SyntaxKind.SingleKeyword type = SpecialType.System_Single Case SyntaxKind.DoubleKeyword type = SpecialType.System_Double Case Else Throw ExceptionUtilities.UnexpectedValue(node.Keyword.Kind) End Select ' We discard diagnostics in case symbols.Add(Me.GetSpecialType(type, node, BindingDiagnosticBag.Discarded)) End Sub Private Function ConstructGenericSymbolWithTypeArgumentsForCref(genericSymbol As Symbol, genericName As GenericNameSyntax) As Symbol Select Case genericSymbol.Kind Case SymbolKind.Method Dim method = DirectCast(genericSymbol, MethodSymbol) Debug.Assert(method.Arity = genericName.TypeArgumentList.Arguments.Count) Return method.Construct(BingTypeArgumentsForCref(genericName.TypeArgumentList.Arguments)) Case SymbolKind.NamedType, SymbolKind.ErrorType Dim type = DirectCast(genericSymbol, NamedTypeSymbol) Debug.Assert(type.Arity = genericName.TypeArgumentList.Arguments.Count) Return type.Construct(BingTypeArgumentsForCref(genericName.TypeArgumentList.Arguments)) Case SymbolKind.Alias Dim [alias] = DirectCast(genericSymbol, AliasSymbol) Return ConstructGenericSymbolWithTypeArgumentsForCref([alias].Target, genericName) Case Else Throw ExceptionUtilities.UnexpectedValue(genericSymbol.Kind) End Select End Function Private Function BingTypeArgumentsForCref(args As SeparatedSyntaxList(Of TypeSyntax)) As ImmutableArray(Of TypeSymbol) Dim result(args.Count - 1) As TypeSymbol For i = 0 To args.Count - 1 result(i) = Me.BindTypeSyntax(args(i), BindingDiagnosticBag.Discarded) Next Return result.AsImmutableOrNull() End Function Private Shared Sub CreateGoodOrAmbiguousFromLookupResultAndFree(lookupResult As LookupResult, result As ArrayBuilder(Of Symbol), preserveAliases As Boolean) Dim di As DiagnosticInfo = lookupResult.Diagnostic If TypeOf di Is AmbiguousSymbolDiagnostic Then ' Several ambiguous symbols wrapped in 'AmbiguousSymbolDiagnostic' Debug.Assert(lookupResult.Kind = LookupResultKind.Ambiguous) Debug.Assert(lookupResult.Symbols.Count = 1) Dim symbols As ImmutableArray(Of Symbol) = DirectCast(di, AmbiguousSymbolDiagnostic).AmbiguousSymbols Debug.Assert(symbols.Length > 1) If preserveAliases Then result.AddRange(symbols) Else For Each sym In symbols result.Add(UnwrapAlias(sym)) Next End If Else If preserveAliases Then result.AddRange(lookupResult.Symbols) Else For Each sym In lookupResult.Symbols result.Add(sym.UnwrapAlias()) Next End If End If lookupResult.Free() End Sub End Class End Namespace