Skip to content

Commit

Permalink
[move-ide] Added support for name chain completions in attributes (My…
Browse files Browse the repository at this point in the history
…stenLabs#18866)

## Description 

This PR adds support for handling name access chains in attributes. The
goal here is NOT to add more general support smart auto-completion for
attributes, though we can potentially do a lot of interesting things
there. Instead, the focus here is to finish `::` auto-completion started
in MystenLabs#18778

## Test plan 

All new and old tests must pass
  • Loading branch information
awelc authored Aug 1, 2024
1 parent 7efc10b commit 9702dfb
Show file tree
Hide file tree
Showing 4 changed files with 204 additions and 11 deletions.
58 changes: 55 additions & 3 deletions external-crates/move/crates/move-analyzer/src/symbols.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ use move_compiler::{
expansion::ast::{self as E, AbilitySet, ModuleIdent, ModuleIdent_, Value, Value_, Visibility},
linters::LintLevel,
naming::ast::{DatatypeTypeParameter, StructFields, Type, TypeName_, Type_, VariantFields},
parser::ast::{self as P, NameAccessChain, NameAccessChain_},
parser::ast as P,
shared::{
files::{FileId, MappedFiles},
unique_map::UniqueMap,
Expand Down Expand Up @@ -438,6 +438,13 @@ impl CursorContext {
None
}
}
CP::Attribute(attr_val) => {
if let P::AttributeValue_::ModuleAccess(chain) = &attr_val.value {
Some((chain.clone(), CT::All))
} else {
None
}
}
_ => None,
};
if let Some((c, _)) = &chain_info {
Expand All @@ -458,6 +465,7 @@ pub enum CursorPosition {
FieldDefn(P::Field),
Parameter(P::Var),
DefName,
Attribute(P::AttributeValue),
Unknown,
// FIXME: These two are currently unused because these forms don't have enough location
// recorded on them during parsing.
Expand Down Expand Up @@ -790,6 +798,10 @@ impl fmt::Display for CursorContext {
}?;
write!(f, "- position: ")?;
match position {
CursorPosition::Attribute(value) => {
writeln!(f, "attribute value")?;
writeln!(f, "- value: {:#?}", value)?;
}
CursorPosition::DefName => {
writeln!(f, "defn name")?;
}
Expand Down Expand Up @@ -2418,6 +2430,19 @@ impl<'a> ParsingSymbolicator<'a> {
}
}

fn attr_symbols(&mut self, sp!(_, attr): P::Attribute) {
use P::Attribute_ as A;
match attr {
A::Name(_) => (),
A::Assigned(_, v) => {
update_cursor!(self.cursor, *v, Attribute);
}
A::Parameterized(_, sp!(_, attributes)) => {
attributes.iter().for_each(|a| self.attr_symbols(a.clone()))
}
}
}

/// Get symbols for the whole module
fn mod_symbols(
&mut self,
Expand All @@ -2437,6 +2462,11 @@ impl<'a> ParsingSymbolicator<'a> {
let alias_lengths: BTreeMap<Position, usize> = BTreeMap::new();
let old_alias_lengths = std::mem::replace(&mut self.alias_lengths, alias_lengths);

mod_def
.attributes
.iter()
.for_each(|sp!(_, attrs)| attrs.iter().for_each(|a| self.attr_symbols(a.clone())));

for m in &mod_def.members {
use P::ModuleMember as MM;
match m {
Expand All @@ -2461,6 +2491,10 @@ impl<'a> ParsingSymbolicator<'a> {
}
};

fun.attributes.iter().for_each(|sp!(_, attrs)| {
attrs.iter().for_each(|a| self.attr_symbols(a.clone()))
});

for (_, x, t) in fun.signature.parameters.iter() {
update_cursor!(IDENT, self.cursor, x, Parameter);
self.type_symbols(t)
Expand Down Expand Up @@ -2488,6 +2522,11 @@ impl<'a> ParsingSymbolicator<'a> {
cursor.defn_name = Some(CursorDefinition::Struct(sdef.name));
}
};

sdef.attributes.iter().for_each(|sp!(_, attrs)| {
attrs.iter().for_each(|a| self.attr_symbols(a.clone()))
});

match &sdef.fields {
P::StructFields::Named(v) => v.iter().for_each(|(x, t)| {
self.field_defn(x);
Expand All @@ -2512,6 +2551,10 @@ impl<'a> ParsingSymbolicator<'a> {
}
};

edef.attributes.iter().for_each(|sp!(_, attrs)| {
attrs.iter().for_each(|a| self.attr_symbols(a.clone()))
});

let P::EnumDefinition { variants, .. } = edef;
for variant in variants {
let P::VariantDefinition { fields, .. } = variant;
Expand Down Expand Up @@ -2541,6 +2584,11 @@ impl<'a> ParsingSymbolicator<'a> {
cursor.defn_name = Some(CursorDefinition::Constant(c.name));
}
};

c.attributes.iter().for_each(|sp!(_, attrs)| {
attrs.iter().for_each(|a| self.attr_symbols(a.clone()))
});

self.type_symbols(&c.signature);
self.exp_symbols(&c.value);
}
Expand Down Expand Up @@ -2609,8 +2657,8 @@ impl<'a> ParsingSymbolicator<'a> {
/// Get symbols for an expression
fn exp_symbols(&mut self, exp: &P::Exp) {
use P::Exp_ as E;
fn last_chain_symbol_loc(sp!(_, chain): &NameAccessChain) -> Loc {
use NameAccessChain_ as NA;
fn last_chain_symbol_loc(sp!(_, chain): &P::NameAccessChain) -> Loc {
use P::NameAccessChain_ as NA;
match chain {
NA::Single(entry) => entry.name.loc,
NA::Path(path) => {
Expand Down Expand Up @@ -2809,6 +2857,10 @@ impl<'a> ParsingSymbolicator<'a> {

/// Get symbols for a use declaration
fn use_decl_symbols(&mut self, use_decl: &P::UseDecl) {
use_decl
.attributes
.iter()
.for_each(|sp!(_, attrs)| attrs.iter().for_each(|a| self.attr_symbols(a.clone())));
match &use_decl.use_ {
P::Use::ModuleUse(mod_ident, mod_use) => {
let mod_ident_str =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ Constant 'SOME_CONST'
Enum 'SomeEnum'
Struct 'SomeStruct'
Enum 'TargEnum'
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -69,6 +73,10 @@ Module 'other_mod_dot'

-- test 3 -------------------
use line: 21, use_col: 47
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -180,6 +188,10 @@ Module 'CC'
Module 'Self'
Module 'option'
Module 'vector'
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -361,6 +373,10 @@ Constant 'SOME_CONST'
Enum 'SomeEnum'
Struct 'SomeStruct'
Enum 'TargEnum'
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -405,6 +421,10 @@ EnumMember 'SomeVariant'

-- test 15 -------------------
use line: 28, use_col: 13
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -456,6 +476,10 @@ Constant 'SOME_CONST'
Enum 'SomeEnum'
Struct 'SomeStruct'
Enum 'TargEnum'
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -556,6 +580,10 @@ Constant 'SOME_CONST'
Enum 'SomeEnum'
Struct 'SomeStruct'
Enum 'TargEnum'
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -628,6 +656,103 @@ Keyword 'address'
TypeParameter 'SOME_TYPE'

-- test 24 -------------------
use line: 62, use_col: 43
Unit '0x1'
Unit '0xA'
Unit '0xCAFE'
Unit 'Completion'
Unit 'std'
Module 'Self'
Module 'option'
Module 'vector'
Struct 'CompletionStruct'
Struct 'Option'
Constant 'SOME_CONST'
Enum 'SomeEnum'
Struct 'SomeStruct'
Enum 'TargEnum'
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
TYPE : 'fun (SomeStruct)'
Method 'multi_colon_colon()'
INSERT TEXT: 'multi_colon_colon()'
TARGET : '(Completion::colon_colon::multi_colon_colon)'
TYPE : 'fun ()'
Method 'one_colon_colon()'
INSERT TEXT: 'one_colon_colon()'
TARGET : '(Completion::colon_colon::one_colon_colon)'
TYPE : 'fun ()'
Method 'sbar()'
INSERT TEXT: 'sbar(${1:_param1}, ${2:_param2})'
TARGET : '(Completion::colon_colon::sbar)'
TYPE : 'fun (u64, SomeStruct)'
Method 'sbaz()'
INSERT TEXT: 'sbaz()'
TARGET : '(Completion::colon_colon::sbaz)'
TYPE : 'fun ()'
Method 'single_ident()'
INSERT TEXT: 'single_ident()'
TARGET : '(Completion::colon_colon::single_ident)'
TYPE : 'fun ()'
Method 'targ_chain()'
INSERT TEXT: 'targ_chain()'
TARGET : '(Completion::colon_colon::targ_chain)'
TYPE : 'fun ()'
Method 'targ_type()'
INSERT TEXT: 'targ_type(${1:p})'
TARGET : '(Completion::colon_colon::targ_type)'
TYPE : 'fun <SOME_TYPE>(SOME_TYPE)'

-- test 25 -------------------
use line: 62, use_col: 49
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
TYPE : 'fun (SomeStruct)'
Method 'multi_colon_colon()'
INSERT TEXT: 'multi_colon_colon()'
TARGET : '(Completion::colon_colon::multi_colon_colon)'
TYPE : 'fun ()'
Method 'one_colon_colon()'
INSERT TEXT: 'one_colon_colon()'
TARGET : '(Completion::colon_colon::one_colon_colon)'
TYPE : 'fun ()'
Method 'sbar()'
INSERT TEXT: 'sbar(${1:_param1}, ${2:_param2})'
TARGET : '(Completion::colon_colon::sbar)'
TYPE : 'fun (u64, SomeStruct)'
Method 'sbaz()'
INSERT TEXT: 'sbaz()'
TARGET : '(Completion::colon_colon::sbaz)'
TYPE : 'fun ()'
Method 'single_ident()'
INSERT TEXT: 'single_ident()'
TARGET : '(Completion::colon_colon::single_ident)'
TYPE : 'fun ()'
Method 'targ_chain()'
INSERT TEXT: 'targ_chain()'
TARGET : '(Completion::colon_colon::targ_chain)'
TYPE : 'fun ()'
Method 'targ_type()'
INSERT TEXT: 'targ_type(${1:p})'
TARGET : '(Completion::colon_colon::targ_type)'
TYPE : 'fun <SOME_TYPE>(SOME_TYPE)'
Struct 'CompletionStruct'
Struct 'SomeStruct'
Enum 'SomeEnum'
Enum 'TargEnum'
Constant 'SOME_CONST'

-- test 26 -------------------
use line: 21, use_col: 33
Module 'colon_colon'
Module 'dot'
Expand All @@ -637,8 +762,12 @@ Module 'macro_dot'
Module 'object'
Module 'other_mod_dot'

-- test 25 -------------------
-- test 27 -------------------
use line: 21, use_col: 46
Method 'attr_chain()'
INSERT TEXT: 'attr_chain()'
TARGET : '(Completion::colon_colon::attr_chain)'
TYPE : 'fun ()'
Method 'complete_chains()'
INSERT TEXT: 'complete_chains(${1:s})'
TARGET : '(Completion::colon_colon::complete_chains)'
Expand Down Expand Up @@ -677,7 +806,7 @@ Enum 'SomeEnum'
Enum 'TargEnum'
Constant 'SOME_CONST'

-- test 26 -------------------
-- test 28 -------------------
use line: 21, use_col: 56
EnumMember 'SomeNamedVariant{}'
INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}'
Expand All @@ -686,7 +815,7 @@ EnumMember 'SomePositionalVariant()'
EnumMember 'SomeVariant'
INSERT TEXT: 'SomeVariant{}'

-- test 27 -------------------
-- test 29 -------------------
use line: 25, use_col: 16
Method 'and!()'
INSERT TEXT: 'and!(${1:o}, |${2}| ${3})'
Expand Down Expand Up @@ -805,7 +934,7 @@ Method 'to_vec()'
TARGET : '(std::option::to_vec)'
TYPE : 'fun <Element>(Option): vector<Element>'

-- test 28 -------------------
-- test 30 -------------------
use line: 26, use_col: 19
Method 'sha2_256()'
INSERT TEXT: 'sha2_256(${1:data})'
Expand All @@ -816,7 +945,7 @@ Method 'sha3_256()'
TARGET : '(std::hash::sha3_256)'
TYPE : 'fun (vector<u8>): vector<u8>'

-- test 29 -------------------
-- test 31 -------------------
use line: 27, use_col: 23
EnumMember 'SomeNamedVariant{}'
INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}'
Expand All @@ -825,7 +954,7 @@ EnumMember 'SomePositionalVariant()'
EnumMember 'SomeVariant'
INSERT TEXT: 'SomeVariant{}'

-- test 30 -------------------
-- test 32 -------------------
use line: 41, use_col: 20
Module 'colon_colon'
Module 'dot'
Expand All @@ -835,7 +964,7 @@ Module 'macro_dot'
Module 'object'
Module 'other_mod_dot'

-- test 31 -------------------
-- test 33 -------------------
use line: 44, use_col: 43
EnumMember 'SomeNamedVariant{}'
INSERT TEXT: 'SomeNamedVariant{${1:name1}, ${2:name2}}'
Expand All @@ -844,7 +973,7 @@ EnumMember 'SomePositionalVariant()'
EnumMember 'SomeVariant'
INSERT TEXT: 'SomeVariant{}'

-- test 32 -------------------
-- test 34 -------------------
use line: 55, use_col: 38
EnumMember 'Variant{}'
INSERT TEXT: 'Variant{${1:field}}'
Expand Down
Loading

0 comments on commit 9702dfb

Please sign in to comment.