1use cairo_lang_utils::LookupIntern;
2use smol_str::SmolStr;
3
4use super::ast::{
5 self, FunctionDeclaration, FunctionDeclarationGreen, FunctionWithBody, FunctionWithBodyPtr,
6 ImplItem, ItemConstant, ItemEnum, ItemExternFunction, ItemExternFunctionPtr, ItemExternType,
7 ItemImpl, ItemImplAlias, ItemInlineMacro, ItemModule, ItemStruct, ItemTrait, ItemTypeAlias,
8 ItemUse, Member, Modifier, ModuleItem, OptionArgListParenthesized, Statement, StatementBreak,
9 StatementContinue, StatementExpr, StatementLet, StatementReturn, TerminalIdentifierGreen,
10 TokenIdentifierGreen, TraitItem, TraitItemConstant, TraitItemFunction, TraitItemFunctionPtr,
11 TraitItemImpl, TraitItemType, UsePathLeaf, Variant, WrappedArgList,
12};
13use super::db::SyntaxGroup;
14use super::ids::SyntaxStablePtrId;
15use super::kind::SyntaxKind;
16use super::{SyntaxNode, Terminal, TypedStablePtr, TypedSyntaxNode};
17use crate::node::ast::{Attribute, AttributeList};
18use crate::node::green::GreenNodeDetails;
19
20#[cfg(test)]
21#[path = "helpers_test.rs"]
22mod test;
23
24pub trait GetIdentifier {
25 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr;
26}
27impl ast::UsePathLeafPtr {
28 pub fn name_green(&self, _syntax_db: &dyn SyntaxGroup) -> Self {
29 *self
30 }
31}
32impl GetIdentifier for ast::UsePathLeafPtr {
33 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
34 let alias_clause_green = self.alias_clause_green(db).0;
35 let green_node = alias_clause_green.lookup_intern(db);
36 let children = match &green_node.details {
37 GreenNodeDetails::Node { children, width: _ } => children,
38 _ => panic!("Unexpected token"),
39 };
40 if !children.is_empty() {
41 return ast::TerminalIdentifierGreen(children[ast::AliasClause::INDEX_ALIAS])
42 .identifier(db);
43 }
44 let ident_green = self.ident_green(db);
45 ident_green.identifier(db)
46 }
47}
48impl GetIdentifier for ast::PathSegmentGreen {
49 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
51 let green_node = self.0.lookup_intern(db);
52 let children = match &green_node.details {
53 GreenNodeDetails::Node { children, width: _ } => children,
54 _ => panic!("Unexpected token"),
55 };
56 let identifier = ast::TerminalIdentifierGreen(children[0]);
57 identifier.identifier(db)
58 }
59}
60impl GetIdentifier for ast::ExprPathGreen {
61 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
63 let green_node = self.0.lookup_intern(db);
64 let children = match &green_node.details {
65 GreenNodeDetails::Node { children, width: _ } => children,
66 _ => panic!("Unexpected token"),
67 };
68 assert_eq!(children.len() & 1, 1, "Expected an odd number of elements in the path.");
69 let segment_green = ast::PathSegmentGreen(*children.last().unwrap());
70 segment_green.identifier(db)
71 }
72}
73impl GetIdentifier for ast::TerminalIdentifierGreen {
74 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
75 match &self.0.lookup_intern(db).details {
76 GreenNodeDetails::Token(_) => "Unexpected token".into(),
77 GreenNodeDetails::Node { children, width: _ } => {
78 TokenIdentifierGreen(children[1]).text(db)
79 }
80 }
81 }
82}
83impl GetIdentifier for ast::ExprPath {
84 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
86 self.elements(db).last().cloned().unwrap().identifier(db)
87 }
88}
89
90pub trait PathSegmentEx {
92 fn identifier_ast(&self, db: &dyn SyntaxGroup) -> ast::TerminalIdentifier;
93 fn generic_args(&self, db: &dyn SyntaxGroup) -> Option<Vec<ast::GenericArg>>;
94}
95impl PathSegmentEx for ast::PathSegment {
96 fn identifier_ast(&self, db: &dyn SyntaxGroup) -> ast::TerminalIdentifier {
98 match self {
99 ast::PathSegment::Simple(segment) => segment.ident(db),
100 ast::PathSegment::WithGenericArgs(segment) => segment.ident(db),
101 }
102 }
103 fn generic_args(&self, db: &dyn SyntaxGroup) -> Option<Vec<ast::GenericArg>> {
104 match self {
105 ast::PathSegment::Simple(_) => None,
106 ast::PathSegment::WithGenericArgs(segment) => {
107 Some(segment.generic_args(db).generic_args(db).elements(db))
108 }
109 }
110 }
111}
112impl GetIdentifier for ast::PathSegment {
113 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
115 self.identifier_ast(db).text(db)
116 }
117}
118impl GetIdentifier for ast::Modifier {
119 fn identifier(&self, db: &dyn SyntaxGroup) -> SmolStr {
120 match self {
121 Modifier::Ref(r) => r.text(db),
122 Modifier::Mut(m) => m.text(db),
123 }
124 }
125}
126
127pub trait NameGreen {
129 fn name_green(self, db: &dyn SyntaxGroup) -> TerminalIdentifierGreen;
131}
132
133impl NameGreen for FunctionDeclarationGreen {
134 fn name_green(self, db: &dyn SyntaxGroup) -> TerminalIdentifierGreen {
135 TerminalIdentifierGreen(
136 self.0.lookup_intern(db).children()[FunctionDeclaration::INDEX_NAME],
137 )
138 }
139}
140
141impl NameGreen for FunctionWithBodyPtr {
142 fn name_green(self, db: &dyn SyntaxGroup) -> TerminalIdentifierGreen {
143 self.declaration_green(db).name_green(db)
144 }
145}
146
147impl NameGreen for ItemExternFunctionPtr {
148 fn name_green(self, db: &dyn SyntaxGroup) -> TerminalIdentifierGreen {
149 self.declaration_green(db).name_green(db)
150 }
151}
152
153impl NameGreen for TraitItemFunctionPtr {
154 fn name_green(self, db: &dyn SyntaxGroup) -> TerminalIdentifierGreen {
155 self.declaration_green(db).name_green(db)
156 }
157}
158
159pub trait GenericParamEx {
160 fn name(&self, db: &dyn SyntaxGroup) -> Option<ast::TerminalIdentifier>;
162}
163impl GenericParamEx for ast::GenericParam {
164 fn name(&self, db: &dyn SyntaxGroup) -> Option<ast::TerminalIdentifier> {
165 match self {
166 ast::GenericParam::Type(t) => Some(t.name(db)),
167 ast::GenericParam::Const(c) => Some(c.name(db)),
168 ast::GenericParam::ImplNamed(i) => Some(i.name(db)),
169 ast::GenericParam::ImplAnonymous(_) => None,
170 ast::GenericParam::NegativeImpl(_) => None,
171 }
172 }
173}
174
175pub fn is_single_arg_attr(db: &dyn SyntaxGroup, attr: &Attribute, arg_name: &str) -> bool {
177 match attr.arguments(db) {
178 OptionArgListParenthesized::ArgListParenthesized(args) => {
179 matches!(&args.arguments(db).elements(db)[..],
180 [arg] if arg.as_syntax_node().get_text_without_trivia(db) == arg_name)
181 }
182 OptionArgListParenthesized::Empty(_) => false,
183 }
184}
185
186pub trait QueryAttrs {
188 #[doc(hidden)]
192 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute>;
193
194 fn query_attr(&self, db: &dyn SyntaxGroup, attr: &str) -> Vec<Attribute> {
196 self.attributes_elements(db)
197 .into_iter()
198 .filter(|a| a.attr(db).as_syntax_node().get_text_without_trivia(db) == attr)
199 .collect()
200 }
201
202 fn find_attr(&self, db: &dyn SyntaxGroup, attr: &str) -> Option<Attribute> {
204 self.query_attr(db, attr).into_iter().next()
205 }
206
207 fn has_attr(&self, db: &dyn SyntaxGroup, attr: &str) -> bool {
209 self.find_attr(db, attr).is_some()
210 }
211
212 fn has_attr_with_arg(&self, db: &dyn SyntaxGroup, attr_name: &str, arg_name: &str) -> bool {
214 self.query_attr(db, attr_name).iter().any(|attr| is_single_arg_attr(db, attr, arg_name))
215 }
216}
217
218impl QueryAttrs for ItemConstant {
219 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
220 self.attributes(db).elements(db)
221 }
222}
223impl QueryAttrs for ItemModule {
224 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
225 self.attributes(db).elements(db)
226 }
227}
228impl QueryAttrs for FunctionWithBody {
229 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
230 self.attributes(db).elements(db)
231 }
232}
233impl QueryAttrs for ItemUse {
234 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
235 self.attributes(db).elements(db)
236 }
237}
238impl QueryAttrs for ItemExternFunction {
239 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
240 self.attributes(db).elements(db)
241 }
242}
243impl QueryAttrs for ItemExternType {
244 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
245 self.attributes(db).elements(db)
246 }
247}
248impl QueryAttrs for ItemTrait {
249 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
250 self.attributes(db).elements(db)
251 }
252}
253impl QueryAttrs for ItemImpl {
254 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
255 self.attributes(db).elements(db)
256 }
257}
258impl QueryAttrs for ItemImplAlias {
259 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
260 self.attributes(db).elements(db)
261 }
262}
263impl QueryAttrs for ItemStruct {
264 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
265 self.attributes(db).elements(db)
266 }
267}
268impl QueryAttrs for ItemEnum {
269 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
270 self.attributes(db).elements(db)
271 }
272}
273impl QueryAttrs for ItemTypeAlias {
274 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
275 self.attributes(db).elements(db)
276 }
277}
278impl QueryAttrs for TraitItemFunction {
279 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
280 self.attributes(db).elements(db)
281 }
282}
283impl QueryAttrs for TraitItemType {
284 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
285 self.attributes(db).elements(db)
286 }
287}
288impl QueryAttrs for TraitItemConstant {
289 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
290 self.attributes(db).elements(db)
291 }
292}
293impl QueryAttrs for TraitItemImpl {
294 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
295 self.attributes(db).elements(db)
296 }
297}
298impl QueryAttrs for TraitItem {
299 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
300 match self {
301 TraitItem::Function(item) => item.attributes_elements(db),
302 TraitItem::Type(item) => item.attributes_elements(db),
303 TraitItem::Constant(item) => item.attributes_elements(db),
304 TraitItem::Impl(item) => item.attributes_elements(db),
305 TraitItem::Missing(_) => vec![],
306 }
307 }
308}
309
310impl QueryAttrs for ItemInlineMacro {
311 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
312 self.attributes(db).elements(db)
313 }
314}
315
316impl QueryAttrs for ModuleItem {
317 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
318 match self {
319 ModuleItem::Constant(item) => item.attributes_elements(db),
320 ModuleItem::Module(item) => item.attributes_elements(db),
321 ModuleItem::FreeFunction(item) => item.attributes_elements(db),
322 ModuleItem::Use(item) => item.attributes_elements(db),
323 ModuleItem::ExternFunction(item) => item.attributes_elements(db),
324 ModuleItem::ExternType(item) => item.attributes_elements(db),
325 ModuleItem::Trait(item) => item.attributes_elements(db),
326 ModuleItem::Impl(item) => item.attributes_elements(db),
327 ModuleItem::ImplAlias(item) => item.attributes_elements(db),
328 ModuleItem::Struct(item) => item.attributes_elements(db),
329 ModuleItem::Enum(item) => item.attributes_elements(db),
330 ModuleItem::TypeAlias(item) => item.attributes_elements(db),
331 ModuleItem::InlineMacro(item) => item.attributes_elements(db),
332 ModuleItem::Missing(_) => vec![],
333 ModuleItem::HeaderDoc(_) => vec![],
334 }
335 }
336}
337
338impl QueryAttrs for ImplItem {
339 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
340 match self {
341 ImplItem::Function(item) => item.attributes_elements(db),
342 ImplItem::Type(item) => item.attributes_elements(db),
343 ImplItem::Constant(item) => item.attributes_elements(db),
344 ImplItem::Impl(item) => item.attributes_elements(db),
345 ImplItem::Module(item) => item.attributes_elements(db),
346 ImplItem::Use(item) => item.attributes_elements(db),
347 ImplItem::ExternFunction(item) => item.attributes_elements(db),
348 ImplItem::ExternType(item) => item.attributes_elements(db),
349 ImplItem::Trait(item) => item.attributes_elements(db),
350 ImplItem::Struct(item) => item.attributes_elements(db),
351 ImplItem::Enum(item) => item.attributes_elements(db),
352 ImplItem::Missing(_) => vec![],
353 }
354 }
355}
356
357impl QueryAttrs for AttributeList {
358 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
359 self.elements(db)
360 }
361}
362impl QueryAttrs for Member {
363 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
364 self.attributes(db).elements(db)
365 }
366}
367
368impl QueryAttrs for Variant {
369 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
370 self.attributes(db).elements(db)
371 }
372}
373
374impl QueryAttrs for StatementBreak {
375 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
376 self.attributes(db).elements(db)
377 }
378}
379
380impl QueryAttrs for StatementContinue {
381 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
382 self.attributes(db).elements(db)
383 }
384}
385
386impl QueryAttrs for StatementReturn {
387 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
388 self.attributes(db).elements(db)
389 }
390}
391
392impl QueryAttrs for StatementLet {
393 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
394 self.attributes(db).elements(db)
395 }
396}
397
398impl QueryAttrs for StatementExpr {
399 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
400 self.attributes(db).elements(db)
401 }
402}
403
404impl QueryAttrs for SyntaxNode {
407 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
408 match self.kind(db) {
409 SyntaxKind::ItemConstant => {
410 ast::ItemConstant::from_syntax_node(db, self.clone()).attributes_elements(db)
411 }
412 SyntaxKind::ItemModule => {
413 ast::ItemModule::from_syntax_node(db, self.clone()).attributes_elements(db)
414 }
415 SyntaxKind::FunctionWithBody => {
416 ast::FunctionWithBody::from_syntax_node(db, self.clone()).attributes_elements(db)
417 }
418 SyntaxKind::ItemUse => {
419 ast::ItemUse::from_syntax_node(db, self.clone()).attributes_elements(db)
420 }
421 SyntaxKind::ItemExternFunction => {
422 ast::ItemExternFunction::from_syntax_node(db, self.clone()).attributes_elements(db)
423 }
424 SyntaxKind::ItemExternType => {
425 ast::ItemExternType::from_syntax_node(db, self.clone()).attributes_elements(db)
426 }
427 SyntaxKind::ItemTrait => {
428 ast::ItemTrait::from_syntax_node(db, self.clone()).attributes_elements(db)
429 }
430 SyntaxKind::ItemImpl => {
431 ast::ItemImpl::from_syntax_node(db, self.clone()).attributes_elements(db)
432 }
433 SyntaxKind::ItemImplAlias => {
434 ast::ItemImplAlias::from_syntax_node(db, self.clone()).attributes_elements(db)
435 }
436 SyntaxKind::ItemStruct => {
437 ast::ItemStruct::from_syntax_node(db, self.clone()).attributes_elements(db)
438 }
439 SyntaxKind::ItemEnum => {
440 ast::ItemEnum::from_syntax_node(db, self.clone()).attributes_elements(db)
441 }
442 SyntaxKind::ItemTypeAlias => {
443 ast::ItemTypeAlias::from_syntax_node(db, self.clone()).attributes_elements(db)
444 }
445 SyntaxKind::TraitItemFunction => {
446 ast::TraitItemFunction::from_syntax_node(db, self.clone()).attributes_elements(db)
447 }
448 SyntaxKind::ItemInlineMacro => {
449 ast::ItemInlineMacro::from_syntax_node(db, self.clone()).attributes_elements(db)
450 }
451 SyntaxKind::AttributeList => {
452 ast::AttributeList::from_syntax_node(db, self.clone()).attributes_elements(db)
453 }
454 SyntaxKind::Member => {
455 ast::Member::from_syntax_node(db, self.clone()).attributes_elements(db)
456 }
457 SyntaxKind::Variant => {
458 ast::Variant::from_syntax_node(db, self.clone()).attributes_elements(db)
459 }
460 SyntaxKind::StatementBreak => {
461 ast::StatementBreak::from_syntax_node(db, self.clone()).attributes_elements(db)
462 }
463 SyntaxKind::StatementContinue => {
464 ast::StatementContinue::from_syntax_node(db, self.clone()).attributes_elements(db)
465 }
466 SyntaxKind::StatementReturn => {
467 ast::StatementReturn::from_syntax_node(db, self.clone()).attributes_elements(db)
468 }
469 SyntaxKind::StatementLet => {
470 ast::StatementLet::from_syntax_node(db, self.clone()).attributes_elements(db)
471 }
472 SyntaxKind::StatementExpr => {
473 ast::StatementExpr::from_syntax_node(db, self.clone()).attributes_elements(db)
474 }
475 _ => vec![],
476 }
477 }
478}
479
480impl QueryAttrs for Statement {
481 fn attributes_elements(&self, db: &dyn SyntaxGroup) -> Vec<Attribute> {
482 match self {
483 Statement::Break(statement) => statement.attributes_elements(db),
484 Statement::Continue(statement) => statement.attributes_elements(db),
485 Statement::Return(statement) => statement.attributes_elements(db),
486 Statement::Let(statement) => statement.attributes_elements(db),
487 Statement::Expr(statement) => statement.attributes_elements(db),
488 Statement::Item(statement) => statement.item(db).attributes_elements(db),
489 Statement::Missing(_) => vec![],
490 }
491 }
492}
493pub trait WrappedArgListHelper {
494 fn arg_list(&self, db: &dyn SyntaxGroup) -> Option<ast::ArgList>;
496 fn right_bracket_syntax_node(&self, db: &dyn SyntaxGroup) -> SyntaxNode;
498 fn left_bracket_syntax_node(&self, db: &dyn SyntaxGroup) -> SyntaxNode;
500 fn left_bracket_stable_ptr(&self, db: &dyn SyntaxGroup) -> SyntaxStablePtrId;
502}
503impl WrappedArgListHelper for WrappedArgList {
504 fn arg_list(&self, db: &dyn SyntaxGroup) -> Option<ast::ArgList> {
505 match self {
506 WrappedArgList::ParenthesizedArgList(args) => Some(args.arguments(db)),
507 WrappedArgList::BracketedArgList(args) => Some(args.arguments(db)),
508 WrappedArgList::BracedArgList(args) => Some(args.arguments(db)),
509 WrappedArgList::Missing(_) => None,
510 }
511 }
512
513 fn right_bracket_syntax_node(&self, db: &dyn SyntaxGroup) -> SyntaxNode {
514 match self {
515 WrappedArgList::ParenthesizedArgList(args) => args.rparen(db).as_syntax_node(),
516 WrappedArgList::BracketedArgList(args) => args.rbrack(db).as_syntax_node(),
517 WrappedArgList::BracedArgList(args) => args.rbrace(db).as_syntax_node(),
518 WrappedArgList::Missing(_) => self.as_syntax_node(),
519 }
520 }
521
522 fn left_bracket_syntax_node(&self, db: &dyn SyntaxGroup) -> SyntaxNode {
523 match self {
524 WrappedArgList::ParenthesizedArgList(args) => args.lparen(db).as_syntax_node(),
525 WrappedArgList::BracketedArgList(args) => args.lbrack(db).as_syntax_node(),
526 WrappedArgList::BracedArgList(args) => args.lbrace(db).as_syntax_node(),
527 WrappedArgList::Missing(_) => self.as_syntax_node(),
528 }
529 }
530
531 fn left_bracket_stable_ptr(&self, db: &dyn SyntaxGroup) -> SyntaxStablePtrId {
532 match self {
533 WrappedArgList::ParenthesizedArgList(args) => (&args.lparen(db)).into(),
534 WrappedArgList::BracketedArgList(args) => (&args.lbrack(db)).into(),
535 WrappedArgList::BracedArgList(args) => (&args.lbrace(db)).into(),
536 WrappedArgList::Missing(_) => self.into(),
537 }
538 }
539}
540
541pub trait WrappedGenericParamListHelper {
542 fn is_empty(&self, db: &dyn SyntaxGroup) -> bool;
544}
545impl WrappedGenericParamListHelper for ast::WrappedGenericParamList {
546 fn is_empty(&self, db: &dyn SyntaxGroup) -> bool {
547 self.generic_params(db).elements(db).is_empty()
548 }
549}
550
551pub trait OptionWrappedGenericParamListHelper {
552 fn is_empty(&self, db: &dyn SyntaxGroup) -> bool;
555}
556impl OptionWrappedGenericParamListHelper for ast::OptionWrappedGenericParamList {
557 fn is_empty(&self, db: &dyn SyntaxGroup) -> bool {
558 match self {
559 ast::OptionWrappedGenericParamList::Empty(_) => true,
560 ast::OptionWrappedGenericParamList::WrappedGenericParamList(
561 wrapped_generic_param_list,
562 ) => wrapped_generic_param_list.is_empty(db),
563 }
564 }
565}
566
567pub trait BodyItems {
569 type Item;
571 fn items_vec(&self, db: &dyn SyntaxGroup) -> Vec<Self::Item>;
579}
580
581impl BodyItems for ast::ModuleBody {
582 type Item = ModuleItem;
583 fn items_vec(&self, db: &dyn SyntaxGroup) -> Vec<ModuleItem> {
584 self.items(db).elements(db)
585 }
586}
587
588impl BodyItems for ast::TraitBody {
589 type Item = TraitItem;
590 fn items_vec(&self, db: &dyn SyntaxGroup) -> Vec<TraitItem> {
591 self.items(db).elements(db)
592 }
593}
594
595impl BodyItems for ast::ImplBody {
596 type Item = ImplItem;
597 fn items_vec(&self, db: &dyn SyntaxGroup) -> Vec<ImplItem> {
598 self.items(db).elements(db)
599 }
600}
601
602pub trait UsePathEx {
604 fn get_item(&self, db: &dyn SyntaxGroup) -> ast::ItemUse;
606}
607impl UsePathEx for ast::UsePath {
608 fn get_item(&self, db: &dyn SyntaxGroup) -> ast::ItemUse {
609 let mut node = self.as_syntax_node();
610 loop {
611 let Some(parent) = node.parent() else {
612 unreachable!("UsePath is not under an ItemUse.");
613 };
614 match parent.kind(db) {
615 SyntaxKind::ItemUse => {
616 break ast::ItemUse::from_syntax_node(db, parent);
617 }
618 _ => node = parent,
619 }
620 }
621 }
622}
623
624impl UsePathLeaf {
625 pub fn name_stable_ptr(&self, db: &dyn SyntaxGroup) -> SyntaxStablePtrId {
627 match self.alias_clause(db) {
628 ast::OptionAliasClause::Empty(_) => self.ident(db).stable_ptr().untyped(),
629 ast::OptionAliasClause::AliasClause(alias) => alias.alias(db).stable_ptr().untyped(),
630 }
631 }
632}