Add handling for soft keywords as type alias names

This commit is contained in:
Zanie 2023-07-13 14:53:27 -05:00
parent 50f1b6a3ec
commit 4b99996f96
3 changed files with 131 additions and 14 deletions

View file

@ -931,16 +931,12 @@ type()[a:
b] # (type())[a: b] b] # (type())[a: b]
if type := 1: pass if type := 1: pass
type = lambda query: query == event type = lambda query: query == event
type type = int | str
print(type(12)) print(type(12))
type(type)
type match = int # other soft keyword
type case = int
"#; "#;
use crate::lexer::lex;
let lexer = lex(source, Mode::Module);
println!(
"tokens {:#?}",
lexer.map(|x| x.unwrap().0).collect::<Vec<_>>()
);
insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap()); insta::assert_debug_snapshot!(ast::Suite::parse(source, "<test>").unwrap());
} }

View file

@ -769,15 +769,54 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
type_comment: None, type_comment: None,
}, },
), ),
TypeAlias(
StmtTypeAlias {
range: 536..557,
name: Name(
ExprName {
range: 541..545,
id: Identifier(
"type",
),
ctx: Load,
},
),
type_params: [],
value: BinOp(
ExprBinOp {
range: 548..557,
left: Name(
ExprName {
range: 548..551,
id: Identifier(
"int",
),
ctx: Load,
},
),
op: BitOr,
right: Name(
ExprName {
range: 554..557,
id: Identifier(
"str",
),
ctx: Load,
},
),
},
),
},
),
Expr( Expr(
StmtExpr { StmtExpr {
range: 536..551, range: 558..573,
value: Call( value: Call(
ExprCall { ExprCall {
range: 536..551, range: 558..573,
func: Name( func: Name(
ExprName { ExprName {
range: 536..541, range: 558..563,
id: Identifier( id: Identifier(
"print", "print",
), ),
@ -787,10 +826,10 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
args: [ args: [
Call( Call(
ExprCall { ExprCall {
range: 542..550, range: 564..572,
func: Name( func: Name(
ExprName { ExprName {
range: 542..546, range: 564..568,
id: Identifier( id: Identifier(
"type", "type",
), ),
@ -800,7 +839,7 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
args: [ args: [
Constant( Constant(
ExprConstant { ExprConstant {
range: 547..549, range: 569..571,
value: Int( value: Int(
12, 12,
), ),
@ -817,4 +856,83 @@ expression: "ast::Suite::parse(source, \"<test>\").unwrap()"
), ),
}, },
), ),
Expr(
StmtExpr {
range: 574..584,
value: Call(
ExprCall {
range: 574..584,
func: Name(
ExprName {
range: 574..578,
id: Identifier(
"type",
),
ctx: Load,
},
),
args: [
Name(
ExprName {
range: 579..583,
id: Identifier(
"type",
),
ctx: Load,
},
),
],
keywords: [],
},
),
},
),
TypeAlias(
StmtTypeAlias {
range: 585..601,
name: Name(
ExprName {
range: 590..595,
id: Identifier(
"match",
),
ctx: Load,
},
),
type_params: [],
value: Name(
ExprName {
range: 598..601,
id: Identifier(
"int",
),
ctx: Load,
},
),
},
),
TypeAlias(
StmtTypeAlias {
range: 624..639,
name: Name(
ExprName {
range: 629..633,
id: Identifier(
"case",
),
ctx: Load,
},
),
type_params: [],
value: Name(
ExprName {
range: 636..639,
id: Identifier(
"int",
),
ctx: Load,
},
),
},
),
] ]

View file

@ -102,6 +102,9 @@ where
match tok { match tok {
Tok::Newline => break, Tok::Newline => break,
Tok::Name { .. } if nesting == 0 => seen_name = true, 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::Equal if nesting == 0 && seen_name => seen_equal = true, Tok::Equal if nesting == 0 && seen_name => seen_equal = true,
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1, Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1, Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,