Skip to content

Commit 1364485

Browse files
committed
Use match statement in soft keyword token handler
1 parent 8432964 commit 1364485

File tree

1 file changed

+62
-57
lines changed

1 file changed

+62
-57
lines changed

parser/src/soft_keywords.rs

Lines changed: 62 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -50,71 +50,76 @@ where
5050
// used as an identifier. We assume every soft keyword use is an identifier unless
5151
// a heuristic is met.
5252

53-
// For `match` and `case`, all of the following conditions must be met:
54-
// 1. The token is at the start of a logical line.
55-
// 2. The logical line contains a top-level colon (that is, a colon that is not nested
56-
// inside a parenthesized expression, list, or dictionary).
57-
// 3. The top-level colon is not the immediate sibling of a `match` or `case` token.
58-
// (This is to avoid treating `match` or `case` as identifiers when annotated with
59-
// type hints.)
60-
if matches!(tok, Tok::Match | Tok::Case) {
61-
if !self.start_of_line {
62-
next = Some(Ok((soft_to_name(tok), *range)));
63-
} else {
64-
let mut nesting = 0;
65-
let mut first = true;
66-
let mut seen_colon = false;
67-
let mut seen_lambda = false;
68-
while let Some(Ok((tok, _))) = self.underlying.peek() {
69-
match tok {
70-
Tok::Newline => break,
71-
Tok::Lambda if nesting == 0 => seen_lambda = true,
72-
Tok::Colon if nesting == 0 => {
73-
if seen_lambda {
74-
seen_lambda = false;
75-
} else if !first {
76-
seen_colon = true;
53+
match tok {
54+
// For `match` and `case`, all of the following conditions must be met:
55+
// 1. The token is at the start of a logical line.
56+
// 2. The logical line contains a top-level colon (that is, a colon that is not nested
57+
// inside a parenthesized expression, list, or dictionary).
58+
// 3. The top-level colon is not the immediate sibling of a `match` or `case` token.
59+
// (This is to avoid treating `match` or `case` as identifiers when annotated with
60+
// type hints.) type hints.)
61+
Tok::Match | Tok::Case => {
62+
if !self.start_of_line {
63+
next = Some(Ok((soft_to_name(tok), *range)));
64+
} else {
65+
let mut nesting = 0;
66+
let mut first = true;
67+
let mut seen_colon = false;
68+
let mut seen_lambda = false;
69+
while let Some(Ok((tok, _))) = self.underlying.peek() {
70+
match tok {
71+
Tok::Newline => break,
72+
Tok::Lambda if nesting == 0 => seen_lambda = true,
73+
Tok::Colon if nesting == 0 => {
74+
if seen_lambda {
75+
seen_lambda = false;
76+
} else if !first {
77+
seen_colon = true;
78+
}
7779
}
80+
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
81+
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,
82+
_ => {}
7883
}
79-
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
80-
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,
81-
_ => {}
84+
first = false;
8285
}
83-
first = false;
84-
}
85-
if !seen_colon {
86-
next = Some(Ok((soft_to_name(tok), *range)));
87-
}
88-
}
89-
}
90-
// For `type` all of the following conditions must be met:
91-
// 1. The token is at the start of a logical line.
92-
// 2. The type token is followed by a name token.
93-
// 3. The name token is followed by an equality token.
94-
else if matches!(tok, Tok::Type) {
95-
if !self.start_of_line {
96-
next = Some(Ok((soft_to_name(tok), *range)));
97-
} else {
98-
let mut nesting = 0;
99-
let mut seen_name = false;
100-
let mut seen_equal = false;
101-
while let Some(Ok((tok, _))) = self.underlying.peek() {
102-
match tok {
103-
Tok::Newline => break,
104-
Tok::Name { .. } if nesting == 0 => seen_name = true,
105-
// We treat a soft keyword token following a type token as a
106-
// name to support cases like `type type = int` or `type match = int`
107-
Tok::Type | Tok::Match | Tok::Case if nesting == 0 => seen_name = true,
108-
Tok::Equal if nesting == 0 && seen_name => seen_equal = true,
109-
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
110-
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,
111-
_ => {}
86+
if !seen_colon {
87+
next = Some(Ok((soft_to_name(tok), *range)));
11288
}
11389
}
114-
if !(seen_name && seen_equal) {
90+
}
91+
// For `type` all of the following conditions must be met:
92+
// 1. The token is at the start of a logical line.
93+
// 2. The type token is followed by a name token.
94+
// 3. The name token is followed by an equality token.
95+
Tok::Type => {
96+
if !self.start_of_line {
11597
next = Some(Ok((soft_to_name(tok), *range)));
98+
} else {
99+
let mut nesting = 0;
100+
let mut seen_name = false;
101+
let mut seen_equal = false;
102+
while let Some(Ok((tok, _))) = self.underlying.peek() {
103+
match tok {
104+
Tok::Newline => break,
105+
Tok::Name { .. } if nesting == 0 => seen_name = true,
106+
// We treat a soft keyword token following a type token as a
107+
// name to support cases like `type type = int` or `type match = int`
108+
Tok::Type | Tok::Match | Tok::Case if nesting == 0 => {
109+
seen_name = true
110+
}
111+
Tok::Equal if nesting == 0 && seen_name => seen_equal = true,
112+
Tok::Lpar | Tok::Lsqb | Tok::Lbrace => nesting += 1,
113+
Tok::Rpar | Tok::Rsqb | Tok::Rbrace => nesting -= 1,
114+
_ => {}
115+
}
116+
}
117+
if !(seen_name && seen_equal) {
118+
next = Some(Ok((soft_to_name(tok), *range)));
119+
}
116120
}
117121
}
122+
_ => (), // Not a soft keyword token
118123
}
119124
}
120125

0 commit comments

Comments
 (0)