Skip to content
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

Export attributes in save-analysis data #39820

Merged
merged 3 commits into from
Mar 11, 2017
Merged

Export attributes in save-analysis data #39820

merged 3 commits into from
Mar 11, 2017

Conversation

jonasbb
Copy link
Contributor

@jonasbb jonasbb commented Feb 14, 2017

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with #[test] annotations such that tools like rls can offer a test-runner feature. I described my idea here rls#173.

My changes contain:

  1. track a vector of attributes in the various *Data types in data.rs and external_data.rs
  2. implement lowering for Attribute and MetaItem
  3. adjust JsonDumper to print the attributes

In the lowering of Attribute I remove the distinction between MetaItem and NestedMetaItem. I did this because this distinction is somewhat confusing. For example, NestedMetaItemKind::Literal has two identical spans, because both NestedMetaItem and Lit are defined as Spanned<_>.
My model is strictly more general, as it allows an LitKind instead of a Symbol for MetaItem and Symbols are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of #[test] annotation:

"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]     
      },    
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }     
    },    
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]

@rust-highfive
Copy link
Collaborator

Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @nrc (or someone else) soon.

If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes.

Please see the contribution instructions for more information.

Copy link
Member

@nrc nrc left a comment

Choose a reason for hiding this comment

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

This looks really good! I wonder if the data we output should be simpler though - it seems a bit too close to the AST atm.

/// A single item as part of an attribute
#[derive(Clone, Debug, RustcEncodable)]
pub struct AttributeItem {
name: LitKind,
Copy link
Member

Choose a reason for hiding this comment

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

This should probably just be a string, rather than coding it as a LitKind

/// List meta item.
///
/// E.g. the `derive(..)` as in `#[derive(..)]`
List(Vec<AttributeItem>),
Copy link
Member

Choose a reason for hiding this comment

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

I feel like this is too much structure for save-analysis - will we need it all in the RLS? Could we do something simpler?

@jonasbb
Copy link
Contributor Author

jonasbb commented Feb 22, 2017

@nrc Thank you for the feedback. I agree that it is very close to the AST. While implementing the feature I found out that it is possible to have arbitrary literals in the attributes (using the attr_literals feature). I wanted to be as general as possible, therefore I chose the design so close to the AST.

This allows to answer any query about attributes. A query which would need this information would be "All types which derive Serializable". I am not sure if this is needed in RLS though.

I see two ways to simplify it:

