问题
I'm looking at Roslyn's CompletionService, and ShouldTriggerCompletion
is defined as
public virtual bool ShouldTriggerCompletion(
SourceText text,
int caretPosition,
CompletionTrigger trigger,
ImmutableHashSet<string> roles = null,
OptionSet options = null
) { … }
where CompletionTrigger
is a wrapper for a single char Character
.
This seems to imply I should call ShouldTriggerCompletion
on each char when typing — however that would mean I need to update SourceText
on each char, which allocates an array of TextChange
, a new SourceText
and potentially other things depending on its internal structure.
Do I understand this API correctly? What is the most efficient way to use it when typing?
Edit: To clarify, I know I can second-guess it and only call it for let's say .
. But my goal is to use the API the way it is intended to be used, without any optimizations other than those already provided.
回答1:
however that would mean I need to update SourceText on each char, which allocates an array of TextChange, a new SourceText and potentially other things depending on its internal structure
Yes, on each keystroke in Visual Studio we create a new SourceText and a new Document/Project/Solution snapshot. We have to do it since all features are depending on that Document instance existing.
For us, such an operation is cheap. The text editor component in Visual Studio already creates a cheap ITextSnapshot
for each edit, which it does via very fancy data structures (think binary trees of pieces of strings) so this is as cheap as it can be. When we create SourceTexts for files in the editor, we instead create our own derived type of SourceText and we just forward the requests for data to the editor ITextSnapshot
API. It's not a coincidence that SourceText has effectively a subset of ITextSnapshot
's members, because we were designing for precisely this pattern!
回答2:
It depends what you're trying to do.
If you are certain you know the completion triggers for your text, you can avoid having to call ShouldTriggerCompletion
by triggering completion yourself whenever you think it's appropriate. But premature optimization isn't a good reason to reimplement it yourself. (You'll break compatibility with the other assemblies playing in the Roslyn sandbox; you might miss an edge case; you won't get upgrades when the language is upgraded; etc.)
Also, if you're the caller, you probably shouldn't invoke ShouldTriggerCompletion
directly: GetCompletionsAsync
seems more likely to be what you want.
来源:https://stackoverflow.com/questions/39421668/whats-the-most-efficient-way-to-use-roslyns-completionsevice-when-typing