mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-11-01 20:31:59 +00:00
Give path segment type anchors their own grammar rule
This commit is contained in:
parent
d2164fe08b
commit
7c3de05e3a
14 changed files with 223 additions and 158 deletions
|
|
@ -39,7 +39,10 @@ PathSegment =
|
|||
| NameRef GenericArgList?
|
||||
| NameRef ParenthesizedArgList RetType?
|
||||
| NameRef ReturnTypeSyntax
|
||||
| '<' Type ('as' PathType)? '>'
|
||||
| TypeAnchor
|
||||
|
||||
TypeAnchor =
|
||||
'<' Type ('as' PathType)? '>'
|
||||
|
||||
ReturnTypeSyntax =
|
||||
'(' '..' ')'
|
||||
|
|
@ -98,7 +101,7 @@ WhereClause =
|
|||
'where' predicates:(WherePred (',' WherePred)* ','?)
|
||||
|
||||
WherePred =
|
||||
('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList?
|
||||
('for' GenericParamList)? (Lifetime | Type) ':' TypeBoundList?
|
||||
|
||||
|
||||
//*************************//
|
||||
|
|
|
|||
|
|
@ -1232,21 +1232,13 @@ impl PathSegment {
|
|||
support::child(&self.syntax)
|
||||
}
|
||||
#[inline]
|
||||
pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn ret_type(&self) -> Option<RetType> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn return_type_syntax(&self) -> Option<ReturnTypeSyntax> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||
pub fn type_anchor(&self) -> Option<TypeAnchor> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn coloncolon_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![::]) }
|
||||
#[inline]
|
||||
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
|
||||
#[inline]
|
||||
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
|
||||
#[inline]
|
||||
pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
|
||||
}
|
||||
pub struct PathType {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
|
|
@ -1739,6 +1731,21 @@ impl TypeAlias {
|
|||
#[inline]
|
||||
pub fn type_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![type]) }
|
||||
}
|
||||
pub struct TypeAnchor {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
impl TypeAnchor {
|
||||
#[inline]
|
||||
pub fn path_type(&self) -> Option<PathType> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn ty(&self) -> Option<Type> { support::child(&self.syntax) }
|
||||
#[inline]
|
||||
pub fn l_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![<]) }
|
||||
#[inline]
|
||||
pub fn r_angle_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![>]) }
|
||||
#[inline]
|
||||
pub fn as_token(&self) -> Option<SyntaxToken> { support::token(&self.syntax, T![as]) }
|
||||
}
|
||||
pub struct TypeArg {
|
||||
pub(crate) syntax: SyntaxNode,
|
||||
}
|
||||
|
|
@ -7108,6 +7115,42 @@ impl fmt::Debug for TypeAlias {
|
|||
f.debug_struct("TypeAlias").field("syntax", &self.syntax).finish()
|
||||
}
|
||||
}
|
||||
impl AstNode for TypeAnchor {
|
||||
#[inline]
|
||||
fn kind() -> SyntaxKind
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
TYPE_ANCHOR
|
||||
}
|
||||
#[inline]
|
||||
fn can_cast(kind: SyntaxKind) -> bool { kind == TYPE_ANCHOR }
|
||||
#[inline]
|
||||
fn cast(syntax: SyntaxNode) -> Option<Self> {
|
||||
if Self::can_cast(syntax.kind()) {
|
||||
Some(Self { syntax })
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
#[inline]
|
||||
fn syntax(&self) -> &SyntaxNode { &self.syntax }
|
||||
}
|
||||
impl hash::Hash for TypeAnchor {
|
||||
fn hash<H: hash::Hasher>(&self, state: &mut H) { self.syntax.hash(state); }
|
||||
}
|
||||
impl Eq for TypeAnchor {}
|
||||
impl PartialEq for TypeAnchor {
|
||||
fn eq(&self, other: &Self) -> bool { self.syntax == other.syntax }
|
||||
}
|
||||
impl Clone for TypeAnchor {
|
||||
fn clone(&self) -> Self { Self { syntax: self.syntax.clone() } }
|
||||
}
|
||||
impl fmt::Debug for TypeAnchor {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("TypeAnchor").field("syntax", &self.syntax).finish()
|
||||
}
|
||||
}
|
||||
impl AstNode for TypeArg {
|
||||
#[inline]
|
||||
fn kind() -> SyntaxKind
|
||||
|
|
@ -10624,6 +10667,11 @@ impl std::fmt::Display for TypeAlias {
|
|||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for TypeAnchor {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
}
|
||||
}
|
||||
impl std::fmt::Display for TypeArg {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(self.syntax(), f)
|
||||
|
|
|
|||
|
|
@ -276,18 +276,15 @@ impl ast::PathSegment {
|
|||
_ => PathSegmentKind::Name(name_ref),
|
||||
}
|
||||
} else {
|
||||
match self.syntax().first_child_or_token()?.kind() {
|
||||
T![<] => {
|
||||
// <T> or <T as Trait>
|
||||
// T is any TypeRef, Trait has to be a PathType
|
||||
let mut type_refs =
|
||||
self.syntax().children().filter(|node| ast::Type::can_cast(node.kind()));
|
||||
let type_ref = type_refs.next().and_then(ast::Type::cast);
|
||||
let trait_ref = type_refs.next().and_then(ast::PathType::cast);
|
||||
PathSegmentKind::Type { type_ref, trait_ref }
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
let anchor = self.type_anchor()?;
|
||||
// FIXME: Move this over to `ast::TypeAnchor`
|
||||
// <T> or <T as Trait>
|
||||
// T is any TypeRef, Trait has to be a PathType
|
||||
let mut type_refs =
|
||||
anchor.syntax().children().filter(|node| ast::Type::can_cast(node.kind()));
|
||||
let type_ref = type_refs.next().and_then(ast::Type::cast);
|
||||
let trait_ref = type_refs.next().and_then(ast::PathType::cast);
|
||||
PathSegmentKind::Type { type_ref, trait_ref }
|
||||
};
|
||||
Some(res)
|
||||
}
|
||||
|
|
@ -473,7 +470,7 @@ impl ast::Impl {
|
|||
// [#15778](https://github.com/rust-lang/rust-analyzer/issues/15778)
|
||||
impl ast::PathSegment {
|
||||
pub fn qualifying_trait(&self) -> Option<ast::PathType> {
|
||||
let mut path_types = support::children(self.syntax());
|
||||
let mut path_types = support::children(self.type_anchor()?.syntax());
|
||||
let first = path_types.next()?;
|
||||
path_types.next().or(Some(first))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue