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

Improve/add use_item documentation #256

Merged
merged 2 commits into from
Dec 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 54 additions & 1 deletion crates/ra_syntax/src/grammar/items/use_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,75 @@ pub(super) fn use_item(p: &mut Parser) {
p.expect(SEMI);
}

/// Parse a use 'tree', such as `some::path` in `use some::path;`
/// Note that this is called both by `use_item` and `use_tree_list`,
/// so handles both `some::path::{inner::path}` and `inner::path` in
/// `use some::path::{inner::path};`
fn use_tree(p: &mut Parser) {
let la = p.nth(1);
let m = p.start();
match (p.current(), la) {
// Finish the use_tree for cases of e.g.
// `use some::path::{self, *};` or `use *;`
// This does not handle cases such as `use some::path::*`
// N.B. in Rust 2015 `use *;` imports all from crate root
// however in Rust 2018 `use *;` errors: ('cannot glob-import all possible crates')
// TODO: Add this error (if not out of scope)

// test use_star
// use *;
// use ::*;
// use some::path::{*};
// use some::path::{::*};
(STAR, _) => p.bump(),
(COLONCOLON, STAR) => {
// Parse `use ::*;`, which imports all from the crate root in Rust 2015
// This is invalid inside a use_tree_list, (e.g. `use some::path::{::*}`)
// but still parses and errors later: ('crate root in paths can only be used in start position')
// TODO: Add this error (if not out of scope)
Copy link
Member

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, it was just an overall comment that it was something that naturally comes up there, but should be added somewhere else.

// In Rust 2018, it is always invalid (see above)
p.bump();
p.bump();
}
// Open a use tree list
// Handles cases such as `use {some::path};` or `{inner::path}` in
// `use some::path::{{inner::path}, other::path}`

// test use_tree_list
// use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`)
// use {path::from::root}; // Rust 2015
// use ::{some::arbritrary::path}; // Rust 2015
// use ::{{{crate::export}}}; // Nonsensical but perfectly legal nestnig
(L_CURLY, _) | (COLONCOLON, L_CURLY) => {
if p.at(COLONCOLON) {
p.bump();
}
use_tree_list(p);
}
// Parse a 'standard' path.
// Also handles aliases (e.g. `use something as something_else`)

// test use_path
// use ::crate_name; // Rust 2018 - All flavours
// use crate_name; // Rust 2018 - Anchored paths
// use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths
//
// use self::module::Item;
// use crate::Item;
// use self::some::Struct;
// use crate_name::some_item;
_ if paths::is_path_start(p) => {
paths::use_path(p);
match p.current() {
AS_KW => {
// test use_alias
// use some::path as some_name;
// use some::{
// other::path as some_other_name,
// different::path as different_name,
// yet::another::path,
// running::out::of::synonyms::for::different::*
// };
opt_alias(p);
}
COLONCOLON => {
Expand All @@ -34,6 +84,9 @@ fn use_tree(p: &mut Parser) {
STAR => {
p.bump();
}
// test use_tree_list_after_path
// use crate::{Item};
// use self::{Item};
L_CURLY => use_tree_list(p),
_ => {
// is this unreachable?
Expand All @@ -46,7 +99,7 @@ fn use_tree(p: &mut Parser) {
}
_ => {
m.abandon(p);
p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super`, `indent`");
p.err_and_bump("expected one of `*`, `::`, `{`, `self`, `super` or an indentifier");
return;
}
}
Expand Down
3 changes: 3 additions & 0 deletions crates/ra_syntax/tests/data/parser/inline/0114_use_path.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
use ::crate_name; // Rust 2018 - All flavours
use crate_name; // Rust 2018 - Anchored paths
use item_in_scope_or_crate_name; // Rust 2018 - Uniform Paths
38 changes: 38 additions & 0 deletions crates/ra_syntax/tests/data/parser/inline/0114_use_path.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
SOURCE_FILE@[0; 154)
USE_ITEM@[0; 17)
USE_KW@[0; 3)
WHITESPACE@[3; 4)
USE_TREE@[4; 16)
PATH@[4; 16)
PATH_SEGMENT@[4; 16)
COLONCOLON@[4; 6)
NAME_REF@[6; 16)
IDENT@[6; 16) "crate_name"
SEMI@[16; 17)
WHITESPACE@[17; 18)
COMMENT@[18; 45)
WHITESPACE@[45; 46)
USE_ITEM@[46; 61)
USE_KW@[46; 49)
WHITESPACE@[49; 50)
USE_TREE@[50; 60)
PATH@[50; 60)
PATH_SEGMENT@[50; 60)
NAME_REF@[50; 60)
IDENT@[50; 60) "crate_name"
SEMI@[60; 61)
WHITESPACE@[61; 62)
COMMENT@[62; 91)
WHITESPACE@[91; 92)
USE_ITEM@[92; 124)
USE_KW@[92; 95)
WHITESPACE@[95; 96)
USE_TREE@[96; 123)
PATH@[96; 123)
PATH_SEGMENT@[96; 123)
NAME_REF@[96; 123)
IDENT@[96; 123) "item_in_scope_or_crate_name"
SEMI@[123; 124)
WHITESPACE@[124; 125)
COMMENT@[125; 153)
WHITESPACE@[153; 154)
7 changes: 7 additions & 0 deletions crates/ra_syntax/tests/data/parser/inline/0115_use_alias.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
use some::path as some_name;
use some::{
other::path as some_other_name,
different::path as different_name,
yet::another::path,
running::out::of::synonyms::for::different::*
};
124 changes: 124 additions & 0 deletions crates/ra_syntax/tests/data/parser/inline/0115_use_alias.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
SOURCE_FILE@[0; 181)
USE_ITEM@[0; 28)
USE_KW@[0; 3)
WHITESPACE@[3; 4)
USE_TREE@[4; 27)
PATH@[4; 14)
PATH@[4; 8)
PATH_SEGMENT@[4; 8)
NAME_REF@[4; 8)
IDENT@[4; 8) "some"
COLONCOLON@[8; 10)
PATH_SEGMENT@[10; 14)
NAME_REF@[10; 14)
IDENT@[10; 14) "path"
WHITESPACE@[14; 15)
ALIAS@[15; 27)
AS_KW@[15; 17)
WHITESPACE@[17; 18)
NAME@[18; 27)
IDENT@[18; 27) "some_name"
SEMI@[27; 28)
WHITESPACE@[28; 29)
USE_ITEM@[29; 180)
USE_KW@[29; 32)
WHITESPACE@[32; 33)
USE_TREE@[33; 179)
PATH@[33; 37)
PATH_SEGMENT@[33; 37)
NAME_REF@[33; 37)
IDENT@[33; 37) "some"
COLONCOLON@[37; 39)
USE_TREE_LIST@[39; 179)
L_CURLY@[39; 40)
WHITESPACE@[40; 42)
USE_TREE@[42; 72)
PATH@[42; 53)
PATH@[42; 47)
PATH_SEGMENT@[42; 47)
NAME_REF@[42; 47)
IDENT@[42; 47) "other"
COLONCOLON@[47; 49)
PATH_SEGMENT@[49; 53)
NAME_REF@[49; 53)
IDENT@[49; 53) "path"
WHITESPACE@[53; 54)
ALIAS@[54; 72)
AS_KW@[54; 56)
WHITESPACE@[56; 57)
NAME@[57; 72)
IDENT@[57; 72) "some_other_name"
COMMA@[72; 73)
WHITESPACE@[73; 75)
USE_TREE@[75; 108)
PATH@[75; 90)
PATH@[75; 84)
PATH_SEGMENT@[75; 84)
NAME_REF@[75; 84)
IDENT@[75; 84) "different"
COLONCOLON@[84; 86)
PATH_SEGMENT@[86; 90)
NAME_REF@[86; 90)
IDENT@[86; 90) "path"
WHITESPACE@[90; 91)
ALIAS@[91; 108)
AS_KW@[91; 93)
WHITESPACE@[93; 94)
NAME@[94; 108)
IDENT@[94; 108) "different_name"
COMMA@[108; 109)
WHITESPACE@[109; 111)
USE_TREE@[111; 129)
PATH@[111; 129)
PATH@[111; 123)
PATH@[111; 114)
PATH_SEGMENT@[111; 114)
NAME_REF@[111; 114)
IDENT@[111; 114) "yet"
COLONCOLON@[114; 116)
PATH_SEGMENT@[116; 123)
NAME_REF@[116; 123)
IDENT@[116; 123) "another"
COLONCOLON@[123; 125)
PATH_SEGMENT@[125; 129)
NAME_REF@[125; 129)
IDENT@[125; 129) "path"
COMMA@[129; 130)
WHITESPACE@[130; 132)
USE_TREE@[132; 177)
PATH@[132; 174)
PATH@[132; 163)
PATH@[132; 158)
PATH@[132; 148)
PATH@[132; 144)
PATH@[132; 139)
PATH_SEGMENT@[132; 139)
NAME_REF@[132; 139)
IDENT@[132; 139) "running"
COLONCOLON@[139; 141)
PATH_SEGMENT@[141; 144)
NAME_REF@[141; 144)
IDENT@[141; 144) "out"
COLONCOLON@[144; 146)
PATH_SEGMENT@[146; 148)
NAME_REF@[146; 148)
IDENT@[146; 148) "of"
COLONCOLON@[148; 150)
PATH_SEGMENT@[150; 158)
NAME_REF@[150; 158)
IDENT@[150; 158) "synonyms"
COLONCOLON@[158; 160)
err: `expected identifier`
PATH_SEGMENT@[160; 163)
ERROR@[160; 163)
FOR_KW@[160; 163)
COLONCOLON@[163; 165)
PATH_SEGMENT@[165; 174)
NAME_REF@[165; 174)
IDENT@[165; 174) "different"
COLONCOLON@[174; 176)
STAR@[176; 177)
WHITESPACE@[177; 178)
R_CURLY@[178; 179)
SEMI@[179; 180)
WHITESPACE@[180; 181)
4 changes: 4 additions & 0 deletions crates/ra_syntax/tests/data/parser/inline/0116_use_star.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use *;
use ::*;
use some::path::{*};
use some::path::{::*};
59 changes: 59 additions & 0 deletions crates/ra_syntax/tests/data/parser/inline/0116_use_star.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
SOURCE_FILE@[0; 60)
USE_ITEM@[0; 6)
USE_KW@[0; 3)
WHITESPACE@[3; 4)
USE_TREE@[4; 5)
STAR@[4; 5)
SEMI@[5; 6)
WHITESPACE@[6; 7)
USE_ITEM@[7; 15)
USE_KW@[7; 10)
WHITESPACE@[10; 11)
USE_TREE@[11; 14)
COLONCOLON@[11; 13)
STAR@[13; 14)
SEMI@[14; 15)
WHITESPACE@[15; 16)
USE_ITEM@[16; 36)
USE_KW@[16; 19)
WHITESPACE@[19; 20)
USE_TREE@[20; 35)
PATH@[20; 30)
PATH@[20; 24)
PATH_SEGMENT@[20; 24)
NAME_REF@[20; 24)
IDENT@[20; 24) "some"
COLONCOLON@[24; 26)
PATH_SEGMENT@[26; 30)
NAME_REF@[26; 30)
IDENT@[26; 30) "path"
COLONCOLON@[30; 32)
USE_TREE_LIST@[32; 35)
L_CURLY@[32; 33)
USE_TREE@[33; 34)
STAR@[33; 34)
R_CURLY@[34; 35)
SEMI@[35; 36)
WHITESPACE@[36; 37)
USE_ITEM@[37; 59)
USE_KW@[37; 40)
WHITESPACE@[40; 41)
USE_TREE@[41; 58)
PATH@[41; 51)
PATH@[41; 45)
PATH_SEGMENT@[41; 45)
NAME_REF@[41; 45)
IDENT@[41; 45) "some"
COLONCOLON@[45; 47)
PATH_SEGMENT@[47; 51)
NAME_REF@[47; 51)
IDENT@[47; 51) "path"
COLONCOLON@[51; 53)
USE_TREE_LIST@[53; 58)
L_CURLY@[53; 54)
USE_TREE@[54; 57)
COLONCOLON@[54; 56)
STAR@[56; 57)
R_CURLY@[57; 58)
SEMI@[58; 59)
WHITESPACE@[59; 60)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
use crate::{Item};
use self::{Item};
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
SOURCE_FILE@[0; 37)
USE_ITEM@[0; 18)
USE_KW@[0; 3)
WHITESPACE@[3; 4)
USE_TREE@[4; 17)
PATH@[4; 9)
PATH_SEGMENT@[4; 9)
CRATE_KW@[4; 9)
COLONCOLON@[9; 11)
USE_TREE_LIST@[11; 17)
L_CURLY@[11; 12)
USE_TREE@[12; 16)
PATH@[12; 16)
PATH_SEGMENT@[12; 16)
NAME_REF@[12; 16)
IDENT@[12; 16) "Item"
R_CURLY@[16; 17)
SEMI@[17; 18)
WHITESPACE@[18; 19)
USE_ITEM@[19; 36)
USE_KW@[19; 22)
WHITESPACE@[22; 23)
USE_TREE@[23; 35)
PATH@[23; 27)
PATH_SEGMENT@[23; 27)
SELF_KW@[23; 27)
COLONCOLON@[27; 29)
USE_TREE_LIST@[29; 35)
L_CURLY@[29; 30)
USE_TREE@[30; 34)
PATH@[30; 34)
PATH_SEGMENT@[30; 34)
NAME_REF@[30; 34)
IDENT@[30; 34) "Item"
R_CURLY@[34; 35)
SEMI@[35; 36)
WHITESPACE@[36; 37)
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
use {crate::path::from::root, or::path::from::crate_name}; // Rust 2018 (with a crate named `or`)
use {path::from::root}; // Rust 2015
use ::{some::arbritrary::path}; // Rust 2015
use ::{{{crate::export}}}; // Nonsensical but perfectly legal nestnig
Loading