Skip to content
This repository has been archived by the owner on May 20, 2020. It is now read-only.

Adding all the DefKinds #121 #177

Merged
merged 2 commits into from
Oct 19, 2017
Merged

Adding all the DefKinds #121 #177

merged 2 commits into from
Oct 19, 2017

Conversation

projektir
Copy link
Contributor

@projektir projektir commented Sep 27, 2017

Addresses #121.

This excludes Local, which means it needs to be deliberately skipped. Maybe it should be more specific like DefKind::Local => continue in case something else is added in the future?

I'm not sure if it makes sense for Static or Const and such to have children?

I believe the idea is to set this boilerplate up and then we can move on to actually implementing things in the frontend?

@steveklabnik
Copy link
Owner

steveklabnik commented Sep 27, 2017

Maybe it should be more specific like DefKind::Local => continue in case something else is added in the future?

Yeah, seems good.

I'm not sure if it makes sense for Static or Const and such to have children?

Yeah, this is true. They shouldn't have children, they probably will be children, though.

I believe the idea is to set this boilerplate up and then we can move on to actually implementing things in the frontend?

💯

Could you add tests please?

@mgattozzi
Copy link
Contributor

For the tests you would want to put something under this directory here. I think something like def_kind.rs would be a good thing and then just create every type of DefKind in the source code there and set up some assertions. Or seperately (and probably a better idea) is to set up one type of file for each DefKind we don't have yet and make the assertions in there. You can look at the other files for examples of how to assert something is of the output JSON that rustdoc emits.

@projektir does that make sense? Anything I can clear up with my explanation?

@projektir
Copy link
Contributor Author

@mgattozzi
OK, I've tried some of this but I'm hitting a lot of issues (see comments)... this commit will break since otherwise I have to delete the whole file for macros.

@@ -0,0 +1,9 @@
#![crate_type = "lib"]

// @has /data/relationships/macros/data/0 'macro'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't get this to pick up at all. It doesn't seem to see macros. I have the same issue with unions and I imagine would have the same issue with statics and consts.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@steveklabnik what about this problem?

I'm seeing in #7 a comment"After a quick look at generated JSON, it looks like the exported macros (and their doc comments) are not included.". So that kind of seems like a problem. And I've also seen the same issue with unions.

I'm going to tweak the lib.rs file with all these things and see what it actually generates because it doesn't seem like a lot right now.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds like maybe the same thing as impls, I'm not sure.

pub struct UnitStruct;

impl UnitStruct {
pub fn method_function() {}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since to create a method it needs to be attached to some object, I need to identify it somehow, but nothing seems to work. Am I misunderstanding that this is not actually a child of a struct or such? Is there some intermediate type?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nrc, I don't know anything about this, maybe you do?

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, basically nothing with impls (and thus methods) is going to work very well yet. We need some work in rustc to add support and that is a bit non-trivial in the general case. We could add support for inherent impls pretty easily, if someone wanted to hack on that I could give instructions.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And actually, I thought inherent impls worked, but maybe I was just wrong about that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In which case it might just be best for now if we put tests for what works, mark what doesn't (but still keep the code there), and have the tests written for whatever works. Thoughts @steveklabnik?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd remove the code for the stuff that doesn't work, and go with a _ =>. But yeah, otherwise, let's do that, @projektir . It might also be worth noting this over at #7

Thanks @nrc

@projektir
Copy link
Contributor Author

Looking at it a bit more, it seems the data.json (which I am assuming is backend relevant) is not getting generated right. It only has modules, structs, and functions, and doesn't get methods nor other things if I modify the lib.rs. So it looks like my boilerplate code is just not getting the job done in the first place.

Copy link
Owner

@steveklabnik steveklabnik left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's see what nick says about this

pub struct UnitStruct;

impl UnitStruct {
pub fn method_function() {}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nrc, I don't know anything about this, maybe you do?

@mgattozzi
Copy link
Contributor

Yeah it might just something with rls-analysis or something in your code (which I doubt).

@projektir
Copy link
Contributor Author

All right, so I added everything that I could figure out. I'd like to say that the following DefKinds can be marked as done for #121: Trait, Function, Mod, Type, Static, Const.
Tuple and Local should just be removed maybe since they won't be implemented? For the rest there seem to be some bugs.

I've also added various examples to the example lib.rs.

The new lib.rs contains the following: https://gist.github.com/projektir/5f51fc77fe0608e06f3d374d1b1bce03

Here's the resulting data.json: https://gist.github.com/projektir/f4070a06cb88b8e8093cdfd2f54dd24b

Seeing a few weird things:

  1. Absence of Macros and Unions as we already know.
  2. Can't see the impl and therefore Methods as we already know.
  3. Information seems to get duplicated for Structs, struct Fields, and Enums. If you look you'll see EnumVariant is listed twice, etc. This doesn't happen for modules...
  4. When child_structs and such is used, it seems that it'd be more accurate to say struct_children... or just plain children... but this is odd in general because while the ContainerStruct has as a field that's not a struct, its type is still marked as struct (see comment in test case). That doesn't seem right. Similarly, enum variants have type enum, I think this is a related thing.
  5. There's no way to see docs for EnumVariants. It seems to be because there's no docs attribute for children, only for top level includes, so I am not sure if EnumVariants need to be listed as includes or what.
  6. Docs representation. Multiple lines of docs seem to go poof, only the first line is in the .json. Doc lines sometimes include spaces or \n, but this may be a problem with my IDE or something.

// @has /included/0/attributes/docs ''

// This will fail, the type of 'fields::StructWithFields::integer' is 'struct'
// has /included/0/relationships/child_structs/data/0/type 'field'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I expect this to be a field, but it's a struct. It seems "children" of something all get set to have the type as the parent, which of course is not true for complex types like Structs or Enums.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, that seems... less than ideal.

// @has /included/1/type 'struct'
// @has /included/1/id 'structs::ContainerStruct'
// @has /included/1/attributes/name 'ContainerStruct'
// @has /included/1/attributes/docs 'A struct that contains another struct.'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you can see there's no "Docs for the ContainerStruct." here. That part of the documentation just seems to disappear.


/// An enum.
pub enum SampleEnum {
/// An enum variant.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No way to see these docs that I can find.

@steveklabnik
Copy link
Owner

When child_structs and such is used, it seems that it'd be more accurate to say struct_children... or just plain children... but this is odd in general because while the ContainerStruct has as a field that's not a struct, its type is still marked as struct (see comment in test case). That doesn't seem right. Similarly, enum variants have type enum, I think this is a related thing.

Yeah, so I was doing the child thing because modules have children, but other types don't, so I'm wondering if this isn't, in the end, an anti-pattern. Hrm.

@nrc
Copy link

nrc commented Oct 5, 2017

I think that I would avoid surfacing 'children' to the user at all - it's a bit vague and doesn't reflect any term in the code. I would use different terms for different structures - variants of an enum, fields of a struct, etc. Internally, it makes sense to use children, at least for save-analysis where we try to abstract things as much as possible.

It seems like there are a few rough edges with the save-analysis data. I think they should mostly be easy to fix (unions, docs for enum variants, etc.). If you could file issues on the rls-analysis repo it is easier for me than the Rust repo (just too many notifications). I'll try and fix them or organise an impl period/mentoring effort around them when I get back from parental leave.

@projektir
Copy link
Contributor Author

@nrc
I've made some issues for the stuff that I found. Note that my understanding of rls-analysis is limited, so I may be looking at the wrong thing somewhere.

I'd be happy to try to work on those issues, as well.

@nrc
Copy link

nrc commented Oct 9, 2017

@projektir thanks for filing the issues! It would be great to have you work on some of them. I'm currently on parental leave, but I'll write some instructions when I get back in a couple of weeks.

@mgattozzi
Copy link
Contributor

@nrc if there's instructions left I can take a crack at them as well so we can get this PR moving.

@steveklabnik
Copy link
Owner

Question: since this has been a while, do we want to merge, with the understanding that some stuff doesn't work yet, rather than block this on upstream work?

src/json/mod.rs Outdated
@@ -88,6 +101,19 @@ pub fn create_json(host: &AnalysisHost, crate_name: &str) -> Result<String> {
let (ty, child_ty) = match def.kind {
DefKind::Mod => (String::from("module"), String::from("child_modules")),
DefKind::Struct => (String::from("struct"), String::from("child_structs")),
DefKind::Enum => (String::from("enum"), String::from("child_enums")),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, there's no real reason that we need the child stuff here; i was cargo-culting from modules

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also means that this block and the one above are identical except for modules, which is annoying

@steveklabnik
Copy link
Owner

Okay, so more thorough review today; we should cut the stuff that doesn't work yet, and leave in the stuff that does. wrt the child stuff, let's make it so that only modules does the child thing. And then we can ship this. Sound good?

@steveklabnik
Copy link
Owner

Appveyor is failing on traits, but not for me or @projektir locally :/

@steveklabnik
Copy link
Owner

Update: needed to rebase the branch; appveyor basically does this. Fixed that up. Now to figure out enums...

This adds as much stuff as we can so far; some issues like
rust-dev-tools/rls-analysis#98 mean that we can't do
everything.

Fixes #121
@steveklabnik steveklabnik merged commit d3584d5 into steveklabnik:master Oct 19, 2017
@steveklabnik
Copy link
Owner

🎊

@projektir projektir deleted the backend-defkinds branch October 19, 2017 18:19
@nrc
Copy link

nrc commented Nov 2, 2017

@projektir Hey, are you still interested in working on some rls-analysis issues? I'm back from leave now, so you can ping me anytime in #rust-dev-tools or @Rustc.

Some basic instructions for how to tackle these issues:

  • I track the issues on the rls-analysis repo (you've already filed some issues there)
  • the first job is figuring out where in the toolchain the problem is. There are only really three options:
    • rls-analysis - we get correct data from the compiler but then screw things up when processing the data. This is actually fairly rare. When it does happen, 9 times out of 10 you need to look in lowering.rs. If you log the info! statements, you should get a good idea of what is happening.
    • librustc_save_analysis - conceptually this is the last step of the compiler and it processes the compiler's data into the save-analysis JSON. Most bugs are here.
    • spans - sometimes save-analysis is working properly but the input is wrong. In this case the bug is usually in the parser and it is causing save-analysis to skip an expression or get the analysis wrong when it shouldn't.
  • Write a small test case, then look at the JSON emitted by the compiler when run with -Zsave-analysis. You should be able to interpret the defs and refs to work out if the correct info is there. If it is, then the bug is in rls-analysis, if it isn't then the bug is in the compiler. Note that a ref without a def is ignored, so even if there is a ref, if it doesn't point at any def, it may as well be missing.
  • If the bug is in the compiler, then look in dump_visitor. It is a visitor which walks the AST, so for your minimal test case you should be able to see where we ought to be dumping the node. Then use a debugger or write printlns to work out what is going on.
  • Bugs with macros (or other generated code) tend to be 10x harder to solve, I'd ignore them to start with.

@nrc
Copy link

nrc commented Nov 2, 2017

previous comment also for @mgattozzi

@mgattozzi
Copy link
Contributor

@nrc I need to find some time hopefully soon I've been busier than expected but if I can I'd like to take a crack at it. I'll ping you whenever I have the time.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants