mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-12-25 12:33:33 +00:00
Merge #7288
7288: Handle self/super/crate in PathSegment as NameRef r=matklad a=Veykril Wrapping self/super/crate in NameRef as per https://github.com/rust-analyzer/rust-analyzer/pull/7261#issuecomment-760023172 Co-authored-by: Lukas Wirth <lukastw97@gmail.com>
This commit is contained in:
commit
8a869e870a
42 changed files with 258 additions and 254 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1837,9 +1837,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
|||
|
||||
[[package]]
|
||||
name = "ungrammar"
|
||||
version = "1.7.0"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7758fccf6038d5c368a17c7224abc85d6508d5ae266d5a3de25faac3cc168509"
|
||||
checksum = "e33a2183403af89252547c4219a06a6cc8aef6302fee67e10e8431866af3ee72"
|
||||
|
||||
[[package]]
|
||||
name = "unicase"
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
[workspace]
|
||||
members = [ "xtask/", "lib/*", "crates/*" ]
|
||||
members = ["xtask/", "lib/*", "crates/*"]
|
||||
|
||||
[profile.dev]
|
||||
# Disabling debug info speeds up builds a bunch,
|
||||
|
|
|
@ -750,6 +750,7 @@ to_def_impls![
|
|||
(crate::ConstParam, ast::ConstParam, const_param_to_def),
|
||||
(crate::MacroDef, ast::MacroRules, macro_rules_to_def),
|
||||
(crate::Local, ast::IdentPat, bind_pat_to_def),
|
||||
(crate::Local, ast::SelfParam, self_param_to_def),
|
||||
(crate::Label, ast::Label, label_to_def),
|
||||
];
|
||||
|
||||
|
|
|
@ -114,6 +114,15 @@ impl SourceToDefCtx<'_, '_> {
|
|||
let pat_id = source_map.node_pat(src.as_ref())?;
|
||||
Some((container, pat_id))
|
||||
}
|
||||
pub(super) fn self_param_to_def(
|
||||
&mut self,
|
||||
src: InFile<ast::SelfParam>,
|
||||
) -> Option<(DefWithBodyId, PatId)> {
|
||||
let container = self.find_pat_or_label_container(src.as_ref().map(|it| it.syntax()))?;
|
||||
let (_body, source_map) = self.db.body_with_source_map(container);
|
||||
let pat_id = source_map.node_self_param(src.as_ref())?;
|
||||
Some((container, pat_id))
|
||||
}
|
||||
pub(super) fn label_to_def(
|
||||
&mut self,
|
||||
src: InFile<ast::Label>,
|
||||
|
|
|
@ -258,7 +258,7 @@ impl Resolver {
|
|||
) -> Option<ResolveValueResult> {
|
||||
let n_segments = path.segments.len();
|
||||
let tmp = name![self];
|
||||
let first_name = if path.is_self() { &tmp } else { &path.segments.first()? };
|
||||
let first_name = if path.is_self() { &tmp } else { path.segments.first()? };
|
||||
let skip_to_mod = path.kind != PathKind::Plain && !path.is_self();
|
||||
for scope in self.scopes.iter().rev() {
|
||||
match scope {
|
||||
|
|
|
@ -18,7 +18,7 @@ use itertools::Itertools;
|
|||
use rustc_hash::FxHashSet;
|
||||
use syntax::{
|
||||
ast::{self, AstNode},
|
||||
SyntaxNode, TextRange, T,
|
||||
SyntaxNode, TextRange,
|
||||
};
|
||||
use text_edit::TextEdit;
|
||||
|
||||
|
@ -232,7 +232,7 @@ fn text_edit_for_remove_unnecessary_braces_with_self_in_use_statement(
|
|||
single_use_tree: &ast::UseTree,
|
||||
) -> Option<TextEdit> {
|
||||
let use_tree_list_node = single_use_tree.syntax().parent()?;
|
||||
if single_use_tree.path()?.segment()?.syntax().first_child_or_token()?.kind() == T![self] {
|
||||
if single_use_tree.path()?.segment()?.self_token().is_some() {
|
||||
let start = use_tree_list_node.prev_sibling_or_token()?.text_range().start();
|
||||
let end = use_tree_list_node.text_range().end();
|
||||
return Some(TextEdit::delete(TextRange::new(start, end)));
|
||||
|
|
|
@ -400,24 +400,33 @@ impl TryToNav for hir::GenericParam {
|
|||
impl ToNav for hir::Local {
|
||||
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
|
||||
let src = self.source(db);
|
||||
let node = match &src.value {
|
||||
Either::Left(bind_pat) => {
|
||||
bind_pat.name().map_or_else(|| bind_pat.syntax().clone(), |it| it.syntax().clone())
|
||||
}
|
||||
Either::Right(it) => it.syntax().clone(),
|
||||
let (node, focus_range) = match &src.value {
|
||||
Either::Left(bind_pat) => (
|
||||
bind_pat.syntax().clone(),
|
||||
bind_pat
|
||||
.name()
|
||||
.map(|it| src.with_value(&it.syntax().clone()).original_file_range(db).range),
|
||||
),
|
||||
Either::Right(it) => (it.syntax().clone(), it.self_token().map(|it| it.text_range())),
|
||||
};
|
||||
let full_range = src.with_value(&node).original_file_range(db);
|
||||
let name = match self.name(db) {
|
||||
Some(it) => it.to_string().into(),
|
||||
None => "".into(),
|
||||
};
|
||||
let kind = if self.is_param(db) { SymbolKind::ValueParam } else { SymbolKind::Local };
|
||||
let kind = if self.is_self(db) {
|
||||
SymbolKind::SelfParam
|
||||
} else if self.is_param(db) {
|
||||
SymbolKind::ValueParam
|
||||
} else {
|
||||
SymbolKind::Local
|
||||
};
|
||||
NavigationTarget {
|
||||
file_id: full_range.file_id,
|
||||
name,
|
||||
kind: Some(kind),
|
||||
full_range: full_range.range,
|
||||
focus_range: None,
|
||||
focus_range,
|
||||
container_name: None,
|
||||
description: None,
|
||||
docs: None,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use either::Either;
|
||||
use hir::{HasAttrs, ModuleDef, Semantics};
|
||||
use ide_db::{
|
||||
base_db::FileId,
|
||||
defs::{Definition, NameClass, NameRefClass},
|
||||
symbol_index, RootDatabase,
|
||||
};
|
||||
|
@ -13,7 +12,7 @@ use crate::{
|
|||
display::{ToNav, TryToNav},
|
||||
doc_links::extract_definitions_from_markdown,
|
||||
runnables::doc_owner_to_def,
|
||||
FilePosition, NavigationTarget, RangeInfo, SymbolKind,
|
||||
FilePosition, NavigationTarget, RangeInfo,
|
||||
};
|
||||
|
||||
// Feature: Go to Definition
|
||||
|
@ -49,19 +48,6 @@ pub(crate) fn goto_definition(
|
|||
let nav = def.try_to_nav(sema.db)?;
|
||||
vec![nav]
|
||||
},
|
||||
ast::SelfParam(self_param) => {
|
||||
vec![self_to_nav_target(self_param, position.file_id)?]
|
||||
},
|
||||
ast::PathSegment(segment) => {
|
||||
segment.self_token()?;
|
||||
let path = segment.parent_path();
|
||||
if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) {
|
||||
return None;
|
||||
}
|
||||
let func = segment.syntax().ancestors().find_map(ast::Fn::cast)?;
|
||||
let self_param = func.param_list()?.self_param()?;
|
||||
vec![self_to_nav_target(self_param, position.file_id)?]
|
||||
},
|
||||
ast::Lifetime(lt) => if let Some(name_class) = NameClass::classify_lifetime(&sema, <) {
|
||||
let def = name_class.referenced_or_defined(sema.db);
|
||||
let nav = def.try_to_nav(sema.db)?;
|
||||
|
@ -69,6 +55,11 @@ pub(crate) fn goto_definition(
|
|||
} else {
|
||||
reference_definition(&sema, Either::Left(<)).to_vec()
|
||||
},
|
||||
ast::SelfParam(self_param) => {
|
||||
let def = NameClass::classify_self_param(&sema, &self_param)?.referenced_or_defined(sema.db);
|
||||
let nav = def.try_to_nav(sema.db)?;
|
||||
vec![nav]
|
||||
},
|
||||
_ => return None,
|
||||
}
|
||||
};
|
||||
|
@ -134,20 +125,6 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
|
|||
}
|
||||
}
|
||||
|
||||
fn self_to_nav_target(self_param: ast::SelfParam, file_id: FileId) -> Option<NavigationTarget> {
|
||||
let self_token = self_param.self_token()?;
|
||||
Some(NavigationTarget {
|
||||
file_id,
|
||||
full_range: self_param.syntax().text_range(),
|
||||
focus_range: Some(self_token.text_range()),
|
||||
name: self_token.text().clone(),
|
||||
kind: Some(SymbolKind::SelfParam),
|
||||
container_name: None,
|
||||
description: None,
|
||||
docs: None,
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(crate) enum ReferenceResult {
|
||||
Exact(NavigationTarget),
|
||||
|
|
|
@ -98,6 +98,7 @@ pub(crate) fn hover(
|
|||
ast::NameRef(name_ref) => NameRefClass::classify(&sema, &name_ref).map(|d| d.referenced(sema.db)),
|
||||
ast::Lifetime(lifetime) => NameClass::classify_lifetime(&sema, &lifetime)
|
||||
.map_or_else(|| NameRefClass::classify_lifetime(&sema, &lifetime).map(|d| d.referenced(sema.db)), |d| d.defined(sema.db)),
|
||||
ast::SelfParam(self_param) => NameClass::classify_self_param(&sema, &self_param).and_then(|d| d.defined(sema.db)),
|
||||
_ => None,
|
||||
}
|
||||
};
|
||||
|
@ -134,17 +135,14 @@ pub(crate) fn hover(
|
|||
return None;
|
||||
}
|
||||
|
||||
let node = token.ancestors().find(|n| {
|
||||
ast::Expr::can_cast(n.kind())
|
||||
|| ast::Pat::can_cast(n.kind())
|
||||
|| ast::SelfParam::can_cast(n.kind())
|
||||
})?;
|
||||
let node = token
|
||||
.ancestors()
|
||||
.find(|n| ast::Expr::can_cast(n.kind()) || ast::Pat::can_cast(n.kind()))?;
|
||||
|
||||
let ty = match_ast! {
|
||||
match node {
|
||||
ast::Expr(it) => sema.type_of_expr(&it)?,
|
||||
ast::Pat(it) => sema.type_of_pat(&it)?,
|
||||
ast::SelfParam(self_param) => sema.type_of_self(&self_param)?,
|
||||
// If this node is a MACRO_CALL, it means that `descend_into_macros` failed to resolve.
|
||||
// (e.g expanding a builtin macro). So we give up here.
|
||||
ast::MacroCall(_it) => return None,
|
||||
|
@ -386,7 +384,7 @@ fn pick_best(tokens: TokenAtOffset<SyntaxToken>) -> Option<SyntaxToken> {
|
|||
return tokens.max_by_key(priority);
|
||||
fn priority(n: &SyntaxToken) -> usize {
|
||||
match n.kind() {
|
||||
IDENT | INT_NUMBER | LIFETIME_IDENT => 3,
|
||||
IDENT | INT_NUMBER | LIFETIME_IDENT | T![self] => 3,
|
||||
T!['('] | T![')'] => 2,
|
||||
kind if kind.is_trivia() => 0,
|
||||
_ => 1,
|
||||
|
@ -3129,6 +3127,39 @@ fn foo<T: Foo>(t: T$0){}
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_hover_self_has_go_to_type() {
|
||||
check_actions(
|
||||
r#"
|
||||
struct Foo;
|
||||
impl Foo {
|
||||
fn foo(&self$0) {}
|
||||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
[
|
||||
GoToType(
|
||||
[
|
||||
HoverGotoTypeData {
|
||||
mod_path: "test::Foo",
|
||||
nav: NavigationTarget {
|
||||
file_id: FileId(
|
||||
0,
|
||||
),
|
||||
full_range: 0..11,
|
||||
focus_range: 7..10,
|
||||
name: "Foo",
|
||||
kind: Struct,
|
||||
description: "struct Foo",
|
||||
},
|
||||
},
|
||||
],
|
||||
),
|
||||
]
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hover_displays_normalized_crate_names() {
|
||||
check(
|
||||
|
@ -3193,6 +3224,7 @@ impl Foo {
|
|||
"#,
|
||||
expect![[r#"
|
||||
*&self*
|
||||
|
||||
```rust
|
||||
&Foo
|
||||
```
|
||||
|
@ -3212,6 +3244,7 @@ impl Foo {
|
|||
"#,
|
||||
expect![[r#"
|
||||
*self: Arc<Foo>*
|
||||
|
||||
```rust
|
||||
Arc<Foo>
|
||||
```
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
pub(crate) mod rename;
|
||||
|
||||
use either::Either;
|
||||
use hir::Semantics;
|
||||
use ide_db::{
|
||||
base_db::FileId,
|
||||
|
@ -21,10 +22,10 @@ use ide_db::{
|
|||
use syntax::{
|
||||
algo::find_node_at_offset,
|
||||
ast::{self, NameOwner},
|
||||
match_ast, AstNode, SyntaxNode, TextRange, TokenAtOffset, T,
|
||||
AstNode, SyntaxNode, TextRange, TokenAtOffset, T,
|
||||
};
|
||||
|
||||
use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo, SymbolKind};
|
||||
use crate::{display::TryToNav, FilePosition, FileRange, NavigationTarget, RangeInfo};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ReferenceSearchResult {
|
||||
|
@ -90,10 +91,6 @@ pub(crate) fn find_all_refs(
|
|||
let _p = profile::span("find_all_refs");
|
||||
let syntax = sema.parse(position.file_id).syntax().clone();
|
||||
|
||||
if let Some(res) = try_find_self_references(&syntax, position) {
|
||||
return Some(res);
|
||||
}
|
||||
|
||||
let (opt_name, search_kind) = if let Some(name) =
|
||||
get_struct_def_name_for_struct_literal_search(&sema, &syntax, position)
|
||||
{
|
||||
|
@ -122,13 +119,16 @@ pub(crate) fn find_all_refs(
|
|||
|
||||
let mut kind = ReferenceKind::Other;
|
||||
if let Definition::Local(local) = def {
|
||||
if let either::Either::Left(pat) = local.source(sema.db).value {
|
||||
if matches!(
|
||||
pat.syntax().parent().and_then(ast::RecordPatField::cast),
|
||||
Some(pat_field) if pat_field.name_ref().is_none()
|
||||
) {
|
||||
kind = ReferenceKind::FieldShorthandForLocal;
|
||||
match local.source(sema.db).value {
|
||||
Either::Left(pat) => {
|
||||
if matches!(
|
||||
pat.syntax().parent().and_then(ast::RecordPatField::cast),
|
||||
Some(pat_field) if pat_field.name_ref().is_none()
|
||||
) {
|
||||
kind = ReferenceKind::FieldShorthandForLocal;
|
||||
}
|
||||
}
|
||||
Either::Right(_) => kind = ReferenceKind::SelfParam,
|
||||
}
|
||||
} else if matches!(
|
||||
def,
|
||||
|
@ -251,79 +251,6 @@ fn get_enum_def_name_for_struct_literal_search(
|
|||
None
|
||||
}
|
||||
|
||||
fn try_find_self_references(
|
||||
syntax: &SyntaxNode,
|
||||
position: FilePosition,
|
||||
) -> Option<RangeInfo<ReferenceSearchResult>> {
|
||||
let FilePosition { file_id, offset } = position;
|
||||
let self_token = syntax.token_at_offset(offset).find(|t| t.kind() == T![self])?;
|
||||
let parent = self_token.parent();
|
||||
match_ast! {
|
||||
match parent {
|
||||
ast::SelfParam(it) => (),
|
||||
ast::PathSegment(segment) => {
|
||||
segment.self_token()?;
|
||||
let path = segment.parent_path();
|
||||
if path.qualifier().is_some() && !ast::PathExpr::can_cast(path.syntax().parent()?.kind()) {
|
||||
return None;
|
||||
}
|
||||
},
|
||||
_ => return None,
|
||||
}
|
||||
};
|
||||
let function = parent.ancestors().find_map(ast::Fn::cast)?;
|
||||
let self_param = function.param_list()?.self_param()?;
|
||||
let param_self_token = self_param.self_token()?;
|
||||
|
||||
let declaration = Declaration {
|
||||
nav: NavigationTarget {
|
||||
file_id,
|
||||
full_range: self_param.syntax().text_range(),
|
||||
focus_range: Some(param_self_token.text_range()),
|
||||
name: param_self_token.text().clone(),
|
||||
kind: Some(SymbolKind::SelfParam),
|
||||
container_name: None,
|
||||
description: None,
|
||||
docs: None,
|
||||
},
|
||||
kind: ReferenceKind::SelfKw,
|
||||
access: Some(if self_param.mut_token().is_some() {
|
||||
ReferenceAccess::Write
|
||||
} else {
|
||||
ReferenceAccess::Read
|
||||
}),
|
||||
};
|
||||
let refs = function
|
||||
.body()
|
||||
.map(|body| {
|
||||
body.syntax()
|
||||
.descendants()
|
||||
.filter_map(ast::PathExpr::cast)
|
||||
.filter_map(|expr| {
|
||||
let path = expr.path()?;
|
||||
if path.qualifier().is_none() {
|
||||
path.segment()?.self_token()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.map(|token| FileReference {
|
||||
range: token.text_range(),
|
||||
kind: ReferenceKind::SelfKw,
|
||||
access: declaration.access, // FIXME: properly check access kind here instead of copying it from the declaration
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let mut references = UsageSearchResult::default();
|
||||
references.references.insert(file_id, refs);
|
||||
|
||||
Some(RangeInfo::new(
|
||||
param_self_token.text_range(),
|
||||
ReferenceSearchResult { declaration, references },
|
||||
))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use expect_test::{expect, Expect};
|
||||
|
@ -512,7 +439,7 @@ fn main() {
|
|||
i = 5;
|
||||
}"#,
|
||||
expect![[r#"
|
||||
i Local FileId(0) 24..25 Other Write
|
||||
i Local FileId(0) 20..25 24..25 Other Write
|
||||
|
||||
FileId(0) 50..51 Other Write
|
||||
FileId(0) 54..55 Other Read
|
||||
|
@ -536,7 +463,7 @@ fn bar() {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
spam Local FileId(0) 19..23 Other
|
||||
spam Local FileId(0) 19..23 19..23 Other
|
||||
|
||||
FileId(0) 34..38 Other Read
|
||||
FileId(0) 41..45 Other Read
|
||||
|
@ -551,7 +478,7 @@ fn bar() {
|
|||
fn foo(i : u32) -> u32 { i$0 }
|
||||
"#,
|
||||
expect![[r#"
|
||||
i ValueParam FileId(0) 7..8 Other
|
||||
i ValueParam FileId(0) 7..8 7..8 Other
|
||||
|
||||
FileId(0) 25..26 Other Read
|
||||
"#]],
|
||||
|
@ -565,7 +492,7 @@ fn foo(i : u32) -> u32 { i$0 }
|
|||
fn foo(i$0 : u32) -> u32 { i }
|
||||
"#,
|
||||
expect![[r#"
|
||||
i ValueParam FileId(0) 7..8 Other
|
||||
i ValueParam FileId(0) 7..8 7..8 Other
|
||||
|
||||
FileId(0) 25..26 Other Read
|
||||
"#]],
|
||||
|
@ -813,7 +740,7 @@ fn foo() {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
i Local FileId(0) 23..24 Other Write
|
||||
i Local FileId(0) 19..24 23..24 Other Write
|
||||
|
||||
FileId(0) 34..35 Other Write
|
||||
FileId(0) 38..39 Other Read
|
||||
|
@ -853,7 +780,7 @@ fn foo() {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
i Local FileId(0) 19..20 Other
|
||||
i Local FileId(0) 19..20 19..20 Other
|
||||
|
||||
FileId(0) 26..27 Other Write
|
||||
"#]],
|
||||
|
@ -995,10 +922,10 @@ impl Foo {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
self SelfParam FileId(0) 47..51 47..51 SelfKw Read
|
||||
self SelfParam FileId(0) 47..51 47..51 SelfParam
|
||||
|
||||
FileId(0) 71..75 SelfKw Read
|
||||
FileId(0) 152..156 SelfKw Read
|
||||
FileId(0) 71..75 Other Read
|
||||
FileId(0) 152..156 Other Read
|
||||
"#]],
|
||||
);
|
||||
}
|
||||
|
@ -1105,7 +1032,7 @@ fn main() {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
a Local FileId(0) 59..60 Other
|
||||
a Local FileId(0) 59..60 59..60 Other
|
||||
|
||||
FileId(0) 80..81 Other Read
|
||||
"#]],
|
||||
|
@ -1123,7 +1050,7 @@ fn main() {
|
|||
}
|
||||
"#,
|
||||
expect![[r#"
|
||||
a Local FileId(0) 59..60 Other
|
||||
a Local FileId(0) 59..60 59..60 Other
|
||||
|
||||
FileId(0) 80..81 Other Read
|
||||
"#]],
|
||||
|
|
|
@ -444,7 +444,7 @@ fn rename_reference(
|
|||
mark::hit!(rename_not_an_ident_ref);
|
||||
bail!("Invalid name `{}`: not an identifier", new_name)
|
||||
}
|
||||
(IdentifierKind::ToSelf, ReferenceKind::SelfKw) => {
|
||||
(IdentifierKind::ToSelf, ReferenceKind::SelfParam) => {
|
||||
unreachable!("rename_self_to_param should've been called instead")
|
||||
}
|
||||
(IdentifierKind::ToSelf, _) => {
|
||||
|
|
|
@ -226,35 +226,16 @@ pub(super) fn element(
|
|||
T![unsafe] => h | HlMod::Unsafe,
|
||||
T![true] | T![false] => HlTag::BoolLiteral.into(),
|
||||
T![self] => {
|
||||
let self_param_is_mut = element
|
||||
.parent()
|
||||
.and_then(ast::SelfParam::cast)
|
||||
.and_then(|p| p.mut_token())
|
||||
.is_some();
|
||||
let self_path = &element
|
||||
.parent()
|
||||
.as_ref()
|
||||
.and_then(SyntaxNode::parent)
|
||||
.and_then(ast::Path::cast)
|
||||
.and_then(|p| sema.resolve_path(&p));
|
||||
let mut h = HlTag::Symbol(SymbolKind::SelfParam).into();
|
||||
if self_param_is_mut
|
||||
|| matches!(self_path,
|
||||
Some(hir::PathResolution::Local(local))
|
||||
if local.is_self(db)
|
||||
&& (local.is_mut(db) || local.ty(db).is_mutable_reference())
|
||||
)
|
||||
let self_param = element.parent().and_then(ast::SelfParam::cast);
|
||||
if let Some(NameClass::Definition(def)) = self_param
|
||||
.and_then(|self_param| NameClass::classify_self_param(sema, &self_param))
|
||||
{
|
||||
h |= HlMod::Mutable
|
||||
highlight_def(db, def) | HlMod::Definition
|
||||
} else if element.ancestors().any(|it| it.kind() == USE_TREE) {
|
||||
HlTag::Symbol(SymbolKind::SelfParam).into()
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(hir::PathResolution::Local(local)) = self_path {
|
||||
if is_consumed_lvalue(element, &local, db) {
|
||||
h |= HlMod::Consuming;
|
||||
}
|
||||
}
|
||||
|
||||
h
|
||||
}
|
||||
T![ref] => element
|
||||
.parent()
|
||||
|
@ -345,7 +326,9 @@ fn highlight_def(db: &RootDatabase, def: Definition) -> Highlight {
|
|||
hir::GenericParam::LifetimeParam(_) => HlTag::Symbol(SymbolKind::LifetimeParam),
|
||||
},
|
||||
Definition::Local(local) => {
|
||||
let tag = if local.is_param(db) {
|
||||
let tag = if local.is_self(db) {
|
||||
HlTag::Symbol(SymbolKind::SelfParam)
|
||||
} else if local.is_param(db) {
|
||||
HlTag::Symbol(SymbolKind::ValueParam)
|
||||
} else {
|
||||
HlTag::Symbol(SymbolKind::Local)
|
||||
|
|
|
@ -42,16 +42,16 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
|
||||
<span class="keyword">impl</span> <span class="struct">foo</span> <span class="brace">{</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">trait</span> <span class="trait declaration">t</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration static associated">t_is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">t_is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">impl</span> <span class="trait">t</span> <span class="keyword">for</span> <span class="struct">foo</span> <span class="brace">{</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration static associated">is_static</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">is_not_static</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
</code></pre>
|
|
@ -93,7 +93,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="comment documentation">/// ```sh</span>
|
||||
<span class="comment documentation">/// echo 1</span>
|
||||
<span class="comment documentation">/// ```</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="brace">{</span>
|
||||
<span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration associated">foo</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">bool</span> <span class="brace">{</span>
|
||||
<span class="bool_literal">true</span>
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
|
|
@ -46,7 +46,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="keyword">struct</span> <span class="struct declaration">HasUnsafeFn</span><span class="semicolon">;</span>
|
||||
|
||||
<span class="keyword">impl</span> <span class="struct">HasUnsafeFn</span> <span class="brace">{</span>
|
||||
<span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword unsafe">unsafe</span> <span class="keyword">fn</span> <span class="function declaration associated unsafe">unsafe_method</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">struct</span> <span class="struct declaration">TypeForStaticMut</span> <span class="brace">{</span>
|
||||
|
@ -61,11 +61,11 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">trait</span> <span class="trait declaration">DoTheAutoref</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">impl</span> <span class="trait">DoTheAutoref</span> <span class="keyword">for</span> <span class="builtin_type">u16</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">calls_autoref</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||
|
|
|
@ -66,25 +66,25 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">trait</span> <span class="trait declaration">Bar</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="semicolon">;</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">impl</span> <span class="trait">Bar</span> <span class="keyword">for</span> <span class="struct">Foo</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">bar</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span>
|
||||
<span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">impl</span> <span class="struct">Foo</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">Foo</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">Foo</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span>
|
||||
<span class="value_param">f</span><span class="operator">.</span><span class="function consuming associated">baz</span><span class="parenthesis">(</span><span class="self_keyword mutable consuming">self</span><span class="parenthesis">)</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||
<span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">i32</span> <span class="brace">{</span>
|
||||
<span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
@ -95,15 +95,15 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">impl</span> <span class="struct">FooCopy</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">FooCopy</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">baz</span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">f</span><span class="colon">:</span> <span class="struct">FooCopy</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span>
|
||||
<span class="value_param">f</span><span class="operator">.</span><span class="function associated">baz</span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="parenthesis">)</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">qux</span><span class="parenthesis">(</span><span class="operator">&</span><span class="keyword">mut</span> <span class="self_keyword declaration mutable">self</span><span class="parenthesis">)</span> <span class="brace">{</span>
|
||||
<span class="self_keyword mutable">self</span><span class="operator">.</span><span class="field">x</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
|
||||
<span class="brace">}</span>
|
||||
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">quop</span><span class="parenthesis">(</span><span class="operator">&</span><span class="self_keyword declaration">self</span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="builtin_type">u32</span> <span class="brace">{</span>
|
||||
<span class="self_keyword">self</span><span class="operator">.</span><span class="field">x</span>
|
||||
<span class="brace">}</span>
|
||||
<span class="brace">}</span>
|
||||
|
@ -213,7 +213,7 @@ pre { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
|
|||
<span class="keyword">use</span> <span class="enum">Option</span><span class="operator">::</span><span class="punctuation">*</span><span class="semicolon">;</span>
|
||||
|
||||
<span class="keyword">impl</span><span class="angle"><</span><span class="type_param declaration">T</span><span class="angle">></span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">T</span><span class="angle">></span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="angle"><</span><span class="type_param declaration">U</span><span class="angle">></span><span class="parenthesis">(</span><span class="self_keyword">self</span><span class="comma">,</span> <span class="value_param declaration">other</span><span class="colon">:</span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">U</span><span class="angle">></span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="angle"><</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="comma">,</span> <span class="type_param">U</span><span class="parenthesis">)</span><span class="angle">></span> <span class="brace">{</span>
|
||||
<span class="keyword">fn</span> <span class="function declaration associated">and</span><span class="angle"><</span><span class="type_param declaration">U</span><span class="angle">></span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">other</span><span class="colon">:</span> <span class="enum">Option</span><span class="angle"><</span><span class="type_param">U</span><span class="angle">></span><span class="parenthesis">)</span> <span class="operator">-></span> <span class="enum">Option</span><span class="angle"><</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="comma">,</span> <span class="type_param">U</span><span class="parenthesis">)</span><span class="angle">></span> <span class="brace">{</span>
|
||||
<span class="keyword control">match</span> <span class="value_param">other</span> <span class="brace">{</span>
|
||||
<span class="enum_variant">None</span> <span class="operator">=></span> <span class="macro">unimplemented!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
|
||||
<span class="variable declaration">Nope</span> <span class="operator">=></span> <span class="variable">Nope</span><span class="comma">,</span>
|
||||
|
|
|
@ -10,7 +10,7 @@ use hir::{
|
|||
Module, ModuleDef, Name, PathResolution, Semantics, Visibility,
|
||||
};
|
||||
use syntax::{
|
||||
ast::{self, AstNode},
|
||||
ast::{self, AstNode, PathSegmentKind},
|
||||
match_ast, SyntaxKind, SyntaxNode,
|
||||
};
|
||||
|
||||
|
@ -117,6 +117,13 @@ impl NameClass {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn classify_self_param(
|
||||
sema: &Semantics<RootDatabase>,
|
||||
self_param: &ast::SelfParam,
|
||||
) -> Option<NameClass> {
|
||||
sema.to_def(self_param).map(Definition::Local).map(NameClass::Definition)
|
||||
}
|
||||
|
||||
pub fn classify(sema: &Semantics<RootDatabase>, name: &ast::Name) -> Option<NameClass> {
|
||||
let _p = profile::span("classify_name");
|
||||
|
||||
|
@ -135,24 +142,26 @@ impl NameClass {
|
|||
let path = use_tree.path()?;
|
||||
let path_segment = path.segment()?;
|
||||
let name_ref_class = path_segment
|
||||
.name_ref()
|
||||
// The rename might be from a `self` token, so fallback to the name higher
|
||||
// in the use tree.
|
||||
.or_else(||{
|
||||
if path_segment.self_token().is_none() {
|
||||
return None;
|
||||
.kind()
|
||||
.and_then(|kind| {
|
||||
match kind {
|
||||
// The rename might be from a `self` token, so fallback to the name higher
|
||||
// in the use tree.
|
||||
PathSegmentKind::SelfKw => {
|
||||
let use_tree = use_tree
|
||||
.syntax()
|
||||
.parent()
|
||||
.as_ref()
|
||||
// Skip over UseTreeList
|
||||
.and_then(SyntaxNode::parent)
|
||||
.and_then(ast::UseTree::cast)?;
|
||||
let path = use_tree.path()?;
|
||||
let path_segment = path.segment()?;
|
||||
path_segment.name_ref()
|
||||
},
|
||||
PathSegmentKind::Name(name_ref) => Some(name_ref),
|
||||
_ => return None,
|
||||
}
|
||||
|
||||
let use_tree = use_tree
|
||||
.syntax()
|
||||
.parent()
|
||||
.as_ref()
|
||||
// Skip over UseTreeList
|
||||
.and_then(SyntaxNode::parent)
|
||||
.and_then(ast::UseTree::cast)?;
|
||||
let path = use_tree.path()?;
|
||||
let path_segment = path.segment()?;
|
||||
path_segment.name_ref()
|
||||
})
|
||||
.and_then(|name_ref| NameRefClass::classify(sema, &name_ref))?;
|
||||
|
||||
|
|
|
@ -444,8 +444,14 @@ fn use_tree_path_cmp(a: &ast::Path, a_has_tl: bool, b: &ast::Path, b_has_tl: boo
|
|||
}
|
||||
|
||||
fn path_segment_cmp(a: &ast::PathSegment, b: &ast::PathSegment) -> Ordering {
|
||||
let a = a.name_ref();
|
||||
let b = b.name_ref();
|
||||
let a = a.kind().and_then(|kind| match kind {
|
||||
PathSegmentKind::Name(name_ref) => Some(name_ref),
|
||||
_ => None,
|
||||
});
|
||||
let b = b.kind().and_then(|kind| match kind {
|
||||
PathSegmentKind::Name(name_ref) => Some(name_ref),
|
||||
_ => None,
|
||||
});
|
||||
a.as_ref().map(ast::NameRef::text).cmp(&b.as_ref().map(ast::NameRef::text))
|
||||
}
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ pub enum ReferenceKind {
|
|||
FieldShorthandForLocal,
|
||||
StructLiteral,
|
||||
RecordFieldExprOrPat,
|
||||
SelfKw,
|
||||
SelfParam,
|
||||
EnumLiteral,
|
||||
Lifetime,
|
||||
Other,
|
||||
|
|
|
@ -82,7 +82,11 @@ fn path_segment(p: &mut Parser, mode: Mode, first: bool) {
|
|||
}
|
||||
// test crate_path
|
||||
// use crate::foo;
|
||||
T![self] | T![super] | T![crate] => p.bump_any(),
|
||||
T![self] | T![super] | T![crate] => {
|
||||
let m = p.start();
|
||||
p.bump_any();
|
||||
m.complete(p, NAME_REF);
|
||||
}
|
||||
_ => {
|
||||
p.err_recover("expected identifier", items::ITEM_RECOVERY_SET);
|
||||
if empty {
|
||||
|
|
|
@ -879,7 +879,7 @@ use crate::AstNode;
|
|||
|
||||
replacements:
|
||||
|
||||
Line 2: Node(NAME_REF@5..14) -> crate
|
||||
Line 2: Token(IDENT@5..14 "text_edit") -> crate
|
||||
Line 2: Token(IDENT@16..24 "TextEdit") -> AstNode
|
||||
Line 2: Token(WHITESPACE@25..27 "\n\n") -> "\n"
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@ pub struct NameRef {
|
|||
}
|
||||
impl NameRef {
|
||||
pub fn ident_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![ident]) }
|
||||
pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
|
||||
pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
|
||||
pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
|
||||
}
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct Lifetime {
|
||||
|
@ -42,9 +45,6 @@ pub struct PathSegment {
|
|||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl PathSegment {
|
||||
pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
|
||||
pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
|
||||
pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
|
||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
|
||||
pub fn generic_arg_list(&self) -> Option<GenericArgList> { support::child(&self.syntax) }
|
||||
|
|
|
@ -156,14 +156,28 @@ impl ast::PathSegment {
|
|||
.expect("segments are always nested in paths")
|
||||
}
|
||||
|
||||
pub fn crate_token(&self) -> Option<SyntaxToken> {
|
||||
self.name_ref().and_then(|it| it.crate_token())
|
||||
}
|
||||
|
||||
pub fn self_token(&self) -> Option<SyntaxToken> {
|
||||
self.name_ref().and_then(|it| it.self_token())
|
||||
}
|
||||
|
||||
pub fn super_token(&self) -> Option<SyntaxToken> {
|
||||
self.name_ref().and_then(|it| it.super_token())
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> Option<PathSegmentKind> {
|
||||
let res = if let Some(name_ref) = self.name_ref() {
|
||||
PathSegmentKind::Name(name_ref)
|
||||
match name_ref.syntax().first_token().map(|it| it.kind()) {
|
||||
Some(T![self]) => PathSegmentKind::SelfKw,
|
||||
Some(T![super]) => PathSegmentKind::SuperKw,
|
||||
Some(T![crate]) => PathSegmentKind::CrateKw,
|
||||
_ => PathSegmentKind::Name(name_ref),
|
||||
}
|
||||
} else {
|
||||
match self.syntax().first_child_or_token()?.kind() {
|
||||
T![self] => PathSegmentKind::SelfKw,
|
||||
T![super] => PathSegmentKind::SuperKw,
|
||||
T![crate] => PathSegmentKind::CrateKw,
|
||||
T![<] => {
|
||||
// <T> or <T as Trait>
|
||||
// T is any TypeRef, Trait has to be a PathType
|
||||
|
|
|
@ -256,7 +256,7 @@ fn validate_path_keywords(segment: ast::PathSegment, errors: &mut Vec<SyntaxErro
|
|||
));
|
||||
}
|
||||
} else if let Some(token) = segment.super_token() {
|
||||
if !all_supers(&path) {
|
||||
if segment.coloncolon_token().is_some() || !all_supers(&path) {
|
||||
errors.push(SyntaxError::new(
|
||||
"The `super` keyword may only be preceded by other `super`s",
|
||||
token.text_range(),
|
||||
|
|
|
@ -49,7 +49,8 @@ SOURCE_FILE@0..183
|
|||
PATH_EXPR@67..71
|
||||
PATH@67..71
|
||||
PATH_SEGMENT@67..71
|
||||
SELF_KW@67..71 "self"
|
||||
NAME_REF@67..71
|
||||
SELF_KW@67..71 "self"
|
||||
DOT@71..72 "."
|
||||
NAME_REF@72..78
|
||||
IDENT@72..78 "scopes"
|
||||
|
@ -66,7 +67,8 @@ SOURCE_FILE@0..183
|
|||
PATH_EXPR@94..98
|
||||
PATH@94..98
|
||||
PATH_SEGMENT@94..98
|
||||
SELF_KW@94..98 "self"
|
||||
NAME_REF@94..98
|
||||
SELF_KW@94..98 "self"
|
||||
DOT@98..99 "."
|
||||
NAME_REF@99..105
|
||||
IDENT@99..105 "scopes"
|
||||
|
|
|
@ -24,7 +24,8 @@ SOURCE_FILE@0..48
|
|||
PATH@22..32
|
||||
PATH@22..27
|
||||
PATH_SEGMENT@22..27
|
||||
CRATE_KW@22..27 "crate"
|
||||
NAME_REF@22..27
|
||||
CRATE_KW@22..27 "crate"
|
||||
COLON2@27..29 "::"
|
||||
PATH_SEGMENT@29..32
|
||||
NAME_REF@29..32
|
||||
|
|
|
@ -6,7 +6,8 @@ SOURCE_FILE@0..98
|
|||
PATH@4..11
|
||||
PATH_SEGMENT@4..11
|
||||
COLON2@4..6 "::"
|
||||
CRATE_KW@6..11 "crate"
|
||||
NAME_REF@6..11
|
||||
CRATE_KW@6..11 "crate"
|
||||
SEMICOLON@11..12 ";"
|
||||
WHITESPACE@12..13 "\n"
|
||||
USE@13..54
|
||||
|
@ -18,7 +19,8 @@ SOURCE_FILE@0..98
|
|||
USE_TREE@18..23
|
||||
PATH@18..23
|
||||
PATH_SEGMENT@18..23
|
||||
CRATE_KW@18..23 "crate"
|
||||
NAME_REF@18..23
|
||||
CRATE_KW@18..23 "crate"
|
||||
COMMA@23..24 ","
|
||||
WHITESPACE@24..25 " "
|
||||
USE_TREE@25..52
|
||||
|
@ -35,7 +37,8 @@ SOURCE_FILE@0..98
|
|||
PATH@31..41
|
||||
PATH@31..36
|
||||
PATH_SEGMENT@31..36
|
||||
CRATE_KW@31..36 "crate"
|
||||
NAME_REF@31..36
|
||||
CRATE_KW@31..36 "crate"
|
||||
COLON2@36..38 "::"
|
||||
PATH_SEGMENT@38..41
|
||||
NAME_REF@38..41
|
||||
|
@ -63,7 +66,8 @@ SOURCE_FILE@0..98
|
|||
IDENT@59..64 "hello"
|
||||
COLON2@64..66 "::"
|
||||
PATH_SEGMENT@66..71
|
||||
CRATE_KW@66..71 "crate"
|
||||
NAME_REF@66..71
|
||||
CRATE_KW@66..71 "crate"
|
||||
SEMICOLON@71..72 ";"
|
||||
WHITESPACE@72..73 "\n"
|
||||
USE@73..97
|
||||
|
@ -78,7 +82,8 @@ SOURCE_FILE@0..98
|
|||
IDENT@77..82 "hello"
|
||||
COLON2@82..84 "::"
|
||||
PATH_SEGMENT@84..89
|
||||
CRATE_KW@84..89 "crate"
|
||||
NAME_REF@84..89
|
||||
CRATE_KW@84..89 "crate"
|
||||
COLON2@89..91 "::"
|
||||
PATH_SEGMENT@91..96
|
||||
NAME_REF@91..96
|
||||
|
|
|
@ -6,7 +6,8 @@ SOURCE_FILE@0..67
|
|||
PATH@4..11
|
||||
PATH_SEGMENT@4..11
|
||||
COLON2@4..6 "::"
|
||||
SUPER_KW@6..11 "super"
|
||||
NAME_REF@6..11
|
||||
SUPER_KW@6..11 "super"
|
||||
SEMICOLON@11..12 ";"
|
||||
WHITESPACE@12..13 "\n"
|
||||
USE@13..26
|
||||
|
@ -20,7 +21,8 @@ SOURCE_FILE@0..67
|
|||
IDENT@17..18 "a"
|
||||
COLON2@18..20 "::"
|
||||
PATH_SEGMENT@20..25
|
||||
SUPER_KW@20..25 "super"
|
||||
NAME_REF@20..25
|
||||
SUPER_KW@20..25 "super"
|
||||
SEMICOLON@25..26 ";"
|
||||
WHITESPACE@26..27 "\n"
|
||||
USE@27..47
|
||||
|
@ -31,14 +33,16 @@ SOURCE_FILE@0..67
|
|||
PATH@31..39
|
||||
PATH@31..36
|
||||
PATH_SEGMENT@31..36
|
||||
SUPER_KW@31..36 "super"
|
||||
NAME_REF@31..36
|
||||
SUPER_KW@31..36 "super"
|
||||
COLON2@36..38 "::"
|
||||
PATH_SEGMENT@38..39
|
||||
NAME_REF@38..39
|
||||
IDENT@38..39 "a"
|
||||
COLON2@39..41 "::"
|
||||
PATH_SEGMENT@41..46
|
||||
SUPER_KW@41..46 "super"
|
||||
NAME_REF@41..46
|
||||
SUPER_KW@41..46 "super"
|
||||
SEMICOLON@46..47 ";"
|
||||
WHITESPACE@47..48 "\n"
|
||||
USE@48..66
|
||||
|
@ -56,7 +60,8 @@ SOURCE_FILE@0..67
|
|||
PATH@56..64
|
||||
PATH@56..61
|
||||
PATH_SEGMENT@56..61
|
||||
SUPER_KW@56..61 "super"
|
||||
NAME_REF@56..61
|
||||
SUPER_KW@56..61 "super"
|
||||
COLON2@61..63 "::"
|
||||
PATH_SEGMENT@63..64
|
||||
NAME_REF@63..64
|
||||
|
|
|
@ -6,7 +6,8 @@ SOURCE_FILE@0..25
|
|||
PATH@4..10
|
||||
PATH_SEGMENT@4..10
|
||||
COLON2@4..6 "::"
|
||||
SELF_KW@6..10 "self"
|
||||
NAME_REF@6..10
|
||||
SELF_KW@6..10 "self"
|
||||
SEMICOLON@10..11 ";"
|
||||
WHITESPACE@11..12 "\n"
|
||||
USE@12..24
|
||||
|
@ -20,7 +21,8 @@ SOURCE_FILE@0..25
|
|||
IDENT@16..17 "a"
|
||||
COLON2@17..19 "::"
|
||||
PATH_SEGMENT@19..23
|
||||
SELF_KW@19..23 "self"
|
||||
NAME_REF@19..23
|
||||
SELF_KW@19..23 "self"
|
||||
SEMICOLON@23..24 ";"
|
||||
WHITESPACE@24..25 "\n"
|
||||
error 6..10: The `self` keyword is only allowed as the first segment of a path
|
||||
|
|
|
@ -6,7 +6,8 @@ SOURCE_FILE@0..13
|
|||
PATH@4..11
|
||||
PATH@4..9
|
||||
PATH_SEGMENT@4..9
|
||||
CRATE_KW@4..9 "crate"
|
||||
NAME_REF@4..9
|
||||
CRATE_KW@4..9 "crate"
|
||||
COLON2@9..11 "::"
|
||||
SEMICOLON@11..12 ";"
|
||||
WHITESPACE@12..13 "\n"
|
||||
|
|
|
@ -11,7 +11,8 @@ SOURCE_FILE@0..248
|
|||
PATH@5..16
|
||||
PATH@5..10
|
||||
PATH_SEGMENT@5..10
|
||||
CRATE_KW@5..10 "crate"
|
||||
NAME_REF@5..10
|
||||
CRATE_KW@5..10 "crate"
|
||||
COLON2@10..12 "::"
|
||||
PATH_SEGMENT@12..16
|
||||
NAME_REF@12..16
|
||||
|
|
|
@ -42,7 +42,8 @@ SOURCE_FILE@0..71
|
|||
PATH@39..48
|
||||
PATH@39..43
|
||||
PATH_SEGMENT@39..43
|
||||
SELF_KW@39..43 "self"
|
||||
NAME_REF@39..43
|
||||
SELF_KW@39..43 "self"
|
||||
COLON2@43..45 "::"
|
||||
PATH_SEGMENT@45..48
|
||||
NAME_REF@45..48
|
||||
|
@ -61,7 +62,8 @@ SOURCE_FILE@0..71
|
|||
PATH@59..69
|
||||
PATH@59..64
|
||||
PATH_SEGMENT@59..64
|
||||
SUPER_KW@59..64 "super"
|
||||
NAME_REF@59..64
|
||||
SUPER_KW@59..64 "super"
|
||||
COLON2@64..66 "::"
|
||||
PATH_SEGMENT@66..69
|
||||
NAME_REF@66..69
|
||||
|
|
|
@ -43,7 +43,8 @@ SOURCE_FILE@0..70
|
|||
PATH@45..55
|
||||
PATH@45..50
|
||||
PATH_SEGMENT@45..50
|
||||
SUPER_KW@45..50 "super"
|
||||
NAME_REF@45..50
|
||||
SUPER_KW@45..50 "super"
|
||||
COLON2@50..52 "::"
|
||||
PATH_SEGMENT@52..55
|
||||
NAME_REF@52..55
|
||||
|
|
|
@ -6,7 +6,8 @@ SOURCE_FILE@0..16
|
|||
PATH@4..14
|
||||
PATH@4..9
|
||||
PATH_SEGMENT@4..9
|
||||
CRATE_KW@4..9 "crate"
|
||||
NAME_REF@4..9
|
||||
CRATE_KW@4..9 "crate"
|
||||
COLON2@9..11 "::"
|
||||
PATH_SEGMENT@11..14
|
||||
NAME_REF@11..14
|
||||
|
|
|
@ -5,7 +5,8 @@ SOURCE_FILE@0..37
|
|||
USE_TREE@4..17
|
||||
PATH@4..9
|
||||
PATH_SEGMENT@4..9
|
||||
CRATE_KW@4..9 "crate"
|
||||
NAME_REF@4..9
|
||||
CRATE_KW@4..9 "crate"
|
||||
COLON2@9..11 "::"
|
||||
USE_TREE_LIST@11..17
|
||||
L_CURLY@11..12 "{"
|
||||
|
@ -23,7 +24,8 @@ SOURCE_FILE@0..37
|
|||
USE_TREE@23..35
|
||||
PATH@23..27
|
||||
PATH_SEGMENT@23..27
|
||||
SELF_KW@23..27 "self"
|
||||
NAME_REF@23..27
|
||||
SELF_KW@23..27 "self"
|
||||
COLON2@27..29 "::"
|
||||
USE_TREE_LIST@29..35
|
||||
L_CURLY@29..30 "{"
|
||||
|
|
|
@ -30,7 +30,8 @@ SOURCE_FILE@0..41
|
|||
PATH@26..36
|
||||
PATH@26..31
|
||||
PATH_SEGMENT@26..31
|
||||
CRATE_KW@26..31 "crate"
|
||||
NAME_REF@26..31
|
||||
CRATE_KW@26..31 "crate"
|
||||
COLON2@31..33 "::"
|
||||
PATH_SEGMENT@33..36
|
||||
NAME_REF@33..36
|
||||
|
|
|
@ -17,7 +17,8 @@ SOURCE_FILE@0..27
|
|||
PATH@11..21
|
||||
PATH@11..16
|
||||
PATH_SEGMENT@11..16
|
||||
CRATE_KW@11..16 "crate"
|
||||
NAME_REF@11..16
|
||||
CRATE_KW@11..16 "crate"
|
||||
COLON2@16..18 "::"
|
||||
PATH_SEGMENT@18..21
|
||||
NAME_REF@18..21
|
||||
|
|
|
@ -16,7 +16,8 @@ SOURCE_FILE@0..53
|
|||
PATH@14..22
|
||||
PATH@14..19
|
||||
PATH_SEGMENT@14..19
|
||||
SUPER_KW@14..19 "super"
|
||||
NAME_REF@14..19
|
||||
SUPER_KW@14..19 "super"
|
||||
COLON2@19..21 "::"
|
||||
PATH_SEGMENT@21..22
|
||||
NAME_REF@21..22
|
||||
|
@ -42,7 +43,8 @@ SOURCE_FILE@0..53
|
|||
PATH@40..48
|
||||
PATH@40..45
|
||||
PATH_SEGMENT@40..45
|
||||
CRATE_KW@40..45 "crate"
|
||||
NAME_REF@40..45
|
||||
CRATE_KW@40..45 "crate"
|
||||
COLON2@45..47 "::"
|
||||
PATH_SEGMENT@47..48
|
||||
NAME_REF@47..48
|
||||
|
|
|
@ -6,7 +6,8 @@ SOURCE_FILE@0..38
|
|||
PATH@4..13
|
||||
PATH@4..8
|
||||
PATH_SEGMENT@4..8
|
||||
SELF_KW@4..8 "self"
|
||||
NAME_REF@4..8
|
||||
SELF_KW@4..8 "self"
|
||||
COLON2@8..10 "::"
|
||||
PATH_SEGMENT@10..13
|
||||
NAME_REF@10..13
|
||||
|
@ -21,10 +22,12 @@ SOURCE_FILE@0..38
|
|||
PATH@19..31
|
||||
PATH@19..24
|
||||
PATH_SEGMENT@19..24
|
||||
SUPER_KW@19..24 "super"
|
||||
NAME_REF@19..24
|
||||
SUPER_KW@19..24 "super"
|
||||
COLON2@24..26 "::"
|
||||
PATH_SEGMENT@26..31
|
||||
SUPER_KW@26..31 "super"
|
||||
NAME_REF@26..31
|
||||
SUPER_KW@26..31 "super"
|
||||
COLON2@31..33 "::"
|
||||
PATH_SEGMENT@33..36
|
||||
NAME_REF@33..36
|
||||
|
|
|
@ -187,7 +187,8 @@ SOURCE_FILE@0..250
|
|||
PATH@164..173
|
||||
PATH@164..168
|
||||
PATH_SEGMENT@164..168
|
||||
SELF_KW@164..168 "self"
|
||||
NAME_REF@164..168
|
||||
SELF_KW@164..168 "self"
|
||||
COLON2@168..170 "::"
|
||||
PATH_SEGMENT@170..173
|
||||
NAME_REF@170..173
|
||||
|
|
|
@ -25,7 +25,8 @@ SOURCE_FILE@0..62
|
|||
PATH@27..44
|
||||
PATH@27..32
|
||||
PATH_SEGMENT@27..32
|
||||
CRATE_KW@27..32 "crate"
|
||||
NAME_REF@27..32
|
||||
CRATE_KW@27..32 "crate"
|
||||
COLON2@32..34 "::"
|
||||
PATH_SEGMENT@34..44
|
||||
NAME_REF@34..44
|
||||
|
|
|
@ -15,7 +15,7 @@ flate2 = "1.0"
|
|||
pico-args = "0.3.1"
|
||||
proc-macro2 = "1.0.8"
|
||||
quote = "1.0.2"
|
||||
ungrammar = "1.7"
|
||||
ungrammar = "1.8"
|
||||
walkdir = "2.3.1"
|
||||
write-json = "0.1.0"
|
||||
xshell = "0.1"
|
||||
|
|
Loading…
Reference in a new issue