VisualBasicCompletionService.vb 7.3 KB
Newer Older
1 2 3 4 5 6 7
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

Imports System.Collections.Immutable
Imports System.Composition
Imports System.Globalization
Imports System.Threading
Imports Microsoft.CodeAnalysis.Completion
M
Matt Warren 已提交
8
Imports Microsoft.CodeAnalysis.Completion.Providers
9 10 11 12
Imports Microsoft.CodeAnalysis.Host.Mef
Imports Microsoft.CodeAnalysis.Options
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Completion.Providers
13
Imports Microsoft.CodeAnalysis.VisualBasic.Completion.SuggestionMode
M
Matt Warren 已提交
14
Imports Microsoft.CodeAnalysis.Host
15 16

Namespace Microsoft.CodeAnalysis.VisualBasic.Completion
M
Matt Warren 已提交
17 18 19 20 21 22 23 24 25
    <ExportLanguageServiceFactory(GetType(CompletionService), LanguageNames.VisualBasic), [Shared]>
    Friend Class VisualBasicCompletionServiceFactory
        Implements ILanguageServiceFactory

        Public Function CreateLanguageService(languageServices As HostLanguageServices) As ILanguageService Implements ILanguageServiceFactory.CreateLanguageService
            Return New VisualBasicCompletionService(languageServices.WorkspaceServices.Workspace)
        End Function
    End Class

26
    Partial Friend Class VisualBasicCompletionService
M
Matt Warren 已提交
27
        Inherits CommonCompletionService
28

M
Matt Warren 已提交
29
        Private ReadOnly _completionProviders As ImmutableArray(Of CompletionProvider) = ImmutableArray.Create(Of CompletionProvider)(
30 31 32 33 34 35
            New KeywordCompletionProvider(),
            New SymbolCompletionProvider(),
            New ObjectInitializerCompletionProvider(),
            New ObjectCreationCompletionProvider(),
            New EnumCompletionProvider(),
            New NamedParameterCompletionProvider(),
36
            New VisualBasicSuggestionModeCompletionProvider(),
37 38 39 40
            New ImplementsClauseCompletionProvider(),
            New HandlesClauseCompletionProvider(),
            New PartialTypeCompletionProvider(),
            New CrefCompletionProvider(),
M
Matt Warren 已提交
41 42 43 44 45 46 47
            New CompletionListTagCompletionProvider(),
            New OverrideCompletionProvider(),
            New XmlDocCommentCompletionProvider()
        )

        Private ReadOnly _workspace As Workspace

C
CyrusNajmabadi 已提交
48 49 50
        Public Sub New(workspace As Workspace,
                       Optional exclusiveProviders As ImmutableArray(Of CompletionProvider) ? = Nothing)
            MyBase.New(workspace, exclusiveProviders)
M
Matt Warren 已提交
51 52 53 54 55 56 57 58
            _workspace = workspace
        End Sub

        Public Overrides ReadOnly Property Language As String
            Get
                Return LanguageNames.VisualBasic
            End Get
        End Property
59

M
Matt Warren 已提交
60 61 62 63 64 65 66 67 68 69 70 71
        Private Shared s_defaultCompletionRules As CompletionRules =
            CompletionRules.Create(
                dismissIfEmpty:=True,
                dismissIfLastCharacterDeleted:=True,
                defaultCommitCharacters:=CompletionRules.Default.DefaultCommitCharacters,
                defaultEnterKeyRule:=EnterKeyRule.Always)

        Public Overrides Function GetRules() As CompletionRules
            Return s_defaultCompletionRules
        End Function

        Protected Overrides Function GetBuiltInProviders() As ImmutableArray(Of CompletionProvider)
B
beep boop 已提交
72
            Return _completionProviders
73 74
        End Function

M
Matt Warren 已提交
75 76 77 78 79 80 81 82 83 84
        Protected Overrides Function GetProviders(roles As ImmutableHashSet(Of String), trigger As CompletionTrigger) As ImmutableArray(Of CompletionProvider)
            Dim _providers = MyBase.GetProviders(roles)

            If trigger.Kind = CompletionTriggerKind.Snippets Then
                _providers = _providers.Where(Function(p) p.IsSnippetProvider).ToImmutableArray()
            Else
                _providers = _providers.Where(Function(p) Not p.IsSnippetProvider).ToImmutableArray()
            End If

            Return _providers
85 86
        End Function

M
Matt Warren 已提交
87 88
        Protected Overrides Function GetBetterItem(item As CompletionItem, existingItem As CompletionItem) As CompletionItem
            ' If one Is a keyword, And the other Is some other item that inserts the same text as the keyword,
89 90
            ' keep the keyword (VB only), unless the other item is preselected
            If IsKeywordItem(existingItem) AndAlso existingItem.Rules.MatchPriority >= item.Rules.MatchPriority Then
M
Matt Warren 已提交
91
                Return existingItem
92 93
            End If

M
Matt Warren 已提交
94
            Return MyBase.GetBetterItem(item, existingItem)
95 96
        End Function

M
Matt Warren 已提交
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
        Protected Overrides Function ItemsMatch(item As CompletionItem, existingItem As CompletionItem) As Boolean
            If Not MyBase.ItemsMatch(item, existingItem) Then
                Return False
            End If

            ' DevDiv 957450 Normally, we want to show items with the same display text And
            ' different glyphs. That way, the we won't hide user - defined symbols that happen
            ' to match a keyword (Like Select). However, we want to avoid showing the keyword
            ' for an intrinsic right next to the item for the corresponding symbol. 
            ' Therefore, if a keyword claims to represent an "intrinsic" item, we'll ignore
            ' the glyph when matching.

            Dim keywordCompletionItem = If(IsKeywordItem(existingItem), existingItem, If(IsKeywordItem(item), item, Nothing))
            If keywordCompletionItem IsNot Nothing AndAlso keywordCompletionItem.Tags.Contains(CompletionTags.Intrinsic) Then
                Dim otherItem = If(keywordCompletionItem Is item, existingItem, item)
                Dim changeText = GetChangeText(otherItem)
                If changeText = keywordCompletionItem.DisplayText Then
                    Return True
                Else
                    Return False
                End If
            End If

            Return item.Tags = existingItem.Tags OrElse Enumerable.SequenceEqual(item.Tags, existingItem.Tags)
121 122
        End Function

M
Matt Warren 已提交
123 124 125 126 127 128 129 130 131 132 133
        Private Function GetChangeText(item As CompletionItem) As String
            Dim provider = TryCast(GetProvider(item), CommonCompletionProvider)
            If provider IsNot Nothing Then
                ' TODO: Document Is Not available in this code path.. what about providers that need to reconstruct information before producing text?
                Dim result = provider.GetTextChangeAsync(Nothing, item, Nothing, CancellationToken.None).Result
                If result IsNot Nothing Then
                    Return result.Value.NewText
                End If
            End If

            Return item.DisplayText
134 135
        End Function

M
Matt Warren 已提交
136 137 138
        Public Overrides Function GetDefaultItemSpan(text As SourceText, caretPosition As Integer) As TextSpan
            Return CompletionUtilities.GetCompletionItemSpan(text, caretPosition)
        End Function
139

M
Matt Warren 已提交
140 141
        Public Overrides Function ShouldTriggerCompletion(text As SourceText, position As Integer, trigger As CompletionTrigger, Optional roles As ImmutableHashSet(Of String) = Nothing, Optional options As OptionSet = Nothing) As Boolean
            options = If(options, _workspace.Options)
142

M
Matt Warren 已提交
143 144 145
            If Not options.GetOption(CompletionOptions.TriggerOnTyping, Me.Language) Then
                Return False
            End If
146

M
Matt Warren 已提交
147 148 149 150 151
            If trigger.Kind = CompletionTriggerKind.Deletion AndAlso (Char.IsLetterOrDigit(trigger.Character) OrElse trigger.Character = "."c) Then
                Return True
            Else
                Return MyBase.ShouldTriggerCompletion(text, position, trigger, roles, options)
            End If
152 153 154
        End Function
    End Class
End Namespace