From ac226021cfd26a9332b5971f3e05118d77822af5 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sun, 26 Aug 2018 12:09:28 +0300 Subject: scope based comletion --- crates/libsyntax2/src/algo/visit.rs | 58 ++++++ crates/libsyntax2/src/algo/walk.rs | 10 +- crates/libsyntax2/src/ast/generated.rs | 308 ++++++++++++++++++++++++++++- crates/libsyntax2/src/grammar.ron | 58 +++++- crates/libsyntax2/src/grammar/items/mod.rs | 4 +- 5 files changed, 422 insertions(+), 16 deletions(-) (limited to 'crates/libsyntax2/src') diff --git a/crates/libsyntax2/src/algo/visit.rs b/crates/libsyntax2/src/algo/visit.rs index a36c8f45e..9f1c127c7 100644 --- a/crates/libsyntax2/src/algo/visit.rs +++ b/crates/libsyntax2/src/algo/visit.rs @@ -6,6 +6,10 @@ pub fn visitor<'a, T>() -> impl Visitor<'a, Output=T> { EmptyVisitor { ph: PhantomData } } +pub fn visitor_ctx<'a, T, C>(ctx: C) -> impl VisitorCtx<'a, Output=T, Ctx=C> { + EmptyVisitorCtx { ph: PhantomData, ctx } +} + pub trait Visitor<'a>: Sized { type Output; fn accept(self, node: SyntaxNodeRef<'a>) -> Option; @@ -17,6 +21,18 @@ pub trait Visitor<'a>: Sized { } } +pub trait VisitorCtx<'a>: Sized { + type Output; + type Ctx; + fn accept(self, node: SyntaxNodeRef<'a>) -> Result; + fn visit(self, f: F) -> VisCtx + where N: AstNode<'a>, + F: FnOnce(N, Self::Ctx) -> Self::Output, + { + VisCtx { inner: self, f, ph: PhantomData } + } +} + #[derive(Debug)] struct EmptyVisitor { ph: PhantomData T> @@ -30,6 +46,21 @@ impl<'a, T> Visitor<'a> for EmptyVisitor { } } +#[derive(Debug)] +struct EmptyVisitorCtx { + ctx: C, + ph: PhantomData T>, +} + +impl<'a, T, C> VisitorCtx<'a> for EmptyVisitorCtx { + type Output = T; + type Ctx = C; + + fn accept(self, _node: SyntaxNodeRef<'a>) -> Result { + Err(self.ctx) + } +} + #[derive(Debug)] pub struct Vis { inner: V, @@ -50,3 +81,30 @@ impl<'a, V, N, F> Visitor<'a> for Vis inner.accept(node).or_else(|| N::cast(node).map(f)) } } + +#[derive(Debug)] +pub struct VisCtx { + inner: V, + f: F, + ph: PhantomData, +} + +impl<'a, V, N, F> VisitorCtx<'a> for VisCtx + where + V: VisitorCtx<'a>, + N: AstNode<'a>, + F: FnOnce(N, >::Ctx) -> >::Output, +{ + type Output = >::Output; + type Ctx = >::Ctx; + + fn accept(self, node: SyntaxNodeRef<'a>) -> Result { + let VisCtx { inner, f, .. } = self; + inner.accept(node).or_else(|ctx| + match N::cast(node) { + None => Err(ctx), + Some(node) => Ok(f(node, ctx)) + } + ) + } +} diff --git a/crates/libsyntax2/src/algo/walk.rs b/crates/libsyntax2/src/algo/walk.rs index d8797c453..536ee705f 100644 --- a/crates/libsyntax2/src/algo/walk.rs +++ b/crates/libsyntax2/src/algo/walk.rs @@ -17,19 +17,19 @@ pub enum WalkEvent<'a> { } pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator> { - generate(Some(WalkEvent::Enter(root)), |pos| { + generate(Some(WalkEvent::Enter(root)), move |pos| { let next = match *pos { WalkEvent::Enter(node) => match node.first_child() { Some(child) => WalkEvent::Enter(child), None => WalkEvent::Exit(node), }, WalkEvent::Exit(node) => { + if node == root { + return None; + } match node.next_sibling() { Some(sibling) => WalkEvent::Enter(sibling), - None => match node.parent() { - Some(node) => WalkEvent::Exit(node), - None => return None, - }, + None => WalkEvent::Exit(node.parent().unwrap()), } } }; diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 7d746a85b..6926c0535 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs @@ -80,6 +80,25 @@ impl<'a> AstNode<'a> for BinExpr<'a> { impl<'a> BinExpr<'a> {} +// BindPat +#[derive(Debug, Clone, Copy)] +pub struct BindPat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for BindPat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + BIND_PAT => Some(BindPat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> ast::NameOwner<'a> for BindPat<'a> {} +impl<'a> BindPat<'a> {} + // Block #[derive(Debug, Clone, Copy)] pub struct Block<'a> { @@ -96,7 +115,11 @@ impl<'a> AstNode<'a> for Block<'a> { fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } } -impl<'a> Block<'a> {} +impl<'a> Block<'a> { + pub fn let_stmts(self) -> impl Iterator> + 'a { + super::children(self) + } +} // BlockExpr #[derive(Debug, Clone, Copy)] @@ -378,6 +401,24 @@ impl<'a> AstNode<'a> for FieldExpr<'a> { impl<'a> FieldExpr<'a> {} +// FieldPatList +#[derive(Debug, Clone, Copy)] +pub struct FieldPatList<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for FieldPatList<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + FIELD_PAT_LIST => Some(FieldPatList { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> FieldPatList<'a> {} + // FnDef #[derive(Debug, Clone, Copy)] pub struct FnDef<'a> { @@ -397,7 +438,11 @@ impl<'a> AstNode<'a> for FnDef<'a> { impl<'a> ast::NameOwner<'a> for FnDef<'a> {} impl<'a> ast::TypeParamsOwner<'a> for FnDef<'a> {} impl<'a> ast::AttrsOwner<'a> for FnDef<'a> {} -impl<'a> FnDef<'a> {} +impl<'a> FnDef<'a> { + pub fn param_list(self) -> Option> { + super::child_opt(self) + } +} // FnPointerType #[derive(Debug, Clone, Copy)] @@ -561,6 +606,28 @@ impl<'a> AstNode<'a> for LambdaExpr<'a> { impl<'a> LambdaExpr<'a> {} +// LetStmt +#[derive(Debug, Clone, Copy)] +pub struct LetStmt<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for LetStmt<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + LET_STMT => Some(LetStmt { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> LetStmt<'a> { + pub fn pat(self) -> Option> { + super::child_opt(self) + } +} + // LoopExpr #[derive(Debug, Clone, Copy)] pub struct LoopExpr<'a> { @@ -831,6 +898,50 @@ impl<'a> ast::TypeParamsOwner<'a> for NominalDef<'a> {} impl<'a> ast::AttrsOwner<'a> for NominalDef<'a> {} impl<'a> NominalDef<'a> {} +// Param +#[derive(Debug, Clone, Copy)] +pub struct Param<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for Param<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + PARAM => Some(Param { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> Param<'a> { + pub fn pat(self) -> Option> { + super::child_opt(self) + } +} + +// ParamList +#[derive(Debug, Clone, Copy)] +pub struct ParamList<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for ParamList<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + PARAM_LIST => Some(ParamList { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> ParamList<'a> { + pub fn params(self) -> impl Iterator> + 'a { + super::children(self) + } +} + // ParenExpr #[derive(Debug, Clone, Copy)] pub struct ParenExpr<'a> { @@ -867,6 +978,55 @@ impl<'a> AstNode<'a> for ParenType<'a> { impl<'a> ParenType<'a> {} +// Pat +#[derive(Debug, Clone, Copy)] +pub enum Pat<'a> { + RefPat(RefPat<'a>), + BindPat(BindPat<'a>), + PlaceholderPat(PlaceholderPat<'a>), + PathPat(PathPat<'a>), + StructPat(StructPat<'a>), + FieldPatList(FieldPatList<'a>), + TupleStructPat(TupleStructPat<'a>), + TuplePat(TuplePat<'a>), + SlicePat(SlicePat<'a>), + RangePat(RangePat<'a>), +} + +impl<'a> AstNode<'a> for Pat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + REF_PAT => Some(Pat::RefPat(RefPat { syntax })), + BIND_PAT => Some(Pat::BindPat(BindPat { syntax })), + PLACEHOLDER_PAT => Some(Pat::PlaceholderPat(PlaceholderPat { syntax })), + PATH_PAT => Some(Pat::PathPat(PathPat { syntax })), + STRUCT_PAT => Some(Pat::StructPat(StructPat { syntax })), + FIELD_PAT_LIST => Some(Pat::FieldPatList(FieldPatList { syntax })), + TUPLE_STRUCT_PAT => Some(Pat::TupleStructPat(TupleStructPat { syntax })), + TUPLE_PAT => Some(Pat::TuplePat(TuplePat { syntax })), + SLICE_PAT => Some(Pat::SlicePat(SlicePat { syntax })), + RANGE_PAT => Some(Pat::RangePat(RangePat { syntax })), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { + match self { + Pat::RefPat(inner) => inner.syntax(), + Pat::BindPat(inner) => inner.syntax(), + Pat::PlaceholderPat(inner) => inner.syntax(), + Pat::PathPat(inner) => inner.syntax(), + Pat::StructPat(inner) => inner.syntax(), + Pat::FieldPatList(inner) => inner.syntax(), + Pat::TupleStructPat(inner) => inner.syntax(), + Pat::TuplePat(inner) => inner.syntax(), + Pat::SlicePat(inner) => inner.syntax(), + Pat::RangePat(inner) => inner.syntax(), + } + } +} + +impl<'a> Pat<'a> {} + // PathExpr #[derive(Debug, Clone, Copy)] pub struct PathExpr<'a> { @@ -885,6 +1045,24 @@ impl<'a> AstNode<'a> for PathExpr<'a> { impl<'a> PathExpr<'a> {} +// PathPat +#[derive(Debug, Clone, Copy)] +pub struct PathPat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for PathPat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + PATH_PAT => Some(PathPat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> PathPat<'a> {} + // PathType #[derive(Debug, Clone, Copy)] pub struct PathType<'a> { @@ -903,6 +1081,24 @@ impl<'a> AstNode<'a> for PathType<'a> { impl<'a> PathType<'a> {} +// PlaceholderPat +#[derive(Debug, Clone, Copy)] +pub struct PlaceholderPat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for PlaceholderPat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + PLACEHOLDER_PAT => Some(PlaceholderPat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> PlaceholderPat<'a> {} + // PlaceholderType #[derive(Debug, Clone, Copy)] pub struct PlaceholderType<'a> { @@ -975,6 +1171,24 @@ impl<'a> AstNode<'a> for RangeExpr<'a> { impl<'a> RangeExpr<'a> {} +// RangePat +#[derive(Debug, Clone, Copy)] +pub struct RangePat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for RangePat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + RANGE_PAT => Some(RangePat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> RangePat<'a> {} + // RefExpr #[derive(Debug, Clone, Copy)] pub struct RefExpr<'a> { @@ -993,6 +1207,24 @@ impl<'a> AstNode<'a> for RefExpr<'a> { impl<'a> RefExpr<'a> {} +// RefPat +#[derive(Debug, Clone, Copy)] +pub struct RefPat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for RefPat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + REF_PAT => Some(RefPat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> RefPat<'a> {} + // ReferenceType #[derive(Debug, Clone, Copy)] pub struct ReferenceType<'a> { @@ -1055,6 +1287,24 @@ impl<'a> Root<'a> { } } +// SlicePat +#[derive(Debug, Clone, Copy)] +pub struct SlicePat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for SlicePat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + SLICE_PAT => Some(SlicePat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> SlicePat<'a> {} + // SliceType #[derive(Debug, Clone, Copy)] pub struct SliceType<'a> { @@ -1137,6 +1387,24 @@ impl<'a> AstNode<'a> for StructLit<'a> { impl<'a> StructLit<'a> {} +// StructPat +#[derive(Debug, Clone, Copy)] +pub struct StructPat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for StructPat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + STRUCT_PAT => Some(StructPat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> StructPat<'a> {} + // TokenTree #[derive(Debug, Clone, Copy)] pub struct TokenTree<'a> { @@ -1211,6 +1479,42 @@ impl<'a> AstNode<'a> for TupleExpr<'a> { impl<'a> TupleExpr<'a> {} +// TuplePat +#[derive(Debug, Clone, Copy)] +pub struct TuplePat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for TuplePat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + TUPLE_PAT => Some(TuplePat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> TuplePat<'a> {} + +// TupleStructPat +#[derive(Debug, Clone, Copy)] +pub struct TupleStructPat<'a> { + syntax: SyntaxNodeRef<'a>, +} + +impl<'a> AstNode<'a> for TupleStructPat<'a> { + fn cast(syntax: SyntaxNodeRef<'a>) -> Option { + match syntax.kind() { + TUPLE_STRUCT_PAT => Some(TupleStructPat { syntax }), + _ => None, + } + } + fn syntax(self) -> SyntaxNodeRef<'a> { self.syntax } +} + +impl<'a> TupleStructPat<'a> {} + // TupleType #[derive(Debug, Clone, Copy)] pub struct TupleType<'a> { diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index a753d5e48..3a125ace6 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron @@ -241,11 +241,16 @@ Grammar( ["modules", "Module"], ] ), - "FnDef": ( traits: [ - "NameOwner", - "TypeParamsOwner", - "AttrsOwner", - ] ), + "FnDef": ( + traits: [ + "NameOwner", + "TypeParamsOwner", + "AttrsOwner", + ], + options: [ + ["param_list", "ParamList"] + ], + ), "StructDef": ( traits: [ "NameOwner", @@ -393,13 +398,52 @@ Grammar( ], ), + "RefPat": (), + "BindPat": ( traits: ["NameOwner"] ), + "PlaceholderPat": (), + "PathPat": (), + "StructPat": (), + "FieldPatList": (), + "TupleStructPat": (), + "TuplePat": (), + "SlicePat": (), + "RangePat": (), + + "Pat": ( + enum: [ + "RefPat", + "BindPat", + "PlaceholderPat", + "PathPat", + "StructPat", + "FieldPatList", + "TupleStructPat", + "TuplePat", + "SlicePat", + "RangePat", + ], + ), + "Name": (), "NameRef": (), "Attr": ( options: [ ["value", "TokenTree"] ] ), "TokenTree": (), "TypeParamList": ( collections: [ ["type_params", "TypeParam" ] ]), - "TypeParam": ( traits: ["NameOwner"]), + "TypeParam": ( traits: ["NameOwner"] ), "WhereClause": (), - "Block": (), + "LetStmt": ( options: [ ["pat", "Pat"] ]), + "Block": ( + collections: [ + ["let_stmts", "LetStmt"], + ] + ), + "ParamList": ( + collections: [ + ["params", "Param"] + ] + ), + "Param": ( + options: [["pat", "Pat"]], + ) }, ) diff --git a/crates/libsyntax2/src/grammar/items/mod.rs b/crates/libsyntax2/src/grammar/items/mod.rs index a285892df..7c6f7b63e 100644 --- a/crates/libsyntax2/src/grammar/items/mod.rs +++ b/crates/libsyntax2/src/grammar/items/mod.rs @@ -115,7 +115,7 @@ pub(super) fn maybe_item(p: &mut Parser, flavor: ItemFlavor) -> MaybeItem { // test unsafe_fn // unsafe fn foo() {} FN_KW => { - function(p, flavor); + fn_def(p, flavor); FN_DEF } @@ -227,7 +227,7 @@ fn extern_item_list(p: &mut Parser) { m.complete(p, EXTERN_ITEM_LIST); } -fn function(p: &mut Parser, flavor: ItemFlavor) { +fn fn_def(p: &mut Parser, flavor: ItemFlavor) { assert!(p.at(FN_KW)); p.bump(); -- cgit v1.2.3