diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/src/handlers/merge_imports.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/edit.rs | 4 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/extensions.rs | 18 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated/nodes.rs | 36 | ||||
-rw-r--r-- | crates/ra_syntax/src/ast/generated/tokens.rs | 88 |
5 files changed, 34 insertions, 116 deletions
diff --git a/crates/ra_assists/src/handlers/merge_imports.rs b/crates/ra_assists/src/handlers/merge_imports.rs index 936d50ab4..0958f52f1 100644 --- a/crates/ra_assists/src/handlers/merge_imports.rs +++ b/crates/ra_assists/src/handlers/merge_imports.rs | |||
@@ -3,7 +3,7 @@ use std::iter::successors; | |||
3 | use ra_syntax::{ | 3 | use ra_syntax::{ |
4 | algo::{neighbor, SyntaxRewriter}, | 4 | algo::{neighbor, SyntaxRewriter}, |
5 | ast::{self, edit::AstNodeEdit, make}, | 5 | ast::{self, edit::AstNodeEdit, make}, |
6 | AstNode, AstToken, Direction, InsertPosition, SyntaxElement, T, | 6 | AstNode, Direction, InsertPosition, SyntaxElement, T, |
7 | }; | 7 | }; |
8 | 8 | ||
9 | use crate::{Assist, AssistCtx, AssistId}; | 9 | use crate::{Assist, AssistCtx, AssistId}; |
@@ -82,7 +82,7 @@ fn try_merge_trees(old: &ast::UseTree, new: &ast::UseTree) -> Option<ast::UseTre | |||
82 | .filter(|it| it.kind() != T!['{'] && it.kind() != T!['}']), | 82 | .filter(|it| it.kind() != T!['{'] && it.kind() != T!['}']), |
83 | ); | 83 | ); |
84 | let use_tree_list = lhs.use_tree_list()?; | 84 | let use_tree_list = lhs.use_tree_list()?; |
85 | let pos = InsertPosition::Before(use_tree_list.r_curly_token()?.syntax().clone().into()); | 85 | let pos = InsertPosition::Before(use_tree_list.r_curly_token()?.into()); |
86 | let use_tree_list = use_tree_list.insert_children(pos, to_insert); | 86 | let use_tree_list = use_tree_list.insert_children(pos, to_insert); |
87 | Some(lhs.with_use_tree_list(use_tree_list)) | 87 | Some(lhs.with_use_tree_list(use_tree_list)) |
88 | } | 88 | } |
diff --git a/crates/ra_syntax/src/ast/edit.rs b/crates/ra_syntax/src/ast/edit.rs index a01f6487d..7e14349d2 100644 --- a/crates/ra_syntax/src/ast/edit.rs +++ b/crates/ra_syntax/src/ast/edit.rs | |||
@@ -98,7 +98,7 @@ impl ast::ItemList { | |||
98 | None => match self.l_curly_token() { | 98 | None => match self.l_curly_token() { |
99 | Some(it) => ( | 99 | Some(it) => ( |
100 | " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(), | 100 | " ".to_string() + &leading_indent(self.syntax()).unwrap_or_default(), |
101 | InsertPosition::After(it.syntax().clone().into()), | 101 | InsertPosition::After(it.into()), |
102 | ), | 102 | ), |
103 | None => return self.clone(), | 103 | None => return self.clone(), |
104 | }, | 104 | }, |
@@ -142,7 +142,7 @@ impl ast::RecordFieldList { | |||
142 | macro_rules! after_l_curly { | 142 | macro_rules! after_l_curly { |
143 | () => {{ | 143 | () => {{ |
144 | let anchor = match self.l_curly_token() { | 144 | let anchor = match self.l_curly_token() { |
145 | Some(it) => it.syntax().clone().into(), | 145 | Some(it) => it.into(), |
146 | None => return self.clone(), | 146 | None => return self.clone(), |
147 | }; | 147 | }; |
148 | InsertPosition::After(anchor) | 148 | InsertPosition::After(anchor) |
diff --git a/crates/ra_syntax/src/ast/extensions.rs b/crates/ra_syntax/src/ast/extensions.rs index 11ec70bc0..eee98ebc2 100644 --- a/crates/ra_syntax/src/ast/extensions.rs +++ b/crates/ra_syntax/src/ast/extensions.rs | |||
@@ -416,11 +416,17 @@ impl ast::RangePat { | |||
416 | } | 416 | } |
417 | 417 | ||
418 | impl ast::TokenTree { | 418 | impl ast::TokenTree { |
419 | pub fn left_delimiter(&self) -> Option<ast::LeftDelimiter> { | 419 | pub fn left_delimiter_token(&self) -> Option<SyntaxToken> { |
420 | self.syntax().first_child_or_token()?.into_token().and_then(ast::LeftDelimiter::cast) | 420 | self.syntax().first_child_or_token()?.into_token().filter(|it| match it.kind() { |
421 | } | 421 | T!['{'] | T!['('] | T!['['] => true, |
422 | 422 | _ => false, | |
423 | pub fn right_delimiter(&self) -> Option<ast::RightDelimiter> { | 423 | }) |
424 | self.syntax().last_child_or_token()?.into_token().and_then(ast::RightDelimiter::cast) | 424 | } |
425 | |||
426 | pub fn right_delimiter_token(&self) -> Option<SyntaxToken> { | ||
427 | self.syntax().last_child_or_token()?.into_token().filter(|it| match it.kind() { | ||
428 | T!['{'] | T!['('] | T!['['] => true, | ||
429 | _ => false, | ||
430 | }) | ||
425 | } | 431 | } |
426 | } | 432 | } |
diff --git a/crates/ra_syntax/src/ast/generated/nodes.rs b/crates/ra_syntax/src/ast/generated/nodes.rs index fae76a7a8..3c917257c 100644 --- a/crates/ra_syntax/src/ast/generated/nodes.rs +++ b/crates/ra_syntax/src/ast/generated/nodes.rs | |||
@@ -146,9 +146,9 @@ impl AstNode for RecordFieldDefList { | |||
146 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 146 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
147 | } | 147 | } |
148 | impl RecordFieldDefList { | 148 | impl RecordFieldDefList { |
149 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 149 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
150 | pub fn fields(&self) -> AstChildren<RecordFieldDef> { support::children(&self.syntax) } | 150 | pub fn fields(&self) -> AstChildren<RecordFieldDef> { support::children(&self.syntax) } |
151 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 151 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
152 | } | 152 | } |
153 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 153 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
154 | pub struct RecordFieldDef { | 154 | pub struct RecordFieldDef { |
@@ -251,9 +251,9 @@ impl AstNode for EnumVariantList { | |||
251 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 251 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
252 | } | 252 | } |
253 | impl EnumVariantList { | 253 | impl EnumVariantList { |
254 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 254 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
255 | pub fn variants(&self) -> AstChildren<EnumVariant> { support::children(&self.syntax) } | 255 | pub fn variants(&self) -> AstChildren<EnumVariant> { support::children(&self.syntax) } |
256 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 256 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
257 | } | 257 | } |
258 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 258 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
259 | pub struct EnumVariant { | 259 | pub struct EnumVariant { |
@@ -347,9 +347,9 @@ impl AstNode for ItemList { | |||
347 | } | 347 | } |
348 | impl ast::ModuleItemOwner for ItemList {} | 348 | impl ast::ModuleItemOwner for ItemList {} |
349 | impl ItemList { | 349 | impl ItemList { |
350 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 350 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
351 | pub fn impl_items(&self) -> AstChildren<ImplItem> { support::children(&self.syntax) } | 351 | pub fn impl_items(&self) -> AstChildren<ImplItem> { support::children(&self.syntax) } |
352 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 352 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
353 | } | 353 | } |
354 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 354 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
355 | pub struct ConstDef { | 355 | pub struct ConstDef { |
@@ -1337,9 +1337,9 @@ impl AstNode for MatchArmList { | |||
1337 | } | 1337 | } |
1338 | impl ast::AttrsOwner for MatchArmList {} | 1338 | impl ast::AttrsOwner for MatchArmList {} |
1339 | impl MatchArmList { | 1339 | impl MatchArmList { |
1340 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 1340 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
1341 | pub fn arms(&self) -> AstChildren<MatchArm> { support::children(&self.syntax) } | 1341 | pub fn arms(&self) -> AstChildren<MatchArm> { support::children(&self.syntax) } |
1342 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 1342 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
1343 | } | 1343 | } |
1344 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1344 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1345 | pub struct MatchArm { | 1345 | pub struct MatchArm { |
@@ -1417,11 +1417,11 @@ impl AstNode for RecordFieldList { | |||
1417 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 1417 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
1418 | } | 1418 | } |
1419 | impl RecordFieldList { | 1419 | impl RecordFieldList { |
1420 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 1420 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
1421 | pub fn fields(&self) -> AstChildren<RecordField> { support::children(&self.syntax) } | 1421 | pub fn fields(&self) -> AstChildren<RecordField> { support::children(&self.syntax) } |
1422 | pub fn dotdot_token(&self) -> Option<Dotdot> { support::token(&self.syntax) } | 1422 | pub fn dotdot_token(&self) -> Option<Dotdot> { support::token(&self.syntax) } |
1423 | pub fn spread(&self) -> Option<Expr> { support::child(&self.syntax) } | 1423 | pub fn spread(&self) -> Option<Expr> { support::child(&self.syntax) } |
1424 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 1424 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
1425 | } | 1425 | } |
1426 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1426 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1427 | pub struct RecordField { | 1427 | pub struct RecordField { |
@@ -1709,14 +1709,14 @@ impl AstNode for RecordFieldPatList { | |||
1709 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 1709 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
1710 | } | 1710 | } |
1711 | impl RecordFieldPatList { | 1711 | impl RecordFieldPatList { |
1712 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 1712 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
1713 | pub fn pats(&self) -> AstChildren<RecordInnerPat> { support::children(&self.syntax) } | 1713 | pub fn pats(&self) -> AstChildren<RecordInnerPat> { support::children(&self.syntax) } |
1714 | pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> { | 1714 | pub fn record_field_pats(&self) -> AstChildren<RecordFieldPat> { |
1715 | support::children(&self.syntax) | 1715 | support::children(&self.syntax) |
1716 | } | 1716 | } |
1717 | pub fn bind_pats(&self) -> AstChildren<BindPat> { support::children(&self.syntax) } | 1717 | pub fn bind_pats(&self) -> AstChildren<BindPat> { support::children(&self.syntax) } |
1718 | pub fn dotdot_token(&self) -> Option<Dotdot> { support::token(&self.syntax) } | 1718 | pub fn dotdot_token(&self) -> Option<Dotdot> { support::token(&self.syntax) } |
1719 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 1719 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
1720 | } | 1720 | } |
1721 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1721 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1722 | pub struct RecordFieldPat { | 1722 | pub struct RecordFieldPat { |
@@ -2165,10 +2165,10 @@ impl AstNode for Block { | |||
2165 | impl ast::AttrsOwner for Block {} | 2165 | impl ast::AttrsOwner for Block {} |
2166 | impl ast::ModuleItemOwner for Block {} | 2166 | impl ast::ModuleItemOwner for Block {} |
2167 | impl Block { | 2167 | impl Block { |
2168 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 2168 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
2169 | pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) } | 2169 | pub fn statements(&self) -> AstChildren<Stmt> { support::children(&self.syntax) } |
2170 | pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } | 2170 | pub fn expr(&self) -> Option<Expr> { support::child(&self.syntax) } |
2171 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 2171 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
2172 | } | 2172 | } |
2173 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 2173 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
2174 | pub struct ParamList { | 2174 | pub struct ParamList { |
@@ -2311,9 +2311,9 @@ impl AstNode for UseTreeList { | |||
2311 | fn syntax(&self) -> &SyntaxNode { &self.syntax } | 2311 | fn syntax(&self) -> &SyntaxNode { &self.syntax } |
2312 | } | 2312 | } |
2313 | impl UseTreeList { | 2313 | impl UseTreeList { |
2314 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 2314 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
2315 | pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) } | 2315 | pub fn use_trees(&self) -> AstChildren<UseTree> { support::children(&self.syntax) } |
2316 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 2316 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
2317 | } | 2317 | } |
2318 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 2318 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
2319 | pub struct ExternCrateItem { | 2319 | pub struct ExternCrateItem { |
@@ -2557,9 +2557,9 @@ impl AstNode for ExternItemList { | |||
2557 | } | 2557 | } |
2558 | impl ast::ModuleItemOwner for ExternItemList {} | 2558 | impl ast::ModuleItemOwner for ExternItemList {} |
2559 | impl ExternItemList { | 2559 | impl ExternItemList { |
2560 | pub fn l_curly_token(&self) -> Option<LCurly> { support::token(&self.syntax) } | 2560 | pub fn l_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['{']) } |
2561 | pub fn extern_items(&self) -> AstChildren<ExternItem> { support::children(&self.syntax) } | 2561 | pub fn extern_items(&self) -> AstChildren<ExternItem> { support::children(&self.syntax) } |
2562 | pub fn r_curly_token(&self) -> Option<RCurly> { support::token(&self.syntax) } | 2562 | pub fn r_curly_token(&self) -> Option<SyntaxToken> { support::token2(&self.syntax, T!['}']) } |
2563 | } | 2563 | } |
2564 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 2564 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
2565 | pub struct ExternBlock { | 2565 | pub struct ExternBlock { |
diff --git a/crates/ra_syntax/src/ast/generated/tokens.rs b/crates/ra_syntax/src/ast/generated/tokens.rs index 7344b0e49..4cbc1d793 100644 --- a/crates/ra_syntax/src/ast/generated/tokens.rs +++ b/crates/ra_syntax/src/ast/generated/tokens.rs | |||
@@ -1366,94 +1366,6 @@ impl AstToken for RDollar { | |||
1366 | fn syntax(&self) -> &SyntaxToken { &self.syntax } | 1366 | fn syntax(&self) -> &SyntaxToken { &self.syntax } |
1367 | } | 1367 | } |
1368 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | 1368 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] |
1369 | pub enum LeftDelimiter { | ||
1370 | LParen(LParen), | ||
1371 | LBrack(LBrack), | ||
1372 | LCurly(LCurly), | ||
1373 | } | ||
1374 | impl From<LParen> for LeftDelimiter { | ||
1375 | fn from(node: LParen) -> LeftDelimiter { LeftDelimiter::LParen(node) } | ||
1376 | } | ||
1377 | impl From<LBrack> for LeftDelimiter { | ||
1378 | fn from(node: LBrack) -> LeftDelimiter { LeftDelimiter::LBrack(node) } | ||
1379 | } | ||
1380 | impl From<LCurly> for LeftDelimiter { | ||
1381 | fn from(node: LCurly) -> LeftDelimiter { LeftDelimiter::LCurly(node) } | ||
1382 | } | ||
1383 | impl std::fmt::Display for LeftDelimiter { | ||
1384 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1385 | std::fmt::Display::fmt(self.syntax(), f) | ||
1386 | } | ||
1387 | } | ||
1388 | impl AstToken for LeftDelimiter { | ||
1389 | fn can_cast(kind: SyntaxKind) -> bool { | ||
1390 | match kind { | ||
1391 | L_PAREN | L_BRACK | L_CURLY => true, | ||
1392 | _ => false, | ||
1393 | } | ||
1394 | } | ||
1395 | fn cast(syntax: SyntaxToken) -> Option<Self> { | ||
1396 | let res = match syntax.kind() { | ||
1397 | L_PAREN => LeftDelimiter::LParen(LParen { syntax }), | ||
1398 | L_BRACK => LeftDelimiter::LBrack(LBrack { syntax }), | ||
1399 | L_CURLY => LeftDelimiter::LCurly(LCurly { syntax }), | ||
1400 | _ => return None, | ||
1401 | }; | ||
1402 | Some(res) | ||
1403 | } | ||
1404 | fn syntax(&self) -> &SyntaxToken { | ||
1405 | match self { | ||
1406 | LeftDelimiter::LParen(it) => &it.syntax, | ||
1407 | LeftDelimiter::LBrack(it) => &it.syntax, | ||
1408 | LeftDelimiter::LCurly(it) => &it.syntax, | ||
1409 | } | ||
1410 | } | ||
1411 | } | ||
1412 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1413 | pub enum RightDelimiter { | ||
1414 | RParen(RParen), | ||
1415 | RBrack(RBrack), | ||
1416 | RCurly(RCurly), | ||
1417 | } | ||
1418 | impl From<RParen> for RightDelimiter { | ||
1419 | fn from(node: RParen) -> RightDelimiter { RightDelimiter::RParen(node) } | ||
1420 | } | ||
1421 | impl From<RBrack> for RightDelimiter { | ||
1422 | fn from(node: RBrack) -> RightDelimiter { RightDelimiter::RBrack(node) } | ||
1423 | } | ||
1424 | impl From<RCurly> for RightDelimiter { | ||
1425 | fn from(node: RCurly) -> RightDelimiter { RightDelimiter::RCurly(node) } | ||
1426 | } | ||
1427 | impl std::fmt::Display for RightDelimiter { | ||
1428 | fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { | ||
1429 | std::fmt::Display::fmt(self.syntax(), f) | ||
1430 | } | ||
1431 | } | ||
1432 | impl AstToken for RightDelimiter { | ||
1433 | fn can_cast(kind: SyntaxKind) -> bool { | ||
1434 | match kind { | ||
1435 | R_PAREN | R_BRACK | R_CURLY => true, | ||
1436 | _ => false, | ||
1437 | } | ||
1438 | } | ||
1439 | fn cast(syntax: SyntaxToken) -> Option<Self> { | ||
1440 | let res = match syntax.kind() { | ||
1441 | R_PAREN => RightDelimiter::RParen(RParen { syntax }), | ||
1442 | R_BRACK => RightDelimiter::RBrack(RBrack { syntax }), | ||
1443 | R_CURLY => RightDelimiter::RCurly(RCurly { syntax }), | ||
1444 | _ => return None, | ||
1445 | }; | ||
1446 | Some(res) | ||
1447 | } | ||
1448 | fn syntax(&self) -> &SyntaxToken { | ||
1449 | match self { | ||
1450 | RightDelimiter::RParen(it) => &it.syntax, | ||
1451 | RightDelimiter::RBrack(it) => &it.syntax, | ||
1452 | RightDelimiter::RCurly(it) => &it.syntax, | ||
1453 | } | ||
1454 | } | ||
1455 | } | ||
1456 | #[derive(Debug, Clone, PartialEq, Eq, Hash)] | ||
1457 | pub enum RangeSeparator { | 1369 | pub enum RangeSeparator { |
1458 | Dotdot(Dotdot), | 1370 | Dotdot(Dotdot), |
1459 | Dotdotdot(Dotdotdot), | 1371 | Dotdotdot(Dotdotdot), |