Require the name token to immediately follow the type token

This commit is contained in:
Zanie 2023-07-14 13:12:41 -05:00
parent 4776f689ae
commit 4170b22b7d
4 changed files with 172 additions and 22 deletions

View file

@ -913,6 +913,11 @@ type type = int
type match = int
type case = int
# soft keyword as value
type foo = type
type foo = match
type foo = case
# multine definitions
type \
X = int
@ -959,6 +964,8 @@ type (
X = int
)
type = 1
type = x = 1
x = type = 1
"#;
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
}

View file

@ -636,10 +636,82 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
),
TypeAlias(
StmtTypeAlias {
range: 367..382,
range: 369..384,
name: Name(
ExprName {
range: 375..376,
range: 374..377,
id: Identifier(
"foo",
),
ctx: Load,
},
),
type_params: [],
value: Name(
ExprName {
range: 380..384,
id: Identifier(
"type",
),
ctx: Load,
},
),
},
),
TypeAlias(
StmtTypeAlias {
range: 385..401,
name: Name(
ExprName {
range: 390..393,
id: Identifier(
"foo",
),
ctx: Load,
},
),
type_params: [],
value: Name(
ExprName {
range: 396..401,
id: Identifier(
"match",
),
ctx: Load,
},
),
},
),
TypeAlias(
StmtTypeAlias {
range: 402..417,
name: Name(
ExprName {
range: 407..410,
id: Identifier(
"foo",
),
ctx: Load,
},
),
type_params: [],
value: Name(
ExprName {
range: 413..417,
id: Identifier(
"case",
),
ctx: Load,
},
),
},
),
TypeAlias(
StmtTypeAlias {
range: 441..456,
name: Name(
ExprName {
range: 449..450,
id: Identifier(
"X",
),
@ -649,7 +721,7 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
type_params: [],
value: Name(
ExprName {
range: 379..382,
range: 453..456,
id: Identifier(
"int",
),
@ -660,10 +732,10 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
),
TypeAlias(
StmtTypeAlias {
range: 383..398,
range: 457..472,
name: Name(
ExprName {
range: 388..389,
range: 462..463,
id: Identifier(
"X",
),
@ -673,7 +745,7 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
type_params: [],
value: Name(
ExprName {
range: 395..398,
range: 469..472,
id: Identifier(
"int",
),
@ -684,10 +756,10 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
),
TypeAlias(
StmtTypeAlias {
range: 399..414,
range: 473..488,
name: Name(
ExprName {
range: 404..405,
range: 478..479,
id: Identifier(
"X",
),
@ -697,7 +769,7 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
type_params: [],
value: Name(
ExprName {
range: 411..414,
range: 485..488,
id: Identifier(
"int",
),
@ -708,10 +780,10 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
),
TypeAlias(
StmtTypeAlias {
range: 415..435,
range: 489..509,
name: Name(
ExprName {
range: 420..421,
range: 494..495,
id: Identifier(
"X",
),
@ -721,7 +793,7 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
type_params: [],
value: Name(
ExprName {
range: 430..433,
range: 504..507,
id: Identifier(
"int",
),

View file

@ -1001,4 +1001,74 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
type_comment: None,
},
),
Assign(
StmtAssign {
range: 626..638,
targets: [
Name(
ExprName {
range: 626..630,
id: Identifier(
"type",
),
ctx: Store,
},
),
Name(
ExprName {
range: 633..634,
id: Identifier(
"x",
),
ctx: Store,
},
),
],
value: Constant(
ExprConstant {
range: 637..638,
value: Int(
1,
),
kind: None,
},
),
type_comment: None,
},
),
Assign(
StmtAssign {
range: 639..651,
targets: [
Name(
ExprName {
range: 639..640,
id: Identifier(
"x",
),
ctx: Store,
},
),
Name(
ExprName {
range: 643..647,
id: Identifier(
"type",
),
ctx: Store,
},
),
],
value: Constant(
ExprConstant {
range: 650..651,
value: Int(
1,
),
kind: None,
},
),
type_comment: None,
},
),
]

View file

@ -90,36 +90,37 @@ where
}
// For `type` all of the following conditions must be met:
// 1. The token is at the start of a logical line.
// 2. The type token is followed by a name token.
// 3. The name token is followed by an equality token.
// 2. The type token is immediately followed by a name token.
// 3. The name token is eventually followed by an equality token.
Tok::Type => {
if !self.start_of_line {
next = Some(Ok((soft_to_name(tok), *range)));
} else {
let mut nesting = 0;
let mut first = true;
let mut seen_name = false;
let mut seen_equal = false;
while let Some(Ok((tok, _))) = self.underlying.peek() {
match tok {
Tok::Newline => break,
Tok::Name { .. } if nesting == 0 => seen_name = true,
// We treat a soft keyword token following a type token as a
// name to support cases like `type type = int` or `type match = int`
Tok::Type | Tok::Match | Tok::Case if nesting == 0 => {
seen_name = true
}
Tok::Newline => break,
Tok::Name { .. } |
// We treat a soft keyword token following a type token as a
// name to support cases like `type type = int` or `type match = int`
Tok::Type | Tok::Match | Tok::Case
if first => seen_name = true,
Tok::Equal if nesting == 0 && seen_name => seen_equal = true,
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,
_ => {}
}
first = false;
}
if !(seen_name && seen_equal) {
next = Some(Ok((soft_to_name(tok), *range)));
}
}
}
_ => (), // Not a soft keyword token
_ => (), // Not a soft keyword token
}
}