Open Bug 1782681 Opened 3 years ago Updated 6 months ago

Provide type information for c++ auto type

Categories

(Webtools :: Searchfox, enhancement)

enhancement

Tracking

(Not tracked)

People

(Reporter: manuel, Unassigned)

References

Details

Attachments

(2 files)

Very much agreed! We do already have some of this information. As part of the "structured" landing I added "type" and "typesym" fields, but we currently don't emit any analysis data for the "auto" keywords, but we should. Also none of this is exposed to the UI.

The analysis data for line 258 for example:

for (auto it = aResponses.cbegin(); it != aResponses.cend(); ++it) {

looks like:

{"loc":"00258:12-14","source":1,"syntax":"","pretty":"variable it","sym":"V_1c6b00d16c3836dc_248795","no_crossref":1,"type":"nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator>::const_iterator","typesym":"T_mozilla::ArrayIterator"}
{"loc":"00258:17-27","source":1,"syntax":"","pretty":"variable aResponses","sym":"V_3a1e8bc16c3836dc_8450645e929df627","no_crossref":1,"type":"const nsTArray<struct mozilla::dom::cache::SavedResponse> &"}
{"loc":"00258:28-34","source":1,"syntax":"function,use","pretty":"function nsTArray_Impl::cbegin","sym":"_ZNK13nsTArray_Impl6cbeginEv","type":"nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator>::const_iterator","typesym":"T_mozilla::ArrayIterator"}
{"loc":"00258:38-40","source":1,"syntax":"","pretty":"variable it","sym":"V_1c6b00d16c3836dc_248795","no_crossref":1,"type":"nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator>::const_iterator","typesym":"T_mozilla::ArrayIterator"}
{"loc":"00258:41-43","source":1,"syntax":"function,use","pretty":"function mozilla::ArrayIterator::operator!=","sym":"_ZNK7mozilla13ArrayIteratorneERKNS_13ArrayIteratorIT_T0_EE","type":"_Bool"}
{"loc":"00258:44-54","source":1,"syntax":"","pretty":"variable aResponses","sym":"V_3a1e8bc16c3836dc_8450645e929df627","no_crossref":1,"type":"const nsTArray<struct mozilla::dom::cache::SavedResponse> &"}
{"loc":"00258:55-59","source":1,"syntax":"function,use","pretty":"function nsTArray_Impl::cend","sym":"_ZNK13nsTArray_Impl4cendEv","type":"nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator>::const_iterator","typesym":"T_mozilla::ArrayIterator"}
{"loc":"00258:63-65","source":1,"syntax":"function,use","pretty":"function mozilla::ArrayIterator::operator++","sym":"_ZN7mozilla13ArrayIteratorppEv","type":"mozilla::ArrayIterator<const struct mozilla::dom::cache::SavedResponse &, class nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator> >::iterator_type &"}
{"loc":"00258:65-67","source":1,"syntax":"","pretty":"variable it","sym":"V_1c6b00d16c3836dc_248795","no_crossref":1,"type":"nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator>::const_iterator","typesym":"T_mozilla::ArrayIterator"}

Which is to say we know that for "auto it" we have for "it" and ideally would have for "auto" as well (although it would be pretty/sym since the "auto" is a type, it doesn't have a type):

  • "type":"nsTArray_Impl<struct mozilla::dom::cache::SavedResponse, struct nsTArrayInfallibleAllocator>::const_iterator"
  • "typesym":"T_mozilla::ArrayIterator"

I think in practice the larger questions here are how to handle the UX issues arising:

  • For the UI I'd been thinking we could present the type in the super navigation/sidebar that we'll be adding soon on an opt-in basis. The types in question can become quite huge and placing them in the pop-up context menu ended up very unwieldy in "fancy" branch experiments.
  • The "auto" token actually packs a whole bunch of types inside of it; by our current convention for the above types we'd end up providing a context-menu that references 4 different types all on auto.
  • I've also discussed adding a toggle-able "glasses mode" where we could have searchfox expand "auto" to the underlying type, but the above type is an example where expanding naively would be quite bad for readability. It might be better to have separate presentation lines that aren't technically source lines, similar to how we might handle preprocessor expansions.

One alternative visualization approach to consider is to show the type names as "inlay hints".

This is a feature some editors have, and which was recently added to the Language Server Protocol, to show annotations inline in the code.

The attached screenshot shows the first code example from comment 0 in VSCode (with the clangd language server). You can see that it and headers have type hints next to them. (corpHeaderIt doesn't have one because clangd drops them past a certain length. Also, the type name in it's hint is not qualified, again in an attempt to control the length. This is definitely a downside of trying to show them inline.)

(Inlay hints have other applications as well besides auto, for example further down in the screenshot you can see them used to show the parameter names in the find_if() call.)

The inlay hint mechanism is what I was thinking of for "glasses mode" (and will use that appropriate term from hereon); I've found them extremely useful as provided by rust-analyzer when working on searchfox's rust code and it seems like thanks to VS Code this is probably a UX pattern people would be used to. The length issue is indeed the main one for me in VS Code as the rust code formatter in VS Code unfortunately does not format assuming the presence of the inlay hints and my editor layout doesn't leave much extra space beyond the 100 column marker because I have a tight 3-column layout. I think for searchfox usage people will tend to have extra columns of space, but it's a question of whether the super sidebar fights with that too much.

Searchfox does have the advantage that we have more control over the presentation. One could imagine trying something where when the type information would overflow the current line that we create a "line inlay" or "block inlay" where creates one or more lines that's visually distinct from the source lines but provides information about the types (or other meta-info). The idea of a "block inlay" would be that for a case where there would potentially be multiple line inlays that would cause distracting zebra-striping or redundant types, we hoist them into a consolidated block that could leverage hover highlighting/visual cues like matching emoji, etc. I don't think this would come up so much for this specific use case, but I think there are other searchfox features where it could be interesting to display inline meta-information. For example, https://www.visophyte.org/blog/2008/05/03/master-control-pecobro-the-overkill-performance-code-browser/ was an early project for me at MoMo that integrated profiler data with code listings. We could imagine interleaving Firefox Profiler data or pernosco trace data into source listings where having these synthetic lines/blocks as a UI convention could be useful.

I hadn't realized this was an explicit type for LSP (textDocument/inlayHint it looks like), but that makes sense and is great. I wonder if that's something the https://github.com/sourcegraph/scip will add as an explicit thing or if it's just something that gets automatically re-derived from the more explicit type information in the schema.

I'd completely forgotten that VS Code itself already does line inlays like shown here! Although what I was thinking of would probably be somewhat more in-your-face, maybe this is an example of an approach that would work because it already works. (Where that approach is to use a smaller line-height and gray colors.)

This probably best works for things where the smaller hit target doesn't matter because it would be rare that people would want to click on what's being displayed. The "N implementation(s)" approach also doesn't really require great readability because the "implementation" has low-entropy and the only real value of interest is N and the interesting thing is 0/1/few/many/tons. Having a very verbose type signature in a tiny font may not work as well. Although it's also the case that we would expect any super complex type signature to be drawing from a rather finite set of container/MFBT types that readers would (converge to) already have familiarity with.

See Also: → 1567464
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: