From 5953a348bd6102a868f303d3f732a6ec7d465833 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Tue, 14 Aug 2018 12:38:20 +0300 Subject: Less hackish impl structure --- crates/libeditor/src/symbols.rs | 26 ++- crates/libeditor/tests/test.rs | 6 +- crates/libsyntax2/src/ast/generated.rs | 292 ++++++++++++++++++++++++++++ crates/libsyntax2/src/ast/generated.rs.tera | 28 ++- crates/libsyntax2/src/ast/mod.rs | 23 +++ crates/libsyntax2/src/grammar.ron | 30 +++ 6 files changed, 386 insertions(+), 19 deletions(-) (limited to 'crates') diff --git a/crates/libeditor/src/symbols.rs b/crates/libeditor/src/symbols.rs index 43f4164da..8419f08e6 100644 --- a/crates/libeditor/src/symbols.rs +++ b/crates/libeditor/src/symbols.rs @@ -6,7 +6,6 @@ use libsyntax2::{ visit::{visitor, Visitor}, walk::{walk, WalkEvent, preorder}, }, - SyntaxKind::*, }; use TextRange; @@ -104,24 +103,21 @@ fn structure_node(node: SyntaxNodeRef) -> Option { .visit(decl::>) .visit(decl::>) .visit(|im: ast::ImplItem<_>| { - let mut label = String::new(); - let brace = im.syntax().children() - .find(|it| { - let stop = it.kind() == L_CURLY; - if !stop { - label.push_str(&it.text()); - } - stop - })?; - let navigation_range = TextRange::from_to( - im.syntax().range().start(), - brace.range().start(), - ); + let target_type = im.target_type()?; + let target_trait = im.target_trait(); + let label = match target_trait { + None => format!("impl {}", target_type.syntax().text()), + Some(t) => format!( + "impl {} for {}", + t.syntax().text(), + target_type.syntax().text(), + ), + }; let node = StructureNode { parent: None, label, - navigation_range, + navigation_range: target_type.syntax().range(), node_range: im.syntax().range(), kind: im.syntax().kind(), }; diff --git a/crates/libeditor/tests/test.rs b/crates/libeditor/tests/test.rs index 97fa30e1f..91df74bd6 100644 --- a/crates/libeditor/tests/test.rs +++ b/crates/libeditor/tests/test.rs @@ -66,7 +66,7 @@ fn test_foo() {} } #[test] -fn test_structure() { +fn test_file_structure() { let file = file(r#" struct Foo { x: i32 @@ -94,8 +94,8 @@ impl fmt::Debug for E {} StructureNode { parent: None, label: "T", navigation_range: [81; 82), node_range: [76; 88), kind: TYPE_DEF }, StructureNode { parent: None, label: "S", navigation_range: [96; 97), node_range: [89; 108), kind: STATIC_DEF }, StructureNode { parent: None, label: "C", navigation_range: [115; 116), node_range: [109; 127), kind: CONST_DEF }, - StructureNode { parent: None, label: "impl E ", navigation_range: [129; 136), node_range: [129; 138), kind: IMPL_ITEM }, - StructureNode { parent: None, label: "impl fmt::Debug for E ", navigation_range: [140; 162), node_range: [140; 164), kind: IMPL_ITEM }]"#, + StructureNode { parent: None, label: "impl E", navigation_range: [134; 135), node_range: [129; 138), kind: IMPL_ITEM }, + StructureNode { parent: None, label: "impl fmt::Debug for E", navigation_range: [160; 161), node_range: [140; 164), kind: IMPL_ITEM }]"#, &symbols, ) } diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 13668b803..3e6c673ab 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs @@ -5,6 +5,24 @@ use { SyntaxKind::*, }; +// ArrayType +#[derive(Debug, Clone, Copy)] +pub struct ArrayType> { + syntax: SyntaxNode, +} + +impl AstNode for ArrayType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + ARRAY_TYPE => Some(ArrayType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ArrayType {} + // ConstDef #[derive(Debug, Clone, Copy)] pub struct ConstDef> { @@ -24,6 +42,24 @@ impl AstNode for ConstDef { impl ast::NameOwner for ConstDef {} impl ConstDef {} +// DynTraitType +#[derive(Debug, Clone, Copy)] +pub struct DynTraitType> { + syntax: SyntaxNode, +} + +impl AstNode for DynTraitType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + DYN_TRAIT_TYPE => Some(DynTraitType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl DynTraitType {} + // EnumDef #[derive(Debug, Clone, Copy)] pub struct EnumDef> { @@ -86,6 +122,42 @@ impl AstNode for FnDef { impl ast::NameOwner for FnDef {} impl FnDef {} +// FnPointerType +#[derive(Debug, Clone, Copy)] +pub struct FnPointerType> { + syntax: SyntaxNode, +} + +impl AstNode for FnPointerType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + FN_POINTER_TYPE => Some(FnPointerType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl FnPointerType {} + +// ForType +#[derive(Debug, Clone, Copy)] +pub struct ForType> { + syntax: SyntaxNode, +} + +impl AstNode for ForType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + FOR_TYPE => Some(ForType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ForType {} + // ImplItem #[derive(Debug, Clone, Copy)] pub struct ImplItem> { @@ -104,6 +176,24 @@ impl AstNode for ImplItem { impl ImplItem {} +// ImplTraitType +#[derive(Debug, Clone, Copy)] +pub struct ImplTraitType> { + syntax: SyntaxNode, +} + +impl AstNode for ImplTraitType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + IMPL_TRAIT_TYPE => Some(ImplTraitType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ImplTraitType {} + // Module #[derive(Debug, Clone, Copy)] pub struct Module> { @@ -159,6 +249,132 @@ impl AstNode for NameRef { impl NameRef {} +// NeverType +#[derive(Debug, Clone, Copy)] +pub struct NeverType> { + syntax: SyntaxNode, +} + +impl AstNode for NeverType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + NEVER_TYPE => Some(NeverType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl NeverType {} + +// ParenType +#[derive(Debug, Clone, Copy)] +pub struct ParenType> { + syntax: SyntaxNode, +} + +impl AstNode for ParenType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + PAREN_TYPE => Some(ParenType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ParenType {} + +// PathType +#[derive(Debug, Clone, Copy)] +pub struct PathType> { + syntax: SyntaxNode, +} + +impl AstNode for PathType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + PATH_TYPE => Some(PathType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl PathType {} + +// PlaceholderType +#[derive(Debug, Clone, Copy)] +pub struct PlaceholderType> { + syntax: SyntaxNode, +} + +impl AstNode for PlaceholderType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + PLACEHOLDER_TYPE => Some(PlaceholderType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl PlaceholderType {} + +// PointerType +#[derive(Debug, Clone, Copy)] +pub struct PointerType> { + syntax: SyntaxNode, +} + +impl AstNode for PointerType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + POINTER_TYPE => Some(PointerType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl PointerType {} + +// ReferenceType +#[derive(Debug, Clone, Copy)] +pub struct ReferenceType> { + syntax: SyntaxNode, +} + +impl AstNode for ReferenceType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + REFERENCE_TYPE => Some(ReferenceType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl ReferenceType {} + +// SliceType +#[derive(Debug, Clone, Copy)] +pub struct SliceType> { + syntax: SyntaxNode, +} + +impl AstNode for SliceType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + SLICE_TYPE => Some(SliceType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl SliceType {} + // StaticDef #[derive(Debug, Clone, Copy)] pub struct StaticDef> { @@ -216,6 +432,24 @@ impl AstNode for TraitDef { impl ast::NameOwner for TraitDef {} impl TraitDef {} +// TupleType +#[derive(Debug, Clone, Copy)] +pub struct TupleType> { + syntax: SyntaxNode, +} + +impl AstNode for TupleType { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + TUPLE_TYPE => Some(TupleType { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl TupleType {} + // TypeDef #[derive(Debug, Clone, Copy)] pub struct TypeDef> { @@ -235,3 +469,61 @@ impl AstNode for TypeDef { impl ast::NameOwner for TypeDef {} impl TypeDef {} +// TypeRef +#[derive(Debug, Clone, Copy)] +pub enum TypeRef> { + ParenType(ParenType), + TupleType(TupleType), + NeverType(NeverType), + PathType(PathType), + PointerType(PointerType), + ArrayType(ArrayType), + SliceType(SliceType), + ReferenceType(ReferenceType), + PlaceholderType(PlaceholderType), + FnPointerType(FnPointerType), + ForType(ForType), + ImplTraitType(ImplTraitType), + DynTraitType(DynTraitType), +} + +impl AstNode for TypeRef { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + PAREN_TYPE => Some(TypeRef::ParenType(ParenType { syntax })), + TUPLE_TYPE => Some(TypeRef::TupleType(TupleType { syntax })), + NEVER_TYPE => Some(TypeRef::NeverType(NeverType { syntax })), + PATH_TYPE => Some(TypeRef::PathType(PathType { syntax })), + POINTER_TYPE => Some(TypeRef::PointerType(PointerType { syntax })), + ARRAY_TYPE => Some(TypeRef::ArrayType(ArrayType { syntax })), + SLICE_TYPE => Some(TypeRef::SliceType(SliceType { syntax })), + REFERENCE_TYPE => Some(TypeRef::ReferenceType(ReferenceType { syntax })), + PLACEHOLDER_TYPE => Some(TypeRef::PlaceholderType(PlaceholderType { syntax })), + FN_POINTER_TYPE => Some(TypeRef::FnPointerType(FnPointerType { syntax })), + FOR_TYPE => Some(TypeRef::ForType(ForType { syntax })), + IMPL_TRAIT_TYPE => Some(TypeRef::ImplTraitType(ImplTraitType { syntax })), + DYN_TRAIT_TYPE => Some(TypeRef::DynTraitType(DynTraitType { syntax })), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { + match self { + TypeRef::ParenType(inner) => inner.syntax(), + TypeRef::TupleType(inner) => inner.syntax(), + TypeRef::NeverType(inner) => inner.syntax(), + TypeRef::PathType(inner) => inner.syntax(), + TypeRef::PointerType(inner) => inner.syntax(), + TypeRef::ArrayType(inner) => inner.syntax(), + TypeRef::SliceType(inner) => inner.syntax(), + TypeRef::ReferenceType(inner) => inner.syntax(), + TypeRef::PlaceholderType(inner) => inner.syntax(), + TypeRef::FnPointerType(inner) => inner.syntax(), + TypeRef::ForType(inner) => inner.syntax(), + TypeRef::ImplTraitType(inner) => inner.syntax(), + TypeRef::DynTraitType(inner) => inner.syntax(), + } + } +} + +impl TypeRef {} + diff --git a/crates/libsyntax2/src/ast/generated.rs.tera b/crates/libsyntax2/src/ast/generated.rs.tera index 3d79b5543..f83da0326 100644 --- a/crates/libsyntax2/src/ast/generated.rs.tera +++ b/crates/libsyntax2/src/ast/generated.rs.tera @@ -6,6 +6,32 @@ use { }; {% for node, methods in ast %} // {{ node }} +{%- if methods.enum %} +#[derive(Debug, Clone, Copy)] +pub enum {{ node }}> { +{%- for kind in methods.enum %} + {{ kind }}({{ kind }}), +{%- endfor %} +} + +impl AstNode for {{ node }} { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { +{%- for kind in methods.enum %} + {{ kind | SCREAM }} => Some({{ node }}::{{ kind }}({{ kind }} { syntax })), +{%- endfor %} + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { + match self { +{%- for kind in methods.enum %} + {{ node }}::{{ kind }}(inner) => inner.syntax(), +{%- endfor %} + } + } +} +{% else %} #[derive(Debug, Clone, Copy)] pub struct {{ node }}> { syntax: SyntaxNode, @@ -20,7 +46,7 @@ impl AstNode for {{ node }} { } fn syntax(&self) -> &SyntaxNode { &self.syntax } } - +{% endif %} {% if methods.traits -%} {%- for t in methods.traits -%} impl ast::{{ t }} for {{ node }} {} diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index f001d340e..679e292a2 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs @@ -82,3 +82,26 @@ impl NameRef { ident.leaf_text().unwrap() } } + +impl ImplItem { + pub fn target_type(&self) -> Option> { + match self.target() { + (Some(t), None) | (_, Some(t)) => Some(t), + _ => None, + } + } + + pub fn target_trait(&self) -> Option> { + match self.target() { + (Some(t), Some(_)) => Some(t), + _ => None, + } + } + + fn target(&self) -> (Option>, Option>) { + let mut types = self.syntax().children().filter_map(TypeRef::cast); + let first = types.next(); + let second = types.next(); + (first, second) + } +} diff --git a/crates/libsyntax2/src/grammar.ron b/crates/libsyntax2/src/grammar.ron index ebd7d3943..3641b65e2 100644 --- a/crates/libsyntax2/src/grammar.ron +++ b/crates/libsyntax2/src/grammar.ron @@ -232,5 +232,35 @@ Grammar( "ImplItem": (), "Name": (), "NameRef": (), + + "ParenType": (), + "TupleType": (), + "NeverType": (), + "PathType": (), + "PointerType": (), + "ArrayType": (), + "SliceType": (), + "ReferenceType": (), + "PlaceholderType": (), + "FnPointerType": (), + "ForType": (), + "ImplTraitType": (), + "DynTraitType": (), + + "TypeRef": ( enum: [ + "ParenType", + "TupleType", + "NeverType", + "PathType", + "PointerType", + "ArrayType", + "SliceType", + "ReferenceType", + "PlaceholderType", + "FnPointerType", + "ForType", + "ImplTraitType", + "DynTraitType", + ]) }, ) -- cgit v1.2.3