-
Notifications
You must be signed in to change notification settings - Fork 69
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug 1533802 - Sticky nesting for C , Rust, JS r=kats #212
Conversation
4590db2
to
84e59c0
Compare
91c55b6
to
d4934e1
Compare
So this seems to be sufficiently working for C /Rust/JS. As noted in the commit message (and which I've updated into the root comment), the rust stuff is pretty hacky but I didn't see any other immediately available options. I'll try and spin a new dev run now so I know how to do that. |
And I'll stop force-pushing from here on out. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(I've mostly looked at the rust bits so far)
Thanks for all the rust feedback! I'm still very much at the "cargo cult what I see in the existing code and randomly google for what I don't see", so I deeply appreciate the feedback. (Also, apologies for all the beginner mistakes. I have the Blandy/Orendorff book, but have clearly not gotten very far into it. Arguably it would have been wiser to take some time at the start of the rust indexing delve in order to level up my understanding and decrease my stumbling.) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks pretty good overall! I didn't review rust-indexer.rs in too much detail since it looks like Emilio already did. Most comments are just nits, I think the only functional ones are for merging the source lines properly, and gracefully handling missing source files.
11cef54
to
a6c2649
Compare
Okay, so now there are 2 parts: part 1 is running rustfmt on only the rust code I end up touching and part 2 is just my changes (with rustfmt run again afterwards). I'm going to try and do the dev.searchfox.org thing now (or get it started)> |
I'm pretty sure I fixed everything here and I think all my blatant force-pushing confused the github UI. (Or the use of the atom editor to resolve items.)
…emilio This implements position: sticky display of lines for "source" analysis lines for which we have a "nestingRange" available. Support for emitting "nestingRange" is added to the C (clang), Rust, and JS analyzer logic. However, the Rust analyzer changes are very limited because the "save-analysis" data which forms the basis of the Rust analysis is extremely limited. It effectively already is being provided with the result of an analysis pass which has had all AST information stripped away. There did not seem to be any readily available mechanism in the "RLS" to attempt to reconstitute an AST and relate it to the analysis data. The best hack I was able to come up with was to attempt to recursively build up a span covering all of the 'def' children of a 'def' or an 'impl'. This means that nesting for rust is largely limited to "struct" definitions and for inherent "impl" blocks, with the nestingRange only covering up until the start of the last "fn" in the "impl".
a6c2649
to
5d9e71f
Compare
So sadly this didn't work because the update script that checks out the repo assumes your github clone is called "mozsearch" and not "searchfox"
I'll shut down the indexer and file a bug to fix this. |
Thanks for investigating this and fixing the underlying issue! Your strong ownership of and professionalism on searchfox (/ mozsearch ;) are inspiring. |
When I refactored the nesting_range to point at the braces, I forgot to update the formatting logic that decides when to push a symbol onto the nesting stack. As a result, symbols would only be pushed when the opening brace was on the same line as the symbol. Now we only require that the opening brace doesn't happen before the symbol.
@staktrace @emilio So there's a clean run up at https://dev.searchfox.org/ now where the C looks very good, the JS looks good[1], and the rust is better than nothing. It looks like my "impl" hack isn't working, so I'll iterate on that, potentially adding another commit and triggering another "dev" channel re-indexing when I do. I do think we'll need to pursue explicitly enhancing the save-analysis stuff to include significantly more AST info before the rust stuff is actually useful. 1: https://dev.searchfox.org/mozilla-central/source/browser/modules/Sanitizer.jsm#46 should have Sanitizer be sticky. |
I just tried it out on some C code and it does indeed work pretty well. Then I went to nsTArray.h and found some weirdness... if you to e.g. https://dev.searchfox.org/mozilla-central/rev/94c6b5f06d2464f6780a52f32e917d25ddc30d6b/xpcom/ds/nsTArray.h#1692 there's a whole stack of declarations that are still stuck even though they shouldn't be. |
(Maybe because the function at https://dev.searchfox.org/mozilla-central/rev/94c6b5f06d2464f6780a52f32e917d25ddc30d6b/xpcom/ds/nsTArray.h#2391 is declared and implemented separately in the same file and we're unioning the ranges?) |
I see the sticky line half-under the search bar. The search bar is a bit higher than the CSS variable. The hard-coded pixel value will also likely not play well with any kind of zoom. |
…fix it. This allows us to stop manually offsetting the "position: sticky" lines to compensate for the header, which was not reliable using px (and I didn't want to get into things like rem/etc. or dynamic sizing using JS). The only real downside to this is that the scrollbar no longer goes to the top of the content area, but I'm not sure that's a downside.
tl;dr: The nestingRange is being emitted for declarations when it should only be emitted for definitions and the emission isn't sanity checking that the range is in the same file. I think the union logic is probably right in general, but because we use the "loc" as the start of the region for nesting and only require that the nestingRange.start is >= loc, when we erroneously tie the nestingRange to a declaration even in the same file, we effectively end up unioning the ranges. (This was a change I made so that the nestingRange could point at the braces for cool feature creep purposes, which changed our constraints in format.rs.) I will make sure we only emit nestingRange if the "source" we're emitting is the definition instance. I'll also add defensive sanity-checking that the loc and nestingRange are in the same file. InvestigationAside: Holy cow, so "wc -l nsTArray.h" for the analysis says there are 1,936,965 lines in there. Which makes sense because we have target entries for every permutation of T for Grepping that down to just "source" lines shows that we indeed then union all of those permutations into a single "source" which is very hard to scroll through. Installing "jq" and then doing Looking at |
We already had range validation for PeekRange, so we can just reuse that for NestingRange. I ensured that the range validation protected us from the cross-file glitch on its own before adding the definition check.
Update some documentation and the help.html to aid in this not happening again.
So the other variation I'm trying to deal with now is that nsTArray.h:1337 template <class Item, typename ActualAlloc = Alloc>
elem_type* ReplaceElementsAt(index_type aStart, size_type aCount,
const Item* aArray, size_type aArrayLen); is turning into {"loc":"01337:13-30","pretty":"function nsTArray_Impl::ReplaceElementsAt","syntax":"decl,def,function","nestingRange":"2207:18-2222:0"} as produced via So presumably we're merging "source" entries that have syntax values of "decl,function" and "def,function". The clang indexer can't actually output a syntax of "decl,def,function" on its own that I'm aware of. I've been trying to re-create the problem in big_header.h after seeing the import list at the top of nsTArray.h and deciding adding nsTArray.h to the test repo was not going to be sufficiently straightforward. Oh, and here's the direct clang ast-dump of the header (aka not through a build system):
|
Okay, managed to reproduce the following non-merged analysis output: {"loc":"00064:12-52","source":1,"nestingRange":"81:35-89:0","syntax":"def,function","pretty":"function WhatsYourVector_impl::forwardDeclaredTemplateThingInlinedBelow","sym":"_ZN20WhatsYourVector_impl40forwardDeclaredTemplateThingInlinedBelowEPKT_"}
{"loc":"00064:12-52","source":1,"syntax":"decl,function","pretty":"function WhatsYourVector_impl::forwardDeclaredTemplateThingInlinedBelow","sym":"_ZN20WhatsYourVector_impl40forwardDeclaredTemplateThingInlinedBelowEPKT_"}
{"loc":"00064:12-52","source":1,"syntax":"decl,function","pretty":"function WhatsYourVector_impl::forwardDeclaredTemplateThingInlinedBelow","sym":"_ZN20WhatsYourVector_implIN7outerNS5HumanE9CoolAllocE40forwardDeclaredTemplateThingInlinedBelowEPKT_"}
{"loc":"00064:12-52","source":1,"syntax":"decl,function","pretty":"function WhatsYourVector_impl::forwardDeclaredTemplateThingInlinedBelow","sym":"_ZN20WhatsYourVector_implIN7outerNS9SuperheroE9CoolAllocE40forwardDeclaredTemplateThingInlinedBelowEPKT_"} From the following mess. Interestingly, the decl's are somewhat superfluous, although obviously the def is the unexpected, no good, very bad type definition: class CoolAlloc {
public:
static void ChewGumAndAllocateMemory() {
// nom nom nom
}
};
template <class T>
class JokeBase {
int walkIntoBar() {
int i = 0;
return i--;
}
};
template <class T, class Alloc>
class WhatsYourVector_impl
: public JokeBase<T> {
public:
typedef T* elem_type;
elem_type mStorage;
WhatsYourVector_impl(elem_type thing)
: mStorage(thing) {
}
int forwardDeclaredThingInlinedBelow();
template <class Item, typename ActualAlloc = Alloc>
elem_type forwardDeclaredTemplateThingInlinedBelow(
const Item* aThing);
};
template <class T, class Alloc>
int WhatsYourVector_impl<T, Alloc>::forwardDeclaredThingInlinedBelow() {
int i = 0;
i ;
i--;
return i;
}
template <typename T, class Alloc>
template <class Item, typename ActualAlloc>
auto WhatsYourVector_impl<T, Alloc>::forwardDeclaredTemplateThingInlinedBelow(
const Item* aThing) -> elem_type {
int i = 0;
if (aThing) {
i ;
}
i--;
ActualAlloc::ChewGumAndAllocateMemory();
return mStorage;
}
template <class T>
class WhatsYourVector: public WhatsYourVector_impl<T, CoolAlloc> {
public:
typedef T* elem_type;
WhatsYourVector(elem_type thing)
: WhatsYourVector_impl<T, CoolAlloc>(thing) {
}
}; |
And here's what the AST excerpt for that looks like:
compare with the AST for its non-template friend just above it:
|
… nesting purposes. See discussion in the pull request, but in general the situation this addresses is: - A template method is declared (on a templated class, not sure if that matters.) - The actual body of the template method is outside the template class definition. While normal humans like myself think of that body as the point of definition... - When the template gets instantiated, clang generates a CXXMethodDecl at the point of declaration that looks entirely like a definition. (And all of the source locations reference the sane-human body location, which is semantically discontinuous from the location of the template method declaration.)
That seems to have done it locally, I'm starting the try server dance. |
@staktrace @emilio Okay, the try server dance was successful. nsTArray.h now looks fine, in particular the example line :kats gave of https://dev.searchfox.org/mozilla-central/source/xpcom/ds/nsTArray.h#1692 I addressed the searchbar positioning issues by changing from using position: fixed to using flexbox and have tested it in Firefox on linux/os x/windows and it seems fine with that and zoom used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly skimming the additional changes, and playing around with the dev deployment, everything looks good. I'm happy to merge this unless @emilio has comments
static/css/mozsearch.css
Outdated
* positions for each nested sticky level, and it was hard to know for sure how | ||
* big the search box would actually be without involving JS. | ||
* | ||
* So our solition is to use flexbox to create a non-scrolling fixed-header, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: solition
clang-plugin/MozsearchIndexer.cpp
Outdated
// - This is a definition AND | ||
// - This isn't a template instantiation. Function templates' | ||
// instantiations can end up as a definition with a Loc at their point | ||
// of declaration but with the CompountStmt of the template's |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: CompountStmt
In preparation for landing, I've prepared https://phabricator.services.mozilla.com/D33701 to include the clang indexer changes. While it would potentially be cool to uplift it to branches other than nightly, in practice, we don't have to because the only schema change was to add the nestingRange. No nestingRange means no nesting. We can uplift as appropriate, although if older branches don't use clang 8 maybe they will get sad. |
These are the changes from mozsearch/mozsearch#212 (including the typo fixes requested today. Differential Revision: https://phabricator.services.mozilla.com/D33701 --HG-- extra : moz-landing-system : lando
These are the changes from mozsearch/mozsearch#212 (including the typo fixes requested today. Differential Revision: https://phabricator.services.mozilla.com/D33701
These are the changes from mozsearch/mozsearch#212 (including the typo fixes requested today. Differential Revision: https://phabricator.services.mozilla.com/D33701 UltraBlame original commit: 0342dc8a3781dbb73501802c83aa5cfdf4c548a2
These are the changes from mozsearch/mozsearch#212 (including the typo fixes requested today. Differential Revision: https://phabricator.services.mozilla.com/D33701 UltraBlame original commit: 0342dc8a3781dbb73501802c83aa5cfdf4c548a2
These are the changes from mozsearch/mozsearch#212 (including the typo fixes requested today. Differential Revision: https://phabricator.services.mozilla.com/D33701 UltraBlame original commit: 0342dc8a3781dbb73501802c83aa5cfdf4c548a2
This implements position: sticky display of lines for "source" analysis lines
for which we have a "nestingRange" available. Support for emitting
"nestingRange" is added to the C (clang), Rust, and JS analyzer logic.
However, the Rust analyzer changes are very limited because the "save-analysis"
data which forms the basis of the Rust analysis is extremely limited. It
effectively already is being provided with the result of an analysis pass which
has had all AST information stripped away. There did not seem to be any
readily available mechanism in the "RLS" to attempt to reconstitute an AST and
relate it to the analysis data. The best hack I was able to come up with was
to attempt to recursively build up a span covering all of the 'def' children of
a 'def' or an 'impl'. This means that nesting for rust is largely limited to
"struct" definitions and for inherent "impl" blocks, with the nestingRange only
covering up until the start of the last "fn" in the "impl".