Wrap remaining self/super/crate in Name{Ref}

This commit is contained in:
Lukas Wirth 2021-01-15 21:07:38 +01:00
parent 8a869e870a
commit 98718e0544
28 changed files with 237 additions and 169 deletions

4
Cargo.lock generated
View file

@ -1837,9 +1837,9 @@ checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
[[package]]
name = "ungrammar"
version = "1.8.0"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e33a2183403af89252547c4219a06a6cc8aef6302fee67e10e8431866af3ee72"
checksum = "b137a875a3b942539dd04bd37d193649f5d67e11407186f5b9d63ae0332b1a93"
[[package]]
name = "unicase"

View file

@ -61,7 +61,7 @@ fn generate_fn_def_assist(
// compute the location which implicitly has the same lifetime as the anonymous lifetime
let loc_needing_lifetime = if let Some(self_param) = self_param {
// if we have a self reference, use that
Some(self_param.self_token()?.text_range().start())
Some(self_param.name()?.syntax().text_range().start())
} else {
// otherwise, if there's a single reference parameter without a named liftime, use that
let fn_params_without_lifetime: Vec<_> = param_list

View file

@ -26,7 +26,7 @@ use once_cell::race::OnceBool;
use stdx::format_to;
use syntax::{
algo,
ast::{self, AstNode},
ast::{self, AstNode, NameOwner},
SyntaxNode,
};
use tracing_subscriber::{layer::SubscriberExt, EnvFilter, Registry};
@ -153,7 +153,7 @@ fn infer_with_mismatches(content: &str, include_mismatches: bool) -> String {
});
for (node, ty) in &types {
let (range, text) = if let Some(self_param) = ast::SelfParam::cast(node.value.clone()) {
(self_param.self_token().unwrap().text_range(), "self".to_string())
(self_param.name().unwrap().syntax().text_range(), "self".to_string())
} else {
(node.value.text_range(), node.value.text().to_string().replace("\n", " "))
};

View file

@ -400,15 +400,13 @@ impl TryToNav for hir::GenericParam {
impl ToNav for hir::Local {
fn to_nav(&self, db: &RootDatabase) -> NavigationTarget {
let src = self.source(db);
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 (node, name) = match &src.value {
Either::Left(bind_pat) => (bind_pat.syntax().clone(), bind_pat.name()),
Either::Right(it) => (it.syntax().clone(), it.name()),
};
let focus_range =
name.map(|it| src.with_value(&it.syntax().clone()).original_file_range(db).range);
let full_range = src.with_value(&node).original_file_range(db);
let name = match self.name(db) {
Some(it) => it.to_string().into(),

View file

@ -55,11 +55,6 @@ pub(crate) fn goto_definition(
} else {
reference_definition(&sema, Either::Left(&lt)).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,
}
};

View file

@ -98,7 +98,6 @@ 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,
}
};
@ -3223,7 +3222,7 @@ impl Foo {
}
"#,
expect![[r#"
*&self*
*self*
```rust
&Foo
@ -3243,7 +3242,7 @@ impl Foo {
}
"#,
expect![[r#"
*self: Arc<Foo>*
*self*
```rust
Arc<Foo>

View file

@ -1,12 +1,9 @@
//! FIXME: write short doc here
use std::{
convert::TryInto,
fmt::{self, Display},
};
use std::fmt::{self, Display};
use hir::{Module, ModuleDef, ModuleSource, Semantics};
use ide_db::{
base_db::{AnchoredPathBuf, FileId, FileRange, SourceDatabaseExt},
base_db::{AnchoredPathBuf, FileId, FileRange},
defs::{Definition, NameClass, NameRefClass},
search::FileReference,
RootDatabase,
@ -14,14 +11,14 @@ use ide_db::{
use syntax::{
algo::find_node_at_offset,
ast::{self, NameOwner},
lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, SyntaxToken, T,
lex_single_syntax_kind, match_ast, AstNode, SyntaxKind, SyntaxNode, T,
};
use test_utils::mark;
use text_edit::TextEdit;
use crate::{
FilePosition, FileSystemEdit, RangeInfo, ReferenceKind, ReferenceSearchResult, SourceChange,
TextRange, TextSize,
TextRange,
};
type RenameResult<T> = Result<T, RenameError>;
@ -52,10 +49,6 @@ pub(crate) fn prepare_rename(
let syntax = source_file.syntax();
if let Some(module) = find_module_at_offset(&sema, position, syntax) {
rename_mod(&sema, position, module, "dummy")
} else if let Some(self_token) =
syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self])
{
rename_self_to_param(&sema, position, self_token, "dummy")
} else {
let RangeInfo { range, .. } = find_all_refs(&sema, position)?;
Ok(RangeInfo::new(range, SourceChange::default()))
@ -82,10 +75,6 @@ pub(crate) fn rename_with_semantics(
if let Some(module) = find_module_at_offset(&sema, position, syntax) {
rename_mod(&sema, position, module, new_name)
} else if let Some(self_token) =
syntax.token_at_offset(position.offset).find(|t| t.kind() == T![self])
{
rename_self_to_param(&sema, position, self_token, new_name)
} else {
rename_reference(&sema, position, new_name)
}
@ -108,7 +97,7 @@ pub(crate) fn will_rename_file(
Some(change)
}
#[derive(Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq)]
enum IdentifierKind {
Ident,
Lifetime,
@ -375,53 +364,50 @@ fn text_edit_from_self_param(
fn rename_self_to_param(
sema: &Semantics<RootDatabase>,
position: FilePosition,
self_token: SyntaxToken,
new_name: &str,
ident_kind: IdentifierKind,
range: TextRange,
refs: ReferenceSearchResult,
) -> Result<RangeInfo<SourceChange>, RenameError> {
let ident_kind = check_identifier(new_name)?;
match ident_kind {
IdentifierKind::Lifetime => bail!("Invalid name `{}`: not an identifier", new_name),
IdentifierKind::ToSelf => {
// no-op
mark::hit!(rename_self_to_self);
return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default()));
return Ok(RangeInfo::new(range, SourceChange::default()));
}
_ => (),
}
let source_file = sema.parse(position.file_id);
let syn = source_file.syntax();
let text = sema.db.file_text(position.file_id);
let fn_def = find_node_at_offset::<ast::Fn>(syn, position.offset)
.ok_or_else(|| format_err!("No surrounding method declaration found"))?;
let search_range = fn_def.syntax().text_range();
let mut source_change = SourceChange::default();
for (idx, _) in text.match_indices("self") {
let offset: TextSize = idx.try_into().unwrap();
if !search_range.contains_inclusive(offset) {
continue;
}
if let Some(ref usage) = syn.token_at_offset(offset).find(|t| t.kind() == T![self]) {
let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) {
text_edit_from_self_param(syn, self_param, new_name)
.ok_or_else(|| format_err!("No target type found"))?
} else {
TextEdit::replace(usage.text_range(), String::from(new_name))
};
if let Some(self_param) = fn_def.param_list().and_then(|it| it.self_param()) {
if self_param
.syntax()
.text_range()
.contains_range(refs.declaration().nav.focus_or_full_range())
{
let edit = text_edit_from_self_param(syn, &self_param, new_name)
.ok_or_else(|| format_err!("No target type found"))?;
source_change.insert_source_edit(position.file_id, edit);
source_change.extend(refs.references().iter().map(|(&file_id, references)| {
source_edit_from_references(sema, file_id, &references, new_name)
}));
if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore
{
bail!("Cannot rename reference to `_` as it is being referenced multiple times");
}
return Ok(RangeInfo::new(range, source_change));
}
}
if source_change.source_file_edits.len() > 1 && ident_kind == IdentifierKind::Underscore {
bail!("Cannot rename reference to `_` as it is being referenced multiple times");
}
let range = ast::SelfParam::cast(self_token.parent())
.map_or(self_token.text_range(), |p| p.syntax().text_range());
Ok(RangeInfo::new(range, source_change))
Err(format_err!("Method has no self param"))
}
fn rename_reference(
@ -444,8 +430,9 @@ fn rename_reference(
mark::hit!(rename_not_an_ident_ref);
bail!("Invalid name `{}`: not an identifier", new_name)
}
(IdentifierKind::ToSelf, ReferenceKind::SelfParam) => {
unreachable!("rename_self_to_param should've been called instead")
(_, ReferenceKind::SelfParam) => {
mark::hit!(rename_self_to_param);
return rename_self_to_param(sema, position, new_name, ident_kind, range, refs);
}
(IdentifierKind::ToSelf, _) => {
mark::hit!(rename_to_self);
@ -1350,6 +1337,7 @@ impl Foo {
#[test]
fn test_owned_self_to_parameter() {
mark::check!(rename_self_to_param);
check(
"foo",
r#"

View file

@ -68,7 +68,8 @@ pub(super) fn element(
NAME_REF => {
let name_ref = element.into_node().and_then(ast::NameRef::cast).unwrap();
highlight_func_by_name_ref(sema, &name_ref).unwrap_or_else(|| {
match NameRefClass::classify(sema, &name_ref) {
let is_self = name_ref.self_token().is_some();
let h = match NameRefClass::classify(sema, &name_ref) {
Some(name_kind) => match name_kind {
NameRefClass::ExternCrate(_) => HlTag::Symbol(SymbolKind::Module).into(),
NameRefClass::Definition(def) => {
@ -108,6 +109,11 @@ pub(super) fn element(
highlight_name_ref_by_syntax(name_ref, sema)
}
None => HlTag::UnresolvedReference.into(),
};
if h.tag == HlTag::Symbol(SymbolKind::Module) && is_self {
HlTag::Symbol(SymbolKind::SelfParam).into()
} else {
h
}
})
}
@ -225,18 +231,8 @@ pub(super) fn element(
T![for] if !is_child_of_impl(&element) => h | HlMod::ControlFlow,
T![unsafe] => h | HlMod::Unsafe,
T![true] | T![false] => HlTag::BoolLiteral.into(),
T![self] => {
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))
{
highlight_def(db, def) | HlMod::Definition
} else if element.ancestors().any(|it| it.kind() == USE_TREE) {
HlTag::Symbol(SymbolKind::SelfParam).into()
} else {
return None;
}
}
// self is handled as either a Name or NameRef already
T![self] => return None,
T![ref] => element
.parent()
.and_then(ast::IdentPat::cast)

View file

@ -117,13 +117,6 @@ 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");
@ -186,6 +179,10 @@ impl NameClass {
Some(NameClass::Definition(Definition::Local(local)))
},
ast::SelfParam(it) => {
let def = sema.to_def(&it)?;
Some(NameClass::Definition(Definition::Local(def.into())))
},
ast::RecordField(it) => {
let field: hir::Field = sema.to_def(&it)?;
Some(NameClass::Definition(Definition::Field(field)))

View file

@ -190,17 +190,25 @@ fn opt_visibility(p: &mut Parser) -> bool {
// test crate_visibility
// pub(crate) struct S;
// pub(self) struct S;
// pub(self) struct S;
// pub(self) struct S;
// pub(super) struct S;
// test pub_parens_typepath
// struct B(pub (super::A));
// struct B(pub (crate::A,));
T![crate] | T![self] | T![super] if p.nth(2) != T![:] => {
p.bump_any();
let path_m = p.start();
let path_segment_m = p.start();
let name_ref_m = p.start();
p.bump_any();
name_ref_m.complete(p, NAME_REF);
path_segment_m.complete(p, PATH_SEGMENT);
path_m.complete(p, PATH);
p.expect(T![')']);
}
// test crate_visibility_in
// pub(in super::A) struct S;
// pub(in crate) struct S;
T![in] => {
p.bump_any();
p.bump_any();

View file

@ -270,7 +270,9 @@ fn extern_crate(p: &mut Parser, m: Marker) {
p.bump(T![crate]);
if p.at(T![self]) {
let m = p.start();
p.bump(T![self]);
m.complete(p, NAME_REF);
} else {
name_ref(p);
}

View file

@ -156,7 +156,7 @@ fn variadic_param(p: &mut Parser) -> bool {
fn opt_self_param(p: &mut Parser, m: Marker) {
if p.at(T![self]) || p.at(T![mut]) && p.nth(1) == T![self] {
p.eat(T![mut]);
p.eat(T![self]);
self_as_name(p);
// test arb_self_types
// impl S {
// fn a(self: &Self) {}
@ -169,24 +169,29 @@ fn opt_self_param(p: &mut Parser, m: Marker) {
let la1 = p.nth(1);
let la2 = p.nth(2);
let la3 = p.nth(3);
let mut n_toks = match (p.current(), la1, la2, la3) {
(T![&], T![self], _, _) => 2,
(T![&], T![mut], T![self], _) => 3,
(T![&], LIFETIME_IDENT, T![self], _) => 3,
(T![&], LIFETIME_IDENT, T![mut], T![self]) => 4,
_ => return m.abandon(p),
};
p.bump_any();
if !matches!((p.current(), la1, la2, la3),
(T![&], T![self], _, _)
| (T![&], T![mut], T![self], _)
| (T![&], LIFETIME_IDENT, T![self], _)
| (T![&], LIFETIME_IDENT, T![mut], T![self])
) {
return m.abandon(p);
}
p.bump(T![&]);
if p.at(LIFETIME_IDENT) {
lifetime(p);
n_toks -= 1;
}
for _ in 1..n_toks {
p.bump_any();
}
p.eat(T![mut]);
self_as_name(p);
}
m.complete(p, SELF_PARAM);
if !p.at(T![')']) {
p.expect(T![,]);
}
}
fn self_as_name(p: &mut Parser) {
let m = p.start();
p.bump(T![self]);
m.complete(p, NAME);
}

View file

@ -11,6 +11,7 @@ pub struct Name {
}
impl Name {
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]) }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct NameRef {
@ -238,7 +239,6 @@ impl ExternCrate {
pub fn extern_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![extern]) }
pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
pub fn name_ref(&self) -> Option<NameRef> { support::child(&self.syntax) }
pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
pub fn rename(&self) -> Option<Rename> { support::child(&self.syntax) }
pub fn semicolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![;]) }
}
@ -406,9 +406,6 @@ pub struct Visibility {
impl Visibility {
pub fn pub_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![pub]) }
pub fn l_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T!['(']) }
pub fn super_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![super]) }
pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
pub fn crate_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![crate]) }
pub fn in_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![in]) }
pub fn path(&self) -> Option<Path> { support::child(&self.syntax) }
pub fn r_paren_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![')']) }
@ -492,11 +489,11 @@ pub struct SelfParam {
pub(crate) syntax: SyntaxNode,
}
impl ast::AttrsOwner for SelfParam {}
impl ast::NameOwner for SelfParam {}
impl SelfParam {
pub fn amp_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![&]) }
pub fn lifetime(&self) -> Option<Lifetime> { support::child(&self.syntax) }
pub fn mut_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![mut]) }
pub fn self_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![self]) }
pub fn colon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![:]) }
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
}

View file

@ -198,6 +198,13 @@ impl ast::Path {
pub fn parent_path(&self) -> Option<ast::Path> {
self.syntax().parent().and_then(ast::Path::cast)
}
pub fn as_single_segment(&self) -> Option<ast::PathSegment> {
match self.qualifier() {
Some(_) => None,
None => self.segment(),
}
}
}
impl ast::UseTreeList {
@ -448,16 +455,22 @@ pub enum VisibilityKind {
impl ast::Visibility {
pub fn kind(&self) -> VisibilityKind {
if let Some(path) = support::children(self.syntax()).next() {
VisibilityKind::In(path)
} else if self.crate_token().is_some() {
VisibilityKind::PubCrate
} else if self.super_token().is_some() {
VisibilityKind::PubSuper
} else if self.self_token().is_some() {
VisibilityKind::PubSelf
} else {
VisibilityKind::Pub
match self.path() {
Some(path) => {
if let Some(segment) =
path.as_single_segment().filter(|it| it.coloncolon_token().is_none())
{
if segment.crate_token().is_some() {
return VisibilityKind::PubCrate;
} else if segment.super_token().is_some() {
return VisibilityKind::PubSuper;
} else if segment.self_token().is_some() {
return VisibilityKind::PubSelf;
}
}
VisibilityKind::In(path)
}
None => VisibilityKind::Pub,
}
}
}

View file

@ -50,7 +50,10 @@ SOURCE_FILE@0..118
VISIBILITY@56..66
PUB_KW@56..59 "pub"
L_PAREN@59..60 "("
CRATE_KW@60..65 "crate"
PATH@60..65
PATH_SEGMENT@60..65
NAME_REF@60..65
CRATE_KW@60..65 "crate"
R_PAREN@65..66 ")"
WHITESPACE@66..67 " "
TYPE_KW@67..71 "type"
@ -69,7 +72,10 @@ SOURCE_FILE@0..118
VISIBILITY@86..96
PUB_KW@86..89 "pub"
L_PAREN@89..90 "("
CRATE_KW@90..95 "crate"
PATH@90..95
PATH_SEGMENT@90..95
NAME_REF@90..95
CRATE_KW@90..95 "crate"
R_PAREN@95..96 ")"
WHITESPACE@96..97 " "
CONST_KW@97..102 "const"

View file

@ -19,7 +19,8 @@ SOURCE_FILE@0..128
PARAM_LIST@17..23
L_PAREN@17..18 "("
SELF_PARAM@18..22
SELF_KW@18..22 "self"
NAME@18..22
SELF_KW@18..22 "self"
R_PAREN@22..23 ")"
WHITESPACE@23..24 " "
BLOCK_EXPR@24..26
@ -35,7 +36,8 @@ SOURCE_FILE@0..128
L_PAREN@35..36 "("
SELF_PARAM@36..41
AMP@36..37 "&"
SELF_KW@37..41 "self"
NAME@37..41
SELF_KW@37..41 "self"
COMMA@41..42 ","
R_PAREN@42..43 ")"
WHITESPACE@43..44 " "
@ -55,7 +57,8 @@ SOURCE_FILE@0..128
LIFETIME@57..59
LIFETIME_IDENT@57..59 "\'a"
WHITESPACE@59..60 " "
SELF_KW@60..64 "self"
NAME@60..64
SELF_KW@60..64 "self"
COMMA@64..65 ","
R_PAREN@65..66 ")"
WHITESPACE@66..67 " "
@ -77,7 +80,8 @@ SOURCE_FILE@0..128
WHITESPACE@82..83 " "
MUT_KW@83..86 "mut"
WHITESPACE@86..87 " "
SELF_KW@87..91 "self"
NAME@87..91
SELF_KW@87..91 "self"
COMMA@91..92 ","
WHITESPACE@92..93 " "
PARAM@93..99
@ -107,7 +111,8 @@ SOURCE_FILE@0..128
SELF_PARAM@113..121
MUT_KW@113..116 "mut"
WHITESPACE@116..117 " "
SELF_KW@117..121 "self"
NAME@117..121
SELF_KW@117..121 "self"
R_PAREN@121..122 ")"
WHITESPACE@122..123 " "
BLOCK_EXPR@123..125

View file

@ -19,7 +19,8 @@ SOURCE_FILE@0..69
PARAM_LIST@17..30
L_PAREN@17..18 "("
SELF_PARAM@18..29
SELF_KW@18..22 "self"
NAME@18..22
SELF_KW@18..22 "self"
COLON@22..23 ":"
WHITESPACE@23..24 " "
REF_TYPE@24..29
@ -45,7 +46,8 @@ SOURCE_FILE@0..69
SELF_PARAM@43..62
MUT_KW@43..46 "mut"
WHITESPACE@46..47 " "
SELF_KW@47..51 "self"
NAME@47..51
SELF_KW@47..51 "self"
COLON@51..52 ":"
WHITESPACE@52..53 " "
PATH_TYPE@53..62

View file

@ -67,7 +67,8 @@ SOURCE_FILE@0..89
L_PAREN@76..77 "("
SELF_PARAM@77..82
AMP@77..78 "&"
SELF_KW@78..82 "self"
NAME@78..82
SELF_KW@78..82 "self"
R_PAREN@82..83 ")"
WHITESPACE@83..84 " "
BLOCK_EXPR@84..86

View file

@ -1,9 +1,12 @@
SOURCE_FILE@0..81
SOURCE_FILE@0..62
STRUCT@0..20
VISIBILITY@0..10
PUB_KW@0..3 "pub"
L_PAREN@3..4 "("
CRATE_KW@4..9 "crate"
PATH@4..9
PATH_SEGMENT@4..9
NAME_REF@4..9
CRATE_KW@4..9 "crate"
R_PAREN@9..10 ")"
WHITESPACE@10..11 " "
STRUCT_KW@11..17 "struct"
@ -16,7 +19,10 @@ SOURCE_FILE@0..81
VISIBILITY@21..30
PUB_KW@21..24 "pub"
L_PAREN@24..25 "("
SELF_KW@25..29 "self"
PATH@25..29
PATH_SEGMENT@25..29
NAME_REF@25..29
SELF_KW@25..29 "self"
R_PAREN@29..30 ")"
WHITESPACE@30..31 " "
STRUCT_KW@31..37 "struct"
@ -25,29 +31,19 @@ SOURCE_FILE@0..81
IDENT@38..39 "S"
SEMICOLON@39..40 ";"
WHITESPACE@40..41 "\n"
STRUCT@41..60
VISIBILITY@41..50
STRUCT@41..61
VISIBILITY@41..51
PUB_KW@41..44 "pub"
L_PAREN@44..45 "("
SELF_KW@45..49 "self"
R_PAREN@49..50 ")"
WHITESPACE@50..51 " "
STRUCT_KW@51..57 "struct"
WHITESPACE@57..58 " "
NAME@58..59
IDENT@58..59 "S"
SEMICOLON@59..60 ";"
WHITESPACE@60..61 "\n"
STRUCT@61..80
VISIBILITY@61..70
PUB_KW@61..64 "pub"
L_PAREN@64..65 "("
SELF_KW@65..69 "self"
R_PAREN@69..70 ")"
WHITESPACE@70..71 " "
STRUCT_KW@71..77 "struct"
WHITESPACE@77..78 " "
NAME@78..79
IDENT@78..79 "S"
SEMICOLON@79..80 ";"
WHITESPACE@80..81 "\n"
PATH@45..50
PATH_SEGMENT@45..50
NAME_REF@45..50
SUPER_KW@45..50 "super"
R_PAREN@50..51 ")"
WHITESPACE@51..52 " "
STRUCT_KW@52..58 "struct"
WHITESPACE@58..59 " "
NAME@59..60
IDENT@59..60 "S"
SEMICOLON@60..61 ";"
WHITESPACE@61..62 "\n"

View file

@ -1,4 +1,3 @@
pub(crate) struct S;
pub(self) struct S;
pub(self) struct S;
pub(self) struct S;
pub(super) struct S;

View file

@ -16,7 +16,8 @@ SOURCE_FILE@0..26
IDENT@7..15 "must_use"
R_BRACK@15..16 "]"
WHITESPACE@16..17 " "
SELF_KW@17..21 "self"
NAME@17..21
SELF_KW@17..21 "self"
R_PAREN@21..22 ")"
WHITESPACE@22..23 " "
BLOCK_EXPR@23..25

View file

@ -0,0 +1,42 @@
SOURCE_FILE@0..51
STRUCT@0..26
VISIBILITY@0..16
PUB_KW@0..3 "pub"
L_PAREN@3..4 "("
IN_KW@4..6 "in"
WHITESPACE@6..7 " "
PATH@7..15
PATH@7..12
PATH_SEGMENT@7..12
NAME_REF@7..12
SUPER_KW@7..12 "super"
COLON2@12..14 "::"
PATH_SEGMENT@14..15
NAME_REF@14..15
IDENT@14..15 "A"
R_PAREN@15..16 ")"
WHITESPACE@16..17 " "
STRUCT_KW@17..23 "struct"
WHITESPACE@23..24 " "
NAME@24..25
IDENT@24..25 "S"
SEMICOLON@25..26 ";"
WHITESPACE@26..27 "\n"
STRUCT@27..50
VISIBILITY@27..40
PUB_KW@27..30 "pub"
L_PAREN@30..31 "("
IN_KW@31..33 "in"
WHITESPACE@33..34 " "
PATH@34..39
PATH_SEGMENT@34..39
NAME_REF@34..39
CRATE_KW@34..39 "crate"
R_PAREN@39..40 ")"
WHITESPACE@40..41 " "
STRUCT_KW@41..47 "struct"
WHITESPACE@47..48 " "
NAME@48..49
IDENT@48..49 "S"
SEMICOLON@49..50 ";"
WHITESPACE@50..51 "\n"

View file

@ -0,0 +1,2 @@
pub(in super::A) struct S;
pub(in crate) struct S;

View file

@ -28,7 +28,8 @@ SOURCE_FILE@0..69
WHITESPACE@49..50 " "
CRATE_KW@50..55 "crate"
WHITESPACE@55..56 " "
SELF_KW@56..60 "self"
NAME_REF@56..60
SELF_KW@56..60 "self"
WHITESPACE@60..61 " "
RENAME@61..67
AS_KW@61..63 "as"

View file

@ -32,7 +32,10 @@ SOURCE_FILE@0..98
VISIBILITY@24..34
PUB_KW@24..27 "pub"
L_PAREN@27..28 "("
CRATE_KW@28..33 "crate"
PATH@28..33
PATH_SEGMENT@28..33
NAME_REF@28..33
CRATE_KW@28..33 "crate"
R_PAREN@33..34 ")"
WHITESPACE@34..35 " "
FN_KW@35..37 "fn"
@ -51,7 +54,10 @@ SOURCE_FILE@0..98
VISIBILITY@45..55
PUB_KW@45..48 "pub"
L_PAREN@48..49 "("
SUPER_KW@49..54 "super"
PATH@49..54
PATH_SEGMENT@49..54
NAME_REF@49..54
SUPER_KW@49..54 "super"
R_PAREN@54..55 ")"
WHITESPACE@55..56 " "
FN_KW@56..58 "fn"

View file

@ -110,7 +110,8 @@ SOURCE_FILE@0..686
L_PAREN@558..559 "("
SELF_PARAM@559..564
AMP@559..560 "&"
SELF_KW@560..564 "self"
NAME@560..564
SELF_KW@560..564 "self"
COMMA@564..565 ","
WHITESPACE@565..566 " "
PARAM@566..600

View file

@ -281,7 +281,8 @@ SOURCE_FILE@0..519
IDENT@259..267 "must_use"
R_BRACK@267..268 "]"
WHITESPACE@268..269 " "
SELF_KW@269..273 "self"
NAME@269..273
SELF_KW@269..273 "self"
R_PAREN@273..274 ")"
WHITESPACE@274..275 " "
BLOCK_EXPR@275..277
@ -305,7 +306,8 @@ SOURCE_FILE@0..519
IDENT@291..295 "attr"
R_BRACK@295..296 "]"
WHITESPACE@296..297 " "
SELF_KW@297..301 "self"
NAME@297..301
SELF_KW@297..301 "self"
R_PAREN@301..302 ")"
WHITESPACE@302..303 " "
BLOCK_EXPR@303..305
@ -330,7 +332,8 @@ SOURCE_FILE@0..519
R_BRACK@323..324 "]"
WHITESPACE@324..325 " "
AMP@325..326 "&"
SELF_KW@326..330 "self"
NAME@326..330
SELF_KW@326..330 "self"
R_PAREN@330..331 ")"
WHITESPACE@331..332 " "
BLOCK_EXPR@332..334
@ -363,7 +366,8 @@ SOURCE_FILE@0..519
AMP@358..359 "&"
MUT_KW@359..362 "mut"
WHITESPACE@362..363 " "
SELF_KW@363..367 "self"
NAME@363..367
SELF_KW@363..367 "self"
R_PAREN@367..368 ")"
WHITESPACE@368..369 " "
BLOCK_EXPR@369..371
@ -397,7 +401,8 @@ SOURCE_FILE@0..519
LIFETIME@396..398
LIFETIME_IDENT@396..398 "\'a"
WHITESPACE@398..399 " "
SELF_KW@399..403 "self"
NAME@399..403
SELF_KW@399..403 "self"
R_PAREN@403..404 ")"
WHITESPACE@404..405 " "
BLOCK_EXPR@405..407
@ -433,7 +438,8 @@ SOURCE_FILE@0..519
WHITESPACE@434..435 " "
MUT_KW@435..438 "mut"
WHITESPACE@438..439 " "
SELF_KW@439..443 "self"
NAME@439..443
SELF_KW@439..443 "self"
R_PAREN@443..444 ")"
WHITESPACE@444..445 " "
BLOCK_EXPR@445..447
@ -457,7 +463,8 @@ SOURCE_FILE@0..519
IDENT@460..464 "attr"
R_BRACK@464..465 "]"
WHITESPACE@465..466 " "
SELF_KW@466..470 "self"
NAME@466..470
SELF_KW@466..470 "self"
COLON@470..471 ":"
WHITESPACE@471..472 " "
PATH_TYPE@472..476
@ -488,7 +495,8 @@ SOURCE_FILE@0..519
IDENT@493..497 "attr"
R_BRACK@497..498 "]"
WHITESPACE@498..499 " "
SELF_KW@499..503 "self"
NAME@499..503
SELF_KW@499..503 "self"
COLON@503..504 ":"
WHITESPACE@504..505 " "
PATH_TYPE@505..513

View file

@ -15,7 +15,7 @@ flate2 = "1.0"
pico-args = "0.3.1"
proc-macro2 = "1.0.8"
quote = "1.0.2"
ungrammar = "1.8"
ungrammar = "1.9"
walkdir = "2.3.1"
write-json = "0.1.0"
xshell = "0.1"