Skip to content
This repository was archived by the owner on May 11, 2023. It is now read-only.

Commit 23fee27

Browse files
authored
Merge pull request RustPython#4929 from astral-sh/add-start-end-to-located
Add `Located::start`, `Located::end` and impl `Deref`
2 parents 9287169 + 0a94e13 commit 23fee27

File tree

4 files changed

+65
-36
lines changed

4 files changed

+65
-36
lines changed

compiler/ast/asdl_rs.py

+18
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,24 @@ def write_ast_def(mod, typeinfo, f):
671671
pub fn new(location: Location, end_location: Location, node: T) -> Self {
672672
Self { location, end_location: Some(end_location), custom: (), node }
673673
}
674+
675+
pub const fn start(&self) -> Location {
676+
self.location
677+
}
678+
679+
/// Returns the node's [`end_location`](Located::end_location) or [`location`](Located::start) if
680+
/// [`end_location`](Located::end_location) is `None`.
681+
pub fn end(&self) -> Location {
682+
self.end_location.unwrap_or(self.location)
683+
}
684+
}
685+
686+
impl<T, U> std::ops::Deref for Located<T, U> {
687+
type Target = T;
688+
689+
fn deref(&self) -> &Self::Target {
690+
&self.node
691+
}
674692
}
675693
\n
676694
""".lstrip()

compiler/ast/src/ast_gen.rs

+18
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,24 @@ impl<T> Located<T> {
2424
node,
2525
}
2626
}
27+
28+
pub const fn start(&self) -> Location {
29+
self.location
30+
}
31+
32+
/// Returns the node's [`end_location`](Located::end_location) or [`location`](Located::start) if
33+
/// [`end_location`](Located::end_location) is `None`.
34+
pub fn end(&self) -> Location {
35+
self.end_location.unwrap_or(self.location)
36+
}
37+
}
38+
39+
impl<T, U> std::ops::Deref for Located<T, U> {
40+
type Target = T;
41+
42+
fn deref(&self) -> &Self::Target {
43+
&self.node
44+
}
2745
}
2846

2947
#[derive(Clone, Debug, PartialEq)]

compiler/parser/python.lalrpop

+24-31
Original file line numberDiff line numberDiff line change
@@ -348,8 +348,7 @@ MatchStatement: ast::Stmt = {
348348
.body
349349
.last()
350350
.unwrap()
351-
.end_location
352-
.unwrap();
351+
.end();
353352
ast::Stmt::new(
354353
location,
355354
end_location,
@@ -366,8 +365,7 @@ MatchStatement: ast::Stmt = {
366365
.body
367366
.last()
368367
.unwrap()
369-
.end_location
370-
.unwrap();
368+
.end();
371369
ast::Stmt::new(
372370
location,
373371
end_location,
@@ -384,8 +382,7 @@ MatchStatement: ast::Stmt = {
384382
.body
385383
.last()
386384
.unwrap()
387-
.end_location
388-
.unwrap();
385+
.end();
389386
let mut subjects = subjects;
390387
subjects.insert(0, subject);
391388
ast::Stmt::new(
@@ -803,8 +800,7 @@ IfStatement: ast::Stmt = {
803800
.or_else(|| s2.last().and_then(|last| last.4.last()))
804801
.or_else(|| body.last())
805802
.unwrap()
806-
.end_location
807-
.unwrap();
803+
.end();
808804
// handle elif:
809805
for i in s2.into_iter().rev() {
810806
let x = ast::Stmt::new(
@@ -830,8 +826,7 @@ WhileStatement: ast::Stmt = {
830826
.last()
831827
.or_else(|| body.last())
832828
.unwrap()
833-
.end_location
834-
.unwrap();
829+
.end();
835830
ast::Stmt::new(
836831
location,
837832
end_location,
@@ -851,8 +846,7 @@ ForStatement: ast::Stmt = {
851846
.last()
852847
.or_else(|| body.last())
853848
.unwrap()
854-
.end_location
855-
.unwrap();
849+
.end();
856850
let target = Box::new(set_context(target, ast::ExprContext::Store));
857851
let iter = Box::new(iter);
858852
let type_comment = None;
@@ -871,9 +865,9 @@ TryStatement: ast::Stmt = {
871865
let finalbody = finally.map(|s| s.2).unwrap_or_default();
872866
let end_location = finalbody
873867
.last()
874-
.and_then(|last| last.end_location)
875-
.or_else(|| orelse.last().and_then(|last| last.end_location))
876-
.or_else(|| handlers.last().and_then(|last| last.end_location))
868+
.map(|last| last.end())
869+
.or_else(|| orelse.last().map(|last| last.end()))
870+
.or_else(|| handlers.last().map(|last| last.end()))
877871
.unwrap();
878872
ast::Stmt::new(
879873
location,
@@ -892,8 +886,8 @@ TryStatement: ast::Stmt = {
892886
let end_location = finalbody
893887
.last()
894888
.or_else(|| orelse.last())
895-
.and_then(|last| last.end_location)
896-
.or_else(|| handlers.last().and_then(|last| last.end_location))
889+
.map(|last| last.end())
890+
.or_else(|| handlers.last().map(|last| last.end()))
897891
.unwrap();
898892
ast::Stmt::new(
899893
location,
@@ -910,7 +904,7 @@ TryStatement: ast::Stmt = {
910904
let handlers = vec![];
911905
let orelse = vec![];
912906
let finalbody = finally.2;
913-
let end_location = finalbody.last().unwrap().end_location.unwrap();
907+
let end_location = finalbody.last().unwrap().end();
914908
ast::Stmt::new(
915909
location,
916910
end_location,
@@ -926,7 +920,7 @@ TryStatement: ast::Stmt = {
926920

927921
ExceptStarClause: ast::Excepthandler = {
928922
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
929-
let end_location = body.last().unwrap().end_location.unwrap();
923+
let end_location = body.last().unwrap().end();
930924
ast::Excepthandler::new(
931925
location,
932926
end_location,
@@ -938,7 +932,7 @@ ExceptStarClause: ast::Excepthandler = {
938932
)
939933
},
940934
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
941-
let end_location = body.last().unwrap().end_location.unwrap();
935+
let end_location = body.last().unwrap().end();
942936
ast::Excepthandler::new(
943937
location,
944938
end_location,
@@ -954,7 +948,7 @@ ExceptStarClause: ast::Excepthandler = {
954948

955949
ExceptClause: ast::Excepthandler = {
956950
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
957-
let end_location = body.last().unwrap().end_location.unwrap();
951+
let end_location = body.last().unwrap().end();
958952
ast::Excepthandler::new(
959953
location,
960954
end_location,
@@ -966,7 +960,7 @@ ExceptClause: ast::Excepthandler = {
966960
)
967961
},
968962
<location:@L> "except" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
969-
let end_location = body.last().unwrap().end_location.unwrap();
963+
let end_location = body.last().unwrap().end();
970964
ast::Excepthandler::new(
971965
location,
972966
end_location,
@@ -981,7 +975,7 @@ ExceptClause: ast::Excepthandler = {
981975

982976
WithStatement: ast::Stmt = {
983977
<location:@L> <is_async:"async"?> "with" <items:WithItems> ":" <body:Suite> => {
984-
let end_location = body.last().unwrap().end_location.unwrap();
978+
let end_location = body.last().unwrap().end();
985979
let type_comment = None;
986980
let node = if is_async.is_some() {
987981
ast::StmtKind::AsyncWith { items, body, type_comment }
@@ -1022,7 +1016,7 @@ FuncDef: ast::Stmt = {
10221016
<decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test<"all">)?> ":" <body:Suite> => {
10231017
let args = Box::new(args);
10241018
let returns = r.map(|x| Box::new(x.1));
1025-
let end_location = body.last().unwrap().end_location.unwrap();
1019+
let end_location = body.last().unwrap().end();
10261020
let type_comment = None;
10271021
let node = if is_async.is_some() {
10281022
ast::StmtKind::AsyncFunctionDef { name, args, body, decorator_list, returns, type_comment }
@@ -1197,7 +1191,7 @@ ClassDef: ast::Stmt = {
11971191
Some((_, arg, _)) => (arg.args, arg.keywords),
11981192
None => (vec![], vec![]),
11991193
};
1200-
let end_location = body.last().unwrap().end_location.unwrap();
1194+
let end_location = body.last().unwrap().end();
12011195
ast::Stmt::new(
12021196
location,
12031197
end_location,
@@ -1253,19 +1247,18 @@ NamedExpressionTest: ast::Expr = {
12531247

12541248
NamedExpression: ast::Expr = {
12551249
<location:@L> <id:Identifier> <end_location:@R> ":=" <value:Test<"all">> => {
1256-
ast::Expr {
1250+
ast::Expr::new(
12571251
location,
1258-
end_location: value.end_location,
1259-
custom: (),
1260-
node: ast::ExprKind::NamedExpr {
1252+
value.end(),
1253+
ast::ExprKind::NamedExpr {
12611254
target: Box::new(ast::Expr::new(
12621255
location,
12631256
end_location,
12641257
ast::ExprKind::Name { id, ctx: ast::ExprContext::Store },
12651258
)),
12661259
value: Box::new(value),
12671260
}
1268-
}
1261+
)
12691262
},
12701263
};
12711264

@@ -1564,7 +1557,7 @@ Atom<Goal>: ast::Expr = {
15641557
if matches!(mid.node, ast::ExprKind::Starred { .. }) {
15651558
Err(LexicalError{
15661559
error: LexicalErrorType::OtherError("cannot use starred expression here".to_string()),
1567-
location: mid.location,
1560+
location: mid.start(),
15681561
})?
15691562
}
15701563
Ok(mid)

compiler/parser/src/function.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,12 @@ pub(crate) fn validate_arguments(
3535

3636
let mut all_arg_names = FxHashSet::with_hasher(Default::default());
3737
for arg in all_args {
38-
let arg_name = &arg.node.arg;
38+
let arg_name = &arg.arg;
3939
// Check for duplicate arguments in the function definition.
4040
if !all_arg_names.insert(arg_name) {
4141
return Err(LexicalError {
4242
error: LexicalErrorType::DuplicateArgumentError(arg_name.to_string()),
43-
location: arg.location,
43+
location: arg.start(),
4444
});
4545
}
4646
}
@@ -64,7 +64,7 @@ pub(crate) fn parse_params(
6464
// have defaults.
6565
return Err(LexicalError {
6666
error: LexicalErrorType::DefaultArgumentError,
67-
location: name.location,
67+
location: name.start(),
6868
});
6969
}
7070
Ok(())
@@ -126,14 +126,14 @@ pub(crate) fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ArgumentLis
126126
if !keywords.is_empty() && !is_starred(&value) {
127127
return Err(LexicalError {
128128
error: LexicalErrorType::PositionalArgumentError,
129-
location: value.location,
129+
location: value.start(),
130130
});
131131
// Allow starred arguments after keyword arguments but
132132
// not after double-starred arguments.
133133
} else if double_starred {
134134
return Err(LexicalError {
135135
error: LexicalErrorType::UnpackedArgumentError,
136-
location: value.location,
136+
location: value.start(),
137137
});
138138
}
139139

0 commit comments

Comments
 (0)