| File: Completion\KeywordRecommenders\Declarations\OfKeywordRecommender.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.Collections.Immutable Imports System.Threading Imports Microsoft.CodeAnalysis.Completion.Providers Imports Microsoft.CodeAnalysis.VisualBasic.Extensions.ContextQuery Imports Microsoft.CodeAnalysis.VisualBasic.Syntax Namespace Microsoft.CodeAnalysis.VisualBasic.Completion.KeywordRecommenders.Declarations Friend Class OfKeywordRecommender Inherits AbstractKeywordRecommender Protected Overrides Function RecommendKeywords(context As VisualBasicSyntaxContext, cancellationToken As CancellationToken) As ImmutableArray(Of RecommendedKeyword) If context.FollowsEndOfStatement Then Return ImmutableArray(Of RecommendedKeyword).Empty End If Dim targetToken = context.TargetToken If Not targetToken.IsKind(SyntaxKind.OpenParenToken) Then Return ImmutableArray(Of RecommendedKeyword).Empty End If Dim methodDeclaration = targetToken.GetAncestor(Of MethodStatementSyntax)() If methodDeclaration IsNot Nothing Then If methodDeclaration.TypeParameterList IsNot Nothing Then If targetToken = methodDeclaration.TypeParameterList.OpenParenToken Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If ElseIf methodDeclaration.ParameterList IsNot Nothing Then ' If we don't have a TypeParametersOpt, then we might be in a place where it's ambiguous where we are. ' For example, typing Sub Goo(|, it's not clear if that's a TypeParameters block I'm in or a regular ' block. The parser chooses the sane choice of calling that a regular parameters block until it knows ' otherwise. If targetToken = methodDeclaration.ParameterList.OpenParenToken Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If End If Dim implementsClause = targetToken.GetAncestor(Of ImplementsClauseSyntax) If implementsClause IsNot Nothing Then If targetToken.IsKind(SyntaxKind.OpenParenToken) AndAlso targetToken.Parent.IsKind(SyntaxKind.TypeArgumentList) Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If Dim inheritsStatement = targetToken.GetAncestor(Of InheritsStatementSyntax) If inheritsStatement IsNot Nothing Then If targetToken.IsKind(SyntaxKind.OpenParenToken) AndAlso targetToken.Parent.IsKind(SyntaxKind.TypeArgumentList) Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If Dim delegateDeclaration = targetToken.GetAncestor(Of DelegateStatementSyntax)() If delegateDeclaration IsNot Nothing Then If delegateDeclaration.TypeParameterList IsNot Nothing Then If targetToken = delegateDeclaration.TypeParameterList.OpenParenToken Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If ElseIf delegateDeclaration.ParameterList IsNot Nothing Then If targetToken = delegateDeclaration.ParameterList.OpenParenToken Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If End If Dim typeDeclaration = targetToken.GetAncestor(Of TypeStatementSyntax)() If typeDeclaration IsNot Nothing AndAlso typeDeclaration.IsKind(SyntaxKind.ClassStatement, SyntaxKind.InterfaceStatement, SyntaxKind.StructureStatement) Then If typeDeclaration.TypeParameterList IsNot Nothing Then If targetToken = typeDeclaration.TypeParameterList.OpenParenToken Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If End If ' Cases: ' Dim f As New Goo(| ' Goo(| Dim argumentList = targetToken.GetAncestor(Of ArgumentListSyntax)() If argumentList IsNot Nothing Then ' Ensure it's not "Dim F(|" unless creating a generic delegate If Not argumentList.HasAncestor(Of ModifiedIdentifierSyntax)() AndAlso targetToken = argumentList.OpenParenToken AndAlso (Not context.IsDelegateCreationContext() OrElse IsGenericDelegateCreationExpression(targetToken, context.SemanticModel, cancellationToken)) Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If ' Case: Dim f As Goo(| Dim arrayRankSpecifier = targetToken.GetAncestor(Of ArrayRankSpecifierSyntax)() If arrayRankSpecifier IsNot Nothing Then If targetToken = arrayRankSpecifier.OpenParenToken Then Dim arrayType = TryCast(arrayRankSpecifier.Parent, ArrayTypeSyntax) If arrayType IsNot Nothing AndAlso IsPartiallyTypedGenericName(arrayType.ElementType, context.SemanticModel) Then Return ImmutableArray.Create(New RecommendedKeyword("Of", VBFeaturesResources.Identifies_a_type_parameter_on_a_generic_class_structure_interface_delegate_or_procedure)) End If End If End If Return ImmutableArray(Of RecommendedKeyword).Empty End Function Private Shared Function IsPartiallyTypedGenericName(type As TypeSyntax, semanticModel As SemanticModel) As Boolean Dim symbols = semanticModel.LookupNamespacesAndTypes( position:=type.SpanStart, name:=type.ToString()) Return symbols.OfType(Of INamedTypeSymbol)() _ .Where(Function(nt) nt.IsGenericType) _ .Any() End Function Private Shared Function IsGenericDelegateCreationExpression(token As SyntaxToken, semanticModel As SemanticModel, cancellationToken As CancellationToken) As Boolean Dim objectCreationExpression = token.GetAncestor(Of ObjectCreationExpressionSyntax)() If objectCreationExpression IsNot Nothing Then Dim type = objectCreationExpression.Type If type IsNot Nothing Then Return semanticModel.LookupName(type, namespacesAndTypesOnly:=True, cancellationToken:=cancellationToken) _ .OfType(Of INamedTypeSymbol)() _ .Where(Function(nt) nt.IsDelegateType AndAlso nt.Arity > 0) _ .Any() End If End If Return False End Function End Class End Namespace