mod token_ext;
mod node_ext;
mod expr_ext;
+mod operators;
pub mod edit;
+pub mod edit_in_place;
pub mod make;
use std::marker::PhantomData;
use crate::{
syntax_node::{SyntaxNode, SyntaxNodeChildren, SyntaxToken},
- SmolStr, SyntaxKind,
+ SyntaxKind,
};
pub use self::{
- expr_ext::{ArrayExprKind, BinOp, Effect, ElseBranch, LiteralKind, PrefixOp, Radix, RangeOp},
+ expr_ext::{ArrayExprKind, BlockModifier, CallableExpr, ElseBranch, LiteralKind},
generated::{nodes::*, tokens::*},
node_ext::{
- AttrKind, FieldKind, NameOrNameRef, PathSegmentKind, SelfParamKind, SlicePatComponents,
- StructKind, TypeBoundKind, VisibilityKind,
+ AttrKind, FieldKind, Macro, NameLike, NameOrNameRef, PathSegmentKind, SelfParamKind,
+ SlicePatComponents, StructKind, TypeBoundKind, VisibilityKind,
+ },
+ operators::{ArithOp, BinaryOp, CmpOp, LogicOp, Ordering, RangeOp, UnaryOp},
+ token_ext::{CommentKind, CommentPlacement, CommentShape, IsString, QuoteOffsets, Radix},
+ traits::{
+ DocCommentIter, HasArgList, HasAttrs, HasDocComments, HasGenericParams, HasLoopBody,
+ HasModuleItem, HasName, HasTypeBounds, HasVisibility,
},
- token_ext::*,
- traits::*,
};
/// The main trait to go from untyped `SyntaxNode` to a typed ast. The
Self: Sized;
fn syntax(&self) -> &SyntaxNode;
+ fn clone_for_update(&self) -> Self
+ where
+ Self: Sized,
+ {
+ Self::cast(self.syntax().clone_for_update()).unwrap()
+ }
+ fn clone_subtree(&self) -> Self
+ where
+ Self: Sized,
+ {
+ Self::cast(self.syntax().clone_subtree()).unwrap()
+ }
}
/// Like `AstNode`, but wraps tokens rather than interior nodes.
fn syntax(&self) -> &SyntaxToken;
- fn text(&self) -> &SmolStr {
+ fn text(&self) -> &str {
self.syntax().text()
}
}
#[test]
fn assert_ast_is_object_safe() {
- fn _f(_: &dyn AstNode, _: &dyn NameOwner) {}
+ fn _f(_: &dyn AstNode, _: &dyn HasName) {}
}
#[test]
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert!(module.doc_comment_text().is_none());
+ assert!(module.doc_comments().doc_comment_text().is_none());
}
#[test]
-fn test_doc_comment_of_items() {
+fn test_outer_doc_comment_of_items() {
+ let file = SourceFile::parse(
+ r#"
+ /// doc
+ // non-doc
+ mod foo {}
+ "#,
+ )
+ .ok()
+ .unwrap();
+ let module = file.syntax().descendants().find_map(Module::cast).unwrap();
+ assert_eq!(" doc", module.doc_comments().doc_comment_text().unwrap());
+}
+
+#[test]
+fn test_inner_doc_comment_of_items() {
let file = SourceFile::parse(
r#"
//! doc
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert_eq!("doc", module.doc_comment_text().unwrap());
+ assert!(module.doc_comments().doc_comment_text().is_none());
}
#[test]
.ok()
.unwrap();
let st = file.syntax().descendants().find_map(Static::cast).unwrap();
- assert_eq!("Number of levels", st.doc_comment_text().unwrap());
+ assert_eq!(" Number of levels", st.doc_comments().doc_comment_text().unwrap());
}
#[test]
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert_eq!("doc1\n```\nfn foo() {\n // ...\n}\n```", module.doc_comment_text().unwrap());
+ assert_eq!(
+ " doc1\n ```\n fn foo() {\n // ...\n }\n ```",
+ module.doc_comments().doc_comment_text().unwrap()
+ );
}
#[test]
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert_eq!("this\nis\nmod\nfoo", module.doc_comment_text().unwrap());
+ assert_eq!(" this\n is\n mod\n foo", module.doc_comments().doc_comment_text().unwrap());
}
#[test]
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert_eq!("this is mod foo", module.doc_comment_text().unwrap());
+ assert_eq!(" this is mod foo", module.doc_comments().doc_comment_text().unwrap());
}
#[test]
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert_eq!("this is mod foo ", module.doc_comment_text().unwrap());
+ assert_eq!(" this is mod foo ", module.doc_comments().doc_comment_text().unwrap());
}
#[test]
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
assert_eq!(
- " this\n is\n mod foo\n ",
- module.doc_comment_text().unwrap()
+ "\n this\n is\n mod foo\n ",
+ module.doc_comments().doc_comment_text().unwrap()
);
}
.unwrap();
let def = file.syntax().descendants().find_map(Struct::cast).unwrap();
assert_eq!(
- "Representation of a Realm. \nIn the specification these are called Realm Records.",
- def.doc_comment_text().unwrap()
+ " Representation of a Realm. \n In the specification these are called Realm Records.",
+ def.doc_comments().doc_comment_text().unwrap()
);
}
.ok()
.unwrap();
let module = file.syntax().descendants().find_map(Module::cast).unwrap();
- assert_eq!("doc comment", module.doc_comment_text().unwrap());
+ assert_eq!(" doc comment", module.doc_comments().doc_comment_text().unwrap());
}
#[test]
let pred = predicates.next().unwrap();
let mut bounds = pred.type_bound_list().unwrap().bounds();
- assert_eq!("'a", pred.lifetime_token().unwrap().text());
+ assert_eq!("'a", pred.lifetime().unwrap().lifetime_ident_token().unwrap().text());
assert_bound("'b", bounds.next());
assert_bound("'c", bounds.next());