From ae9530addc4c5e9bbfd5c0287d3c3adb2de95e40 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Fri, 28 Dec 2018 14:34:00 +0100 Subject: Add HIR for impl blocks Since we need to be able to go from def to containing impl block, as well as the other direction, and to find all impls for a certain type, a design similar to the one for modules, where we collect all impls for the whole crate and keep them in an arena, seemed fitting. The ImplBlock type, which provides the public interface, then consists only of an Arc to the arena containing all impls, and the index into it. --- crates/ra_syntax/src/ast/generated.rs | 40 +++++++++++++++++++++++++++++++++-- crates/ra_syntax/src/grammar.ron | 6 +++++- 2 files changed, 43 insertions(+), 3 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index c1c63f555..91de17ddf 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1442,7 +1442,39 @@ impl> ImplBlockNode { } -impl<'a> ImplBlock<'a> {} +impl<'a> ImplBlock<'a> { + pub fn item_list(self) -> Option> { + super::child_opt(self) + } +} + +// ImplItem +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum ImplItem<'a> { + FnDef(FnDef<'a>), + TypeDef(TypeDef<'a>), + ConstDef(ConstDef<'a>), +} + +impl<'a> AstNode<'a> for ImplItem<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + FN_DEF => Some(ImplItem::FnDef(FnDef { syntax })), + TYPE_DEF => Some(ImplItem::TypeDef(TypeDef { syntax })), + CONST_DEF => Some(ImplItem::ConstDef(ConstDef { syntax })), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { + match self { + ImplItem::FnDef(inner) => inner.syntax(), + ImplItem::TypeDef(inner) => inner.syntax(), + ImplItem::ConstDef(inner) => inner.syntax(), + } + } +} + +impl<'a> ImplItem<'a> {} // ImplTraitType #[derive(Debug, Clone, Copy,)] @@ -1555,7 +1587,11 @@ impl> ItemListNode { impl<'a> ast::FnDefOwner<'a> for ItemList<'a> {} impl<'a> ast::ModuleItemOwner<'a> for ItemList<'a> {} -impl<'a> ItemList<'a> {} +impl<'a> ItemList<'a> { + pub fn impl_items(self) -> impl Iterator> + 'a { + super::children(self) + } +} // Label #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 9a4a96fac..688a4af1e 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -284,6 +284,7 @@ Grammar( options: [ "ItemList" ] ), "ItemList": ( + collections: [["impl_items", "ImplItem"]], traits: [ "FnDefOwner", "ModuleItemOwner" ], ), "ConstDef": ( traits: [ @@ -307,7 +308,7 @@ Grammar( "AttrsOwner", "DocCommentsOwner" ] ), - "ImplBlock": (collections: []), + "ImplBlock": (options: ["ItemList"]), "ParenType": (options: ["TypeRef"]), "TupleType": ( collections: [["fields", "TypeRef"]] ), @@ -351,6 +352,9 @@ Grammar( enum: ["StructDef", "EnumDef", "FnDef", "TraitDef", "TypeDef", "ImplBlock", "UseItem", "ExternCrateItem", "ConstDef", "StaticDef", "Module" ] ), + "ImplItem": ( + enum: ["FnDef", "TypeDef", "ConstDef"] + ), "TupleExpr": (), "ArrayExpr": (), -- cgit v1.2.3 From 111126ed3c4f6358e0c833f80226e5192778f749 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 29 Dec 2018 21:32:07 +0100 Subject: Type the self parameter --- crates/ra_syntax/src/ast.rs | 31 +++++++++++++++++++++++ crates/ra_syntax/src/ast/generated.rs | 47 ++++++++++++++++++++++++++++++++++- crates/ra_syntax/src/grammar.ron | 3 ++- 3 files changed, 79 insertions(+), 2 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 7f986d322..2a3bd27e2 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -482,6 +482,37 @@ impl<'a> PrefixExpr<'a> { } } +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] +pub enum SelfParamFlavor { + /// self + Owned, + /// &self + Ref, + /// &mut self + MutRef, +} + +impl<'a> SelfParam<'a> { + pub fn flavor(&self) -> SelfParamFlavor { + let borrowed = self.syntax().children().any(|n| n.kind() == AMP); + if borrowed { + // check for a `mut` coming after the & -- `mut &self` != `&mut self` + if self + .syntax() + .children() + .skip_while(|n| n.kind() != AMP) + .any(|n| n.kind() == MUT_KW) + { + SelfParamFlavor::MutRef + } else { + SelfParamFlavor::Ref + } + } else { + SelfParamFlavor::Owned + } + } +} + #[test] fn test_doc_comment_of_items() { let file = SourceFileNode::parse( diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 91de17ddf..7df6a9c46 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -3488,6 +3488,43 @@ impl<'a> ReturnExpr<'a> { } } +// SelfKw +#[derive(Debug, Clone, Copy,)] +pub struct SelfKwNode = OwnedRoot> { + pub(crate) syntax: SyntaxNode, +} +pub type SelfKw<'a> = SelfKwNode>; + +impl, R2: TreeRoot> PartialEq> for SelfKwNode { + fn eq(&self, other: &SelfKwNode) -> bool { self.syntax == other.syntax } +} +impl> Eq for SelfKwNode {} +impl> Hash for SelfKwNode { + fn hash(&self, state: &mut H) { self.syntax.hash(state) } +} + +impl<'a> AstNode<'a> for SelfKw<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + SELF_KW => Some(SelfKw { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl> SelfKwNode { + pub fn borrowed(&self) -> SelfKw { + SelfKwNode { syntax: self.syntax.borrowed() } + } + pub fn owned(&self) -> SelfKwNode { + SelfKwNode { syntax: self.syntax.owned() } + } +} + + +impl<'a> SelfKw<'a> {} + // SelfParam #[derive(Debug, Clone, Copy,)] pub struct SelfParamNode = OwnedRoot> { @@ -3523,7 +3560,15 @@ impl> SelfParamNode { } -impl<'a> SelfParam<'a> {} +impl<'a> SelfParam<'a> { + pub fn type_ref(self) -> Option> { + super::child_opt(self) + } + + pub fn self_kw(self) -> Option> { + super::child_opt(self) + } +} // SlicePat #[derive(Debug, Clone, Copy,)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 688a4af1e..c55e9e07a 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -534,7 +534,8 @@ Grammar( ["params", "Param"] ] ), - "SelfParam": (), + "SelfParam": (options: ["TypeRef", "SelfKw"]), + "SelfKw": (), "Param": ( options: [ "Pat", "TypeRef" ], ), -- cgit v1.2.3 From bb029cd29b8496e69ca625fabc3612e4c1fe9142 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sun, 30 Dec 2018 18:38:44 +0100 Subject: Rename traits::impl_item -> impl_block as well, as well as the tests --- crates/ra_syntax/src/grammar/items.rs | 2 +- crates/ra_syntax/src/grammar/items/traits.rs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'crates/ra_syntax/src') diff --git a/crates/ra_syntax/src/grammar/items.rs b/crates/ra_syntax/src/grammar/items.rs index b9a00b565..265e84570 100644 --- a/crates/ra_syntax/src/grammar/items.rs +++ b/crates/ra_syntax/src/grammar/items.rs @@ -151,7 +151,7 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { // test unsafe_default_impl // unsafe default impl Foo {} IMPL_KW => { - traits::impl_item(p); + traits::impl_block(p); IMPL_BLOCK } _ => { diff --git a/crates/ra_syntax/src/grammar/items/traits.rs b/crates/ra_syntax/src/grammar/items/traits.rs index d4da8b2f7..0a0621753 100644 --- a/crates/ra_syntax/src/grammar/items/traits.rs +++ b/crates/ra_syntax/src/grammar/items/traits.rs @@ -40,9 +40,9 @@ pub(crate) fn trait_item_list(p: &mut Parser) { m.complete(p, ITEM_LIST); } -// test impl_item +// test impl_block // impl Foo {} -pub(super) fn impl_item(p: &mut Parser) { +pub(super) fn impl_block(p: &mut Parser) { assert!(p.at(IMPL_KW)); p.bump(); if choose_type_params_over_qpath(p) { @@ -52,7 +52,7 @@ pub(super) fn impl_item(p: &mut Parser) { // TODO: never type // impl ! {} - // test impl_item_neg + // test impl_block_neg // impl !Send for X {} p.eat(EXCL); impl_type(p); -- cgit v1.2.3