Skip to content

Commit b385085

Browse files
bwilkersonCommit Queue
authored andcommitted
Document the computation of relevance
This is in response to a question asked on an issue with the goal of making it easier to find the answer in the future. Change-Id: If434a5e2cda36ba88af3cdf86276203472dca01a Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/443902 Reviewed-by: Samuel Rawlins <[email protected]> Commit-Queue: Brian Wilkerson <[email protected]>
1 parent c9c5be0 commit b385085

File tree

1 file changed

+57
-10
lines changed

1 file changed

+57
-10
lines changed

pkg/analysis_server/doc/implementation/code_completion.md

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ Code completion is supported in `.dart` files as well as in the `pubspec.yaml`,
1515
`analysis_options.yaml`, and `fix_data.yaml` files.
1616

1717
Dart completion suggestions are computed using the `DartCompletionManager` by
18-
invoking either the method `computeSuggestions` (for the legacy protocol) or
19-
`computeFinalizedCandidateSuggestions`. (The legacy protocol will be changed to
20-
use `computeFinalizedCandidateSuggestions` in the near future.)
18+
invoking the method `computeFinalizedCandidateSuggestions`.
19+
20+
### Completion passes
2121

2222
The completion manager computes suggestions in two "passes".
2323

@@ -29,6 +29,47 @@ The completion manager computes suggestions in two "passes".
2929
is skipped if there isn't time left in the `budget` or if there are already
3030
enough suggestions that the not-yet-imported elements wouldn't be sent anyway.
3131

32+
### The collector
33+
34+
Both passes add `CandidateSuggestion`s to a `SuggestionCollector`. The collector
35+
keeps a list of candidates and uses an insertion sort to keep the list sorted.
36+
The sorting is done based on how well the suggestion matches the completion
37+
prefix (as computed by the `FuzzyMatcher`).
38+
39+
For performance reasons, there is a limit to the number of suggestions that are
40+
passed back to the client. When there are more candidates in the list than what
41+
will be sent back, then any candidates whose match score is less than the score
42+
of any candidates within the window will be dropped from the list.
43+
44+
### Ranking
45+
46+
After the list of candidates has been computed, the candidates are ranked by the
47+
`RelevanceComputer`. They are then re-sorted based on the relevance and
48+
truncated to the maximum number of suggestions to be returned.
49+
50+
The relevance score is computed as follows. First, the `FeatureComputer` is used
51+
to measure certain features related to both the completion location and the
52+
suggestion. The features include such things as whether the type of the
53+
suggestion matches the context type, or how far from the completion location a
54+
local variable declaration is. Each feature is represented as a `double` between
55+
`-1.0` and `1.0` inclusive. The feature values are combined using a weighted
56+
average and then adjusted to be between `0` and `1000` inclusive.
57+
58+
The set of features used are selected based on a statistical analysis of
59+
representative Dart code. It is easy to find specific cases where the existing
60+
ranking algorithm does a poor job, but the requirement is that the ranking
61+
algorithm must be optimized across all use cases, not just one use case. This
62+
sometimes results in relevance scores that seem counter-intuitive. When that
63+
happens, one possible path to explore is to add a new feature to the mix.
64+
65+
Changes to either the set of features or the computation of a specific feature
66+
should only be done if a statistical analysis indicates that the change will
67+
produce a better overall ranking (as measured by the MRR of the suggestion
68+
compared to the actual selection). The tool in
69+
`analysis_server/tool/code_completion/completion_metrics.dart` can be used to
70+
compare the quality of one or more experiments compared to the current
71+
implementation.
72+
3273
## Maintaining and improving
3374

3475
The easiest way to fix bugs or add support for new features is to start by
@@ -40,14 +81,20 @@ When you have a test that's failing, add a breakpoint to
4081
`InScopeCompletionPass.computeSuggestions`. When the debugger stops at the
4182
breakpoint, hover over `_completionNode` to see what kind of node will be
4283
visited. Add a breakpoint in the corresponding visit method and resume
43-
execution. (If the visit method if it doesn't already exist, then add it and
44-
restart the debugger).
84+
execution. (If the visit method doesn't already exist, then add it and restart
85+
the debugger).
4586

4687
## New language features
4788

4889
If a new language feature is being introduced that adds new syntax, then code
49-
completion support will need to be updated. If the changes are limited to
50-
updating an existing node then you should be able to use the method above to
51-
update the corresponding visit method. If the changes required the addition of
52-
some new subclasses of `AstNode`, then you'll likely need to add a new visit
53-
method for the added nodes.
90+
completion support will need to be updated.
91+
92+
If the changes are limited to updating an existing node then you should be able
93+
to use the method above to update the corresponding visit method. If the changes
94+
required the addition of some new subclasses of `AstNode`, then you'll likely
95+
need to add a new visit method for the added nodes.
96+
97+
If the changes introduce a new kind of element then you might need to add a new
98+
subclass of `CandidateSuggestion` and update the `DeclarationHelper` to produce
99+
the suggestion under the appropriate conditions.
100+

0 commit comments

Comments
 (0)