Add Located::start, Located::end and impl Deref

This commit is contained in:
Micha Reiser 2023-04-26 10:24:34 -06:00
parent 321ab83825
commit 31fd625321
4 changed files with 65 additions and 36 deletions

View file

@ -671,6 +671,24 @@ def write_ast_def(mod, typeinfo, f):
pub fn new(location: Location, end_location: Location, node: T) -> Self {
Self { location, end_location: Some(end_location), custom: (), node }
}
pub const fn start(&self) -> Location {
self.location
}
/// Returns the node's [`end_location`](Located::end_location) or [`location`](Located::start) if
/// [`end_location`](Located::end_location) is `None`.
pub fn end(&self) -> Location {
self.end_location.unwrap_or(self.location)
}
}
impl<T, U> std::ops::Deref for Located<T, U> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.node
}
}
\n
""".lstrip()

View file

@ -24,6 +24,24 @@ impl<T> Located<T> {
node,
}
}
pub const fn start(&self) -> Location {
self.location
}
/// Returns the node's [`end_location`](Located::end_location) or [`location`](Located::start) if
/// [`end_location`](Located::end_location) is `None`.
pub fn end(&self) -> Location {
self.end_location.unwrap_or(self.location)
}
}
impl<T, U> std::ops::Deref for Located<T, U> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.node
}
}
#[derive(Clone, Debug, PartialEq)]

View file

@ -348,8 +348,7 @@ MatchStatement: ast::Stmt = {
.body
.last()
.unwrap()
.end_location
.unwrap();
.end();
ast::Stmt::new(
location,
end_location,
@ -366,8 +365,7 @@ MatchStatement: ast::Stmt = {
.body
.last()
.unwrap()
.end_location
.unwrap();
.end();
ast::Stmt::new(
location,
end_location,
@ -384,8 +382,7 @@ MatchStatement: ast::Stmt = {
.body
.last()
.unwrap()
.end_location
.unwrap();
.end();
let mut subjects = subjects;
subjects.insert(0, subject);
ast::Stmt::new(
@ -803,8 +800,7 @@ IfStatement: ast::Stmt = {
.or_else(|| s2.last().and_then(|last| last.4.last()))
.or_else(|| body.last())
.unwrap()
.end_location
.unwrap();
.end();
// handle elif:
for i in s2.into_iter().rev() {
let x = ast::Stmt::new(
@ -830,8 +826,7 @@ WhileStatement: ast::Stmt = {
.last()
.or_else(|| body.last())
.unwrap()
.end_location
.unwrap();
.end();
ast::Stmt::new(
location,
end_location,
@ -851,8 +846,7 @@ ForStatement: ast::Stmt = {
.last()
.or_else(|| body.last())
.unwrap()
.end_location
.unwrap();
.end();
let target = Box::new(set_context(target, ast::ExprContext::Store));
let iter = Box::new(iter);
let type_comment = None;
@ -871,9 +865,9 @@ TryStatement: ast::Stmt = {
let finalbody = finally.map(|s| s.2).unwrap_or_default();
let end_location = finalbody
.last()
.and_then(|last| last.end_location)
.or_else(|| orelse.last().and_then(|last| last.end_location))
.or_else(|| handlers.last().and_then(|last| last.end_location))
.map(|last| last.end())
.or_else(|| orelse.last().map(|last| last.end()))
.or_else(|| handlers.last().map(|last| last.end()))
.unwrap();
ast::Stmt::new(
location,
@ -892,8 +886,8 @@ TryStatement: ast::Stmt = {
let end_location = finalbody
.last()
.or_else(|| orelse.last())
.and_then(|last| last.end_location)
.or_else(|| handlers.last().and_then(|last| last.end_location))
.map(|last| last.end())
.or_else(|| handlers.last().map(|last| last.end()))
.unwrap();
ast::Stmt::new(
location,
@ -910,7 +904,7 @@ TryStatement: ast::Stmt = {
let handlers = vec![];
let orelse = vec![];
let finalbody = finally.2;
let end_location = finalbody.last().unwrap().end_location.unwrap();
let end_location = finalbody.last().unwrap().end();
ast::Stmt::new(
location,
end_location,
@ -926,7 +920,7 @@ TryStatement: ast::Stmt = {
ExceptStarClause: ast::Excepthandler = {
<location:@L> "except" "*" <typ:Test<"all">> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
ast::Excepthandler::new(
location,
end_location,
@ -938,7 +932,7 @@ ExceptStarClause: ast::Excepthandler = {
)
},
<location:@L> "except" "*" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
ast::Excepthandler::new(
location,
end_location,
@ -954,7 +948,7 @@ ExceptStarClause: ast::Excepthandler = {
ExceptClause: ast::Excepthandler = {
<location:@L> "except" <typ:Test<"all">?> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
ast::Excepthandler::new(
location,
end_location,
@ -966,7 +960,7 @@ ExceptClause: ast::Excepthandler = {
)
},
<location:@L> "except" <x:(Test<"all"> "as" Identifier)> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
ast::Excepthandler::new(
location,
end_location,
@ -981,7 +975,7 @@ ExceptClause: ast::Excepthandler = {
WithStatement: ast::Stmt = {
<location:@L> <is_async:"async"?> "with" <items:WithItems> ":" <body:Suite> => {
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
let type_comment = None;
let node = if is_async.is_some() {
ast::StmtKind::AsyncWith { items, body, type_comment }
@ -1022,7 +1016,7 @@ FuncDef: ast::Stmt = {
<decorator_list:Decorator*> <location:@L> <is_async:"async"?> "def" <name:Identifier> <args:Parameters> <r:("->" Test<"all">)?> ":" <body:Suite> => {
let args = Box::new(args);
let returns = r.map(|x| Box::new(x.1));
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
let type_comment = None;
let node = if is_async.is_some() {
ast::StmtKind::AsyncFunctionDef { name, args, body, decorator_list, returns, type_comment }
@ -1197,7 +1191,7 @@ ClassDef: ast::Stmt = {
Some((_, arg, _)) => (arg.args, arg.keywords),
None => (vec![], vec![]),
};
let end_location = body.last().unwrap().end_location.unwrap();
let end_location = body.last().unwrap().end();
ast::Stmt::new(
location,
end_location,
@ -1253,11 +1247,10 @@ NamedExpressionTest: ast::Expr = {
NamedExpression: ast::Expr = {
<location:@L> <id:Identifier> <end_location:@R> ":=" <value:Test<"all">> => {
ast::Expr {
ast::Expr::new(
location,
end_location: value.end_location,
custom: (),
node: ast::ExprKind::NamedExpr {
value.end(),
ast::ExprKind::NamedExpr {
target: Box::new(ast::Expr::new(
location,
end_location,
@ -1265,7 +1258,7 @@ NamedExpression: ast::Expr = {
)),
value: Box::new(value),
}
}
)
},
};
@ -1564,7 +1557,7 @@ Atom<Goal>: ast::Expr = {
if matches!(mid.node, ast::ExprKind::Starred { .. }) {
Err(LexicalError{
error: LexicalErrorType::OtherError("cannot use starred expression here".to_string()),
location: mid.location,
location: mid.start(),
})?
}
Ok(mid)

View file

@ -35,12 +35,12 @@ pub(crate) fn validate_arguments(
let mut all_arg_names = FxHashSet::with_hasher(Default::default());
for arg in all_args {
let arg_name = &arg.node.arg;
let arg_name = &arg.arg;
// Check for duplicate arguments in the function definition.
if !all_arg_names.insert(arg_name) {
return Err(LexicalError {
error: LexicalErrorType::DuplicateArgumentError(arg_name.to_string()),
location: arg.location,
location: arg.start(),
});
}
}
@ -64,7 +64,7 @@ pub(crate) fn parse_params(
// have defaults.
return Err(LexicalError {
error: LexicalErrorType::DefaultArgumentError,
location: name.location,
location: name.start(),
});
}
Ok(())
@ -126,14 +126,14 @@ pub(crate) fn parse_args(func_args: Vec<FunctionArgument>) -> Result<ArgumentLis
if !keywords.is_empty() && !is_starred(&value) {
return Err(LexicalError {
error: LexicalErrorType::PositionalArgumentError,
location: value.location,
location: value.start(),
});
// Allow starred arguments after keyword arguments but
// not after double-starred arguments.
} else if double_starred {
return Err(LexicalError {
error: LexicalErrorType::UnpackedArgumentError,
location: value.location,
location: value.start(),
});
}