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

Add Constant type/value properties #280

Merged
merged 24 commits into from
Oct 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fc75c49
add Constant property resolution function
eugenesvk Oct 5, 2023
364c401
add Constant property rustdocs example
eugenesvk Oct 5, 2023
2d08ae2
add Constant property rustdoc schema
eugenesvk Oct 5, 2023
443c086
dep: add serde_json for Constant property Type
eugenesvk Oct 5, 2023
6854eb9
fix clippy
eugenesvk Oct 6, 2023
5233132
uglify with rustfmt
eugenesvk Oct 6, 2023
024f7b7
Update src/rustdoc_schema.graphql
eugenesvk Oct 6, 2023
2e665e5
squeeze doc comment
eugenesvk Oct 6, 2023
278ecea
add a doc comment note referencing a more comprehensive example
eugenesvk Oct 6, 2023
7dcafb5
add type_ field to AssociatedConstant property resolution function
eugenesvk Oct 6, 2023
097a7f1
add type_ field to AssociatedConstant property rustdoc schema
eugenesvk Oct 6, 2023
2cdd8c0
split schema docs so that each Constant property is documented
eugenesvk Oct 6, 2023
14be2e1
update schema doc comment
eugenesvk Oct 6, 2023
48c1d3d
update schema docs trait name
eugenesvk Oct 7, 2023
f52b2ae
fix a typo in schema docs
eugenesvk Oct 7, 2023
9a48e86
remove type Assoc/Const property
eugenesvk Oct 7, 2023
151ac1a
remove type Assoc/Const property from schema
eugenesvk Oct 7, 2023
dc87d61
fix a typo in schema docs
eugenesvk Oct 8, 2023
0859104
dep: remove serde_json since Constant property Type was removed
eugenesvk Oct 8, 2023
4950f7c
remove unstable rustdocs example for Constant properties
eugenesvk Oct 8, 2023
c0748bc
Update formatting of the schema docs
eugenesvk Oct 8, 2023
e0ced16
Update AssociatedConstant example to refer to a const generic
eugenesvk Oct 8, 2023
0f75831
Update Constant test with extra properties
eugenesvk Oct 8, 2023
e9209dc
Merge branch 'rustdoc-v26' into rustdoc-v26-const
obi1kenobi Oct 9, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/adapter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ impl<'a> Adapter<'a> for RustdocAdapter<'a> {
"AssociatedConstant" => {
properties::resolve_associated_constant_property(contexts, property_name)
}
"Constant" => properties::resolve_constant_property(contexts, property_name),
_ => unreachable!("resolve_property {type_name} {property_name}"),
}
}
Expand Down
36 changes: 36 additions & 0 deletions src/adapter/properties.rs
Original file line number Diff line number Diff line change
Expand Up @@ -465,3 +465,39 @@ pub(crate) fn resolve_associated_constant_property<'a>(
_ => unreachable!("AssociatedConstant property {property_name}"),
}
}

pub(crate) fn resolve_constant_property<'a>(
contexts: ContextIterator<'a, Vertex<'a>>,
property_name: &str,
) -> ContextOutcomeIterator<'a, Vertex<'a>, FieldValue> {
match property_name {
"expr" => resolve_property_with(
contexts,
field_property!(as_item, inner, {
let ItemEnum::Constant(c) = &inner else {
unreachable!("expected to have a Constant")
};
c.expr.clone().into()
}),
),
"value" => resolve_property_with(
contexts,
field_property!(as_item, inner, {
let ItemEnum::Constant(c) = &inner else {
unreachable!("expected to have a Constant")
};
c.value.clone().into()
}),
),
"is_literal" => resolve_property_with(
contexts,
field_property!(as_item, inner, {
let ItemEnum::Constant(c) = &inner else {
unreachable!("expected to have a Constant")
};
c.is_literal.into()
}),
),
_ => unreachable!("Constant property {property_name}"),
}
}
36 changes: 33 additions & 3 deletions src/adapter/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ fn rustdoc_finds_consts() {
item {
... on Constant {
name @output
expr @output
value @output
is_literal @output

importable_path {
path @output
Expand All @@ -190,24 +193,48 @@ fn rustdoc_finds_consts() {
struct Output {
name: String,
path: Vec<String>,
expr: String,
value: Option<String>,
is_literal: bool,
}
#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, serde::Deserialize)]
struct OutputSimple {
name: String,
path: Vec<String>,
}

let mut results: Vec<_> =
trustfall::execute_query(&schema, adapter.clone(), query, variables.clone())
.expect("failed to run query")
.map(|row| row.try_into_struct().expect("shape mismatch"))
.map(|row| row.try_into_struct::<Output>().expect("shape mismatch"))
.collect();
results.sort_unstable();
// to compare to GlobalValue that doesn't Constant-specific properties
let mut results_simple: Vec<_> =
trustfall::execute_query(&schema, adapter.clone(), query, variables.clone())
.expect("failed to run query")
.map(|row| {
row.try_into_struct::<OutputSimple>()
.expect("shape mismatch")
})
.collect();
results_simple.sort_unstable();

similar_asserts::assert_eq!(
vec![
Output {
name: "FIRST".into(),
path: vec!["consts".into(), "FIRST".into()],
expr: "1".to_string(),
value: Some("1u32".to_string()),
is_literal: true,
},
Output {
name: "SECOND".into(),
path: vec!["consts".into(), "inner".into(), "SECOND".into()],
expr: "2".to_string(),
value: Some("2i64".to_string()),
is_literal: true,
},
],
results
Expand All @@ -232,10 +259,13 @@ fn rustdoc_finds_consts() {
let mut global_values_results: Vec<_> =
trustfall::execute_query(&schema, adapter, global_values_query, variables)
.expect("failed to run query")
.map(|row| row.try_into_struct().expect("shape mismatch"))
.map(|row| {
row.try_into_struct::<OutputSimple>()
.expect("shape mismatch")
})
.collect();
global_values_results.sort_unstable();
assert_eq!(results, global_values_results);
assert_eq!(results_simple, global_values_results);
}

#[test]
Expand Down
79 changes: 69 additions & 10 deletions src/rustdoc_schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -695,6 +695,61 @@ type Constant implements Item & Importable & GlobalValue {
attrs: [String!]!
visibility_limit: String!

# properties for Constant
eugenesvk marked this conversation as resolved.
Show resolved Hide resolved
"""
The expression of the constant, if any, as a Rust literal or `"_"`. For example:
```rust
// // expr
const MIN : usize = 16 ; // 16
const MIN_SIZE: usize = MIN ; // "MIN", referring to the other constant's name
const LOG_AS : &str = "batch" ; // "\"batch\"", including escaped quotes
const YEAR : Years = Years(42); // "_"
const EXPR_2_2: i32 = 2 + 2 ; // "_"
const FN_FIVE : i32 = five() ; // "_"
const fn five() -> i32 { 5 };
struct Years(i32);
```
If the constant is set:

Comment on lines +712 to +713
Copy link
Owner

Choose a reason for hiding this comment

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

minor formatting nit:

Suggested change
If the constant is set:
If the constant is set:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is actually intentional since no space after the "header" breaks the formatting, so instead of 2 bullet points you get one line (at least in my Sublime editor with LSP plugin)

Not sure how it works in your wasm playground or any other tools

Let me know if you want to add an extra empty line before anyway (personally prefer a bit more compact, but up to you)

Copy link
Owner

Choose a reason for hiding this comment

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

Ah nice, thanks for double-checking it in the editor.

Let's add the extra empty line before the block, though. I think that way it's a bit more readable when it's not rendered as markdown.

Copy link
Owner

Choose a reason for hiding this comment

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

It's just the adding the newline, so I'll merge this as-is and add the newline in a separate PR and then cut a release so we can move faster.

- to be equal to another constant, `expr` holds the name of that other constant.
- by evaluating a `const` expression, such as `2 + 2` or a `const fn` call, `expr` is `"_"` instead of including the full expression.
"""
expr: String
"""
The value of the constant, if any, as a Rust literal. For example:
```rust
// // value
const MIN : usize = 16 ; // "16usize"
const MIN_SIZE: usize = MIN ; // "16usize"
const LOG_AS : &str = "batch" ; // None
const YEAR : Years = Years(42); // None
const EXPR_2_2: i32 = 2 + 2 ; // "4i32"
const FN_FIVE : i32 = five() ; // "5i32"
const fn five() -> i32 { 5 };
struct Years(i32);
```
If the constant is set:

eugenesvk marked this conversation as resolved.
Show resolved Hide resolved
- to be equal to another constant, `value` holds the value of that other constant.
- by evaluating a `const` expression, such as `2 + 2` or a `const fn` call, `value` is evaluated
"""
value: String
"""
The literal flag of the constant. For example:
```rust
// // is_literal
const MIN : usize = 16 ; // true
const MIN_SIZE: usize = MIN ; // false
const LOG_AS : &str = "batch" ; // true
const YEAR : Years = Years(42); // false
const EXPR_2_2: i32 = 2 + 2 ; // false
const FN_FIVE : i32 = five() ; // false
const fn five() -> i32 { 5 };
struct Years(i32);
```
"""
is_literal: Boolean

# edges from Item
span: Span
attribute: [Attribute!]
Expand Down Expand Up @@ -882,21 +937,25 @@ type AssociatedConstant implements Item {

For example:
```rust
trait BatchIterator<const MIN: usize> {
const SIZE: usize = 16; // `"16"` is the default
const LOG_AS: &'static str = "batch"; // `"\"batch\""` is the default, including escaped quotes
const MIN_SIZE: usize = MIN; // "MIN" is the default, referring to the other constant's name
Comment on lines -885 to -888
Copy link
Owner

Choose a reason for hiding this comment

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

In the original example, MIN_SIZE was referring to the const generic constant. In the new example it refers to a local sibling constant only, and there's no example with a const generic. Mind adding a const generic example as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

restored MIN to be the const generic and the sibling is just a standalone NUM number

const fn five() -> i32 { 5 };
struct Years(i32);
trait MyTrait<const MIN: usize> { // rustdocs default field
const NUM : i32 = 16 ; // 16
const MIN_SIZE: usize = MIN ; // "MIN", referring to the other constant's name
const LOG_AS : &'static str = "batch" ; // "\"batch\"", including escaped quotes
const EXPR2_2 : i32 = 2+2 ; // "_"
const FN_FIVE : i32 = five() ; // "_"
const YEAR : Years = Years(42); // "_"
}
```

If the associated constant is on a type's inherent impl, the default is always required to be set.
If the associated constant is on a type's inherent impl, `default` is always required to be set.

If the associated constant is set to be equal to another constant, the default holds the name
of that other constant.
If the associated constant is set:

If the associated constant is set by evaluating a `const` expression, such as `2 + 2` or
a `const fn` call, rustdoc's current behavior is to show a default value of `"_"`
instead of evaluating the constant value or including the full expression.
- to be equal to another constant, `default` holds the name of that other constant.
- by evaluating a `const` expression, such as `2 + 2` or a `const fn` call,
`default` is `"_"` instead of evaluating the constant value or including the full expression.
"""
default: String

Expand Down