  1. Remove support for attr_literals in save-analysis. They could be converted into strings so that any save-analysis consumer must parse them again. I don't think this is a good solution if the goal of rust is to support literals in attributes.
  2. Only store the name of the attribute in save-analysis data. The name must always be an identifier and cannot ever be a literal. This would also remove the need of AttributeItemKind.

I am fine with implementing option 2. because this would be sufficient to satisfy my requirement. Are there other consumers besides RLS which would like this information?

@nrc
Copy link
Member

nrc commented Feb 23, 2017

The long term plan for attributes is that they are basically just a name and a bunch of tokens. So I'm not sure that it makes sense to try and preserve any structure beyond a string.

I think any semantic queries about attributes would be better served by analysing the result of the attribute rather than the attribute itself. E.g., rather than looking for derives, look for the impls generated by the derives.

@jonasbb
Copy link
Contributor Author

jonasbb commented Feb 23, 2017

@nrc Reducing attributes to be strings is quite nice I think. I use pprust::attribute_to_string to create a string and then strip the surrounding #[/#![ and ] off it.


fn lower(mut self, tcx: TyCtxt) -> Attribute {
// strip #[] and #![] from the original attributes
self.style = ast::AttrStyle::Outer;
Copy link
Member

Choose a reason for hiding this comment

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

Heh, this is a neat little hack :-)

I think the comment could explain more clearer what is happening here though

// strip #[] and #![] from the original attributes
self.style = ast::AttrStyle::Outer;
let value = pprust::attribute_to_string(&self);
// #[] are all ASCII which makes this slice save
Copy link
Member

Choose a reason for hiding this comment

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

The grammar in this comment seems not right to me.

@@ -228,6 +232,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> {
visibility: From::from(&item.vis),
docs: docs_for_attrs(&item.attrs),
sig: self.sig_base(item),
attributes: remove_docs_from_attrs(&item.attrs),
Copy link
Member

Choose a reason for hiding this comment

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

could the remove_docs_from_attrs call be moved to the lower function so it is not duplicated?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Certainly. I followed the usage of docs_for_attrs here, which does something very similar, except for comments instead of attributes. They are even more similar now, because attributes are lowered to (String, Span) pairs. Calling this function (or even the lowering) earlier reduces the amount of data which needs to be copies around.

@nrc
Copy link
Member

nrc commented Mar 7, 2017

Thanks for the changes!

@bors: r+

@bors
Copy link
Contributor

bors commented Mar 7, 2017

📌 Commit 5bfa0f3 has been approved by nrc

@bors
Copy link
Contributor

bors commented Mar 8, 2017

⌛ Testing commit 5bfa0f3 with merge 05076d9...

@bors
Copy link
Contributor

bors commented Mar 8, 2017

💔 Test failed - status-travis

@arielb1
Copy link
Contributor

arielb1 commented Mar 8, 2017

error: failed to run custom build command for `compiler_builtins v0.0.0 (file:///checkout/src/libcompiler_builtins)`
...
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error { repr: Os { code: 17, message: "File exists" } }', /buildslave/rust-buildbot/slave/beta-dist-rustc-linux/build/src/libcore/result.rs:868

@arielb1
Copy link
Contributor

arielb1 commented Mar 8, 2017

cc @alexcrichton

@alexcrichton
Copy link
Member

@bors
Copy link
Contributor

bors commented Mar 9, 2017

🔒 Merge conflict

@arielb1
Copy link
Contributor

arielb1 commented Mar 9, 2017

@bors retry

@bors
Copy link
Contributor

bors commented Mar 9, 2017

🔒 Merge conflict

@alexcrichton
Copy link
Member

@bors: retry

frewsxcv added a commit to frewsxcv/rust that referenced this pull request Mar 9, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
@bors
Copy link
Contributor

bors commented Mar 9, 2017

🔒 Merge conflict

@alexcrichton
Copy link
Member

@bors: retry

@bors
Copy link
Contributor

bors commented Mar 10, 2017

🔒 Merge conflict

@alexcrichton
Copy link
Member

@bors: retry

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 10, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
Some annotations like the "test" annotations might be of interest for
other projects, especially rls. Export all attributes in a new
attributes item.
Remove the AST structure
@alexcrichton
Copy link
Member

@bors: r=nrc

@bors
Copy link
Contributor

bors commented Mar 10, 2017

📌 Commit db35604 has been approved by nrc

alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 10, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
arielb1 pushed a commit to arielb1/rust that referenced this pull request Mar 10, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
arielb1 pushed a commit to arielb1/rust that referenced this pull request Mar 10, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
arielb1 pushed a commit to arielb1/rust that referenced this pull request Mar 10, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
alexcrichton added a commit to alexcrichton/rust that referenced this pull request Mar 10, 2017
Export attributes in save-analysis data

Since this is my first pull-request to rust, I would like to get some feedback about obvious errors in this implementation.

I would like to change the save-analysis data to include arbitrary attribute data.
A use-case I have in mind for this is identifying functions with `#[test]` annotations such that tools like rls can offer a test-runner feature. I described my idea here [rls#173](rust-lang/rls#173).

My changes contain:

1. track a vector of attributes in the various `*Data` types in `data.rs` and `external_data.rs`
2. implement lowering for `Attribute` and `MetaItem`
3. adjust `JsonDumper` to print the attributes

In the lowering of `Attribute` I remove the distinction between `MetaItem` and `NestedMetaItem`. I did this because this distinction is somewhat confusing. For example, `NestedMetaItemKind::Literal` has two identical spans, because both `NestedMetaItem` and `Lit` are defined as `Spanned<_>`.
My model is strictly more general, as it allows an `LitKind` instead of a `Symbol` for `MetaItem` and `Symbol`s are converted into a cooked string. As a consumer of the save-analysis data this shouldn't affect you much.

Example json output of `#[test]` annotation:
```
"attributes": [
  {
    "value": {
      "name": {
        "variant": "Str",
        "fields": [
          "test",
          "Cooked"
        ]
      },
      "kind": "Literal",
      "span": {
        "file_name": "test.rs",
        "byte_start": 2,
        "byte_end": 6,
        "line_start": 1,
        "line_end": 1,
        "column_start": 3,
        "column_end": 7
      }
    },
    "span": {
      "file_name": "test.rs",
      "byte_start": 0,
      "byte_end": 7,
      "line_start": 1,
      "line_end": 1,
      "column_start": 1,
      "column_end": 8
    }
  }
]
```
@bors bors merged commit db35604 into rust-lang:master Mar 11, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants