1313using Microsoft . VisualStudio . Language . Intellisense . AsyncCompletion ;
1414using Microsoft . VisualStudio . Language . Intellisense . AsyncCompletion . Data ;
1515using Microsoft . VisualStudio . Text ;
16- using Microsoft . VisualStudio . Utilities ;
1716
18- namespace ChinesePinyinIntelliSenseExtender ;
17+ namespace ChinesePinyinIntelliSenseExtender . Completion . Async ;
1918
20- internal class PinyinAsyncCompletionSource : IAsyncCompletionSource
19+ internal class PinyinAsyncCompletionSource : CompletionSourceBase , IAsyncCompletionSource
2120{
2221 #region Private 字段
2322
2423 private static readonly CompletionFilter s_chineseFilter = new ( "中文代码" , "C" , new ( KnownMonikers . Attribute . ToImageId ( ) , "中文代码" ) ) ;
2524
2625 private static readonly ImmutableArray < CompletionFilter > s_chineseFilters = ImmutableArray . Create ( s_chineseFilter ) ;
2726
28- /// <summary>
29- /// <see cref="GetCompletionContextAsync(IAsyncCompletionSession, CompletionTrigger, SnapshotPoint, SnapshotSpan, CancellationToken)"/> 递归标记
30- /// </summary>
31- private static readonly AsyncLocal < bool > s_getCompletionContextRecursionTag = new ( ) ;
32-
33- private readonly GeneralOptions _options ;
3427 private readonly IEnumerable < IAsyncCompletionSource > _otherAsyncCompletionSources ;
35- private InputMethodDictionaryGroup ? _inputMethodDictionaryGroup ;
3628
3729 #endregion Private 字段
3830
3931 #region Public 构造函数
4032
4133 public PinyinAsyncCompletionSource ( IEnumerable < IAsyncCompletionSource > otherAsyncCompletionSources , GeneralOptions options )
34+ : base ( options )
4235 {
4336 _otherAsyncCompletionSources = otherAsyncCompletionSources ?? throw new ArgumentNullException ( nameof ( otherAsyncCompletionSources ) ) ;
44- _options = options ?? throw new ArgumentNullException ( nameof ( options ) ) ;
4537 }
4638
4739 #endregion Public 构造函数
@@ -50,32 +42,34 @@ public PinyinAsyncCompletionSource(IEnumerable<IAsyncCompletionSource> otherAsyn
5042
5143 public async Task < CompletionContext ? > GetCompletionContextAsync ( IAsyncCompletionSession session , CompletionTrigger trigger , SnapshotPoint triggerLocation , SnapshotSpan applicableToSpan , CancellationToken token )
5244 {
53- if ( s_getCompletionContextRecursionTag . Value
54- || ! _options . Enable )
45+ if ( CanNotProcess ( ) )
5546 {
5647 return null ;
5748 }
5849
5950 try
6051 {
61- s_getCompletionContextRecursionTag . Value = true ;
52+ s_completionContextRecursionTag . Value = true ;
6253
63- if ( _inputMethodDictionaryGroup is null
64- || _inputMethodDictionaryGroup . IsDisposed )
65- {
66- _inputMethodDictionaryGroup = await InputMethodDictionaryGroupProvider . GetAsync ( ) ;
67- }
54+ var getInputMethodDictionaryGroupTask = GetInputMethodDictionaryGroupAsync ( ) ;
6855
6956 var tasks = _otherAsyncCompletionSources . Select ( m => m . GetCompletionContextAsync ( session , trigger , triggerLocation , applicableToSpan , token ) ) . ToArray ( ) ;
7057
7158 await Task . WhenAll ( tasks ) ;
7259
7360 token . ThrowIfCancellationRequested ( ) ;
7461
75- Func < string , bool > shouldProcessCheckDelegate = StringPreMatchUtil . GetPreCheckPredicate ( _options . PreMatchType , _options . PreCheckRule ) ;
62+ Func < string , bool > shouldProcessCheckDelegate = StringPreMatchUtil . GetPreCheckPredicate ( Options . PreMatchType , Options . PreCheckRule ) ;
7663
7764 var allCompletionItems = tasks . SelectMany ( static m => m . Status == TaskStatus . RanToCompletion && m . Result ? . Items is not null ? m . Result . Items . AsEnumerable ( ) : Array . Empty < CompletionItem > ( ) ) ;
7865
66+ if ( ! allCompletionItems . Any ( ) )
67+ {
68+ return null ;
69+ }
70+
71+ var inputMethodDictionaryGroup = await getInputMethodDictionaryGroupTask ;
72+
7973 var count = tasks . Sum ( static m => m . Status == TaskStatus . RanToCompletion && m . Result ? . Items is not null ? m . Result . Items . Length : 0 ) ;
8074
8175 var itemBuffer = ArrayPool < CompletionItem > . Shared . Rent ( count * 5 ) ; //预留足够多的空间,避免字典过多导致的问题
@@ -84,7 +78,7 @@ public PinyinAsyncCompletionSource(IEnumerable<IAsyncCompletionSource> otherAsyn
8478 int bufferIndex = 0 ;
8579 allCompletionItems . AsParallel ( )
8680 . WithCancellation ( token )
87- . ForAll ( m => CreateCompletionItemWithConvertion ( m , shouldProcessCheckDelegate , itemBuffer , ref bufferIndex ) ) ;
81+ . ForAll ( m => CreateCompletionItemWithConvertion ( m , inputMethodDictionaryGroup , shouldProcessCheckDelegate , itemBuffer , ref bufferIndex ) ) ;
8882
8983 if ( bufferIndex > 0 )
9084 {
@@ -99,7 +93,7 @@ public PinyinAsyncCompletionSource(IEnumerable<IAsyncCompletionSource> otherAsyn
9993 }
10094 finally
10195 {
102- s_getCompletionContextRecursionTag . Value = false ;
96+ s_completionContextRecursionTag . Value = false ;
10397 }
10498 }
10599
@@ -125,7 +119,7 @@ public CompletionStartData InitializeCompletion(CompletionTrigger trigger, Snaps
125119
126120 #region impl
127121
128- private void CreateCompletionItemWithConvertion ( CompletionItem originCompletionItem , Func < string , bool > shouldProcessCheck , CompletionItem [ ] itemBuffer , ref int bufferIndex )
122+ private void CreateCompletionItemWithConvertion ( CompletionItem originCompletionItem , InputMethodDictionaryGroup inputMethodDictionaryGroup , Func < string , bool > shouldProcessCheck , CompletionItem [ ] itemBuffer , ref int bufferIndex )
129123 {
130124 var originInsertText = originCompletionItem . InsertText ;
131125
@@ -134,28 +128,28 @@ private void CreateCompletionItemWithConvertion(CompletionItem originCompletionI
134128 return ;
135129 }
136130
137- var spellings = _inputMethodDictionaryGroup ! . FindAll ( originInsertText ) ;
131+ var spellings = inputMethodDictionaryGroup . FindAll ( originInsertText ) ;
138132
139133 if ( spellings . Length == 0 )
140134 {
141135 return ;
142136 }
143137
144- if ( _options . EnableFSharpSupport
138+ if ( Options . EnableFSharpSupport
145139 && originCompletionItem . Properties . TryGetProperty ( "RoslynCompletionItemData" , out object data )
146140 && TryGetRoslynItemNameInCode ( data , out var nameInCode ) )
147141 {
148142 originInsertText = nameInCode ! ;
149143 }
150144
151- if ( _options . SingleWordsDisplay )
145+ if ( Options . SingleWordsDisplay )
152146 {
153147 foreach ( var spelling in spellings )
154148 {
155149 itemBuffer [ Interlocked . Increment ( ref bufferIndex ) - 1 ] = CreateCompletionItem ( originCompletionItem , originInsertText , spelling ) ;
156150 }
157151 }
158- else if ( _options . EnableMultipleSpellings )
152+ else if ( Options . EnableMultipleSpellings )
159153 {
160154 itemBuffer [ Interlocked . Increment ( ref bufferIndex ) - 1 ] = CreateCompletionItem ( originCompletionItem , originInsertText , string . Join ( "/" , spellings ) ) ;
161155 }
@@ -169,11 +163,11 @@ private void CreateCompletionItemWithConvertion(CompletionItem originCompletionI
169163
170164 private CompletionItem CreateCompletionItem ( CompletionItem originCompletionItem , string originInsertText , string spelling )
171165 {
172- var newCompletionItem = new CompletionItem ( displayText : Format ( _options . DisplayTextFormat , originCompletionItem . DisplayText , spelling ) ,
166+ var newCompletionItem = new CompletionItem ( displayText : FormatString ( Options . DisplayTextFormat , originCompletionItem . DisplayText , spelling ) ,
173167 source : this ,
174168 icon : originCompletionItem . Icon ,
175169 filters : s_chineseFilters ,
176- suffix : Format ( _options . DisplaySuffixFormat , originCompletionItem . Suffix , spelling ) ,
170+ suffix : FormatString ( Options . DisplaySuffixFormat , originCompletionItem . Suffix , spelling ) ,
177171 insertText : originInsertText ,
178172 sortText : spelling ,
179173 filterText : spelling ,
@@ -187,23 +181,6 @@ private CompletionItem CreateCompletionItem(CompletionItem originCompletionItem,
187181 newCompletionItem . Properties . AddProperty ( this , originCompletionItem ) ;
188182
189183 return newCompletionItem ;
190-
191- static string Format ( string ? format , string origin , string spellings )
192- {
193- if ( string . IsNullOrEmpty ( format ) )
194- {
195- return origin ;
196- }
197- var builder = PooledStringBuilder . GetInstance ( ) ;
198- try
199- {
200- return builder . Builder . AppendFormat ( format , origin , spellings ) . ToString ( ) ;
201- }
202- finally
203- {
204- builder . Free ( ) ;
205- }
206- }
207184 }
208185
209186 #endregion CreateCompletionItem
0 commit comments