Attempt to implement typed accessors
This commit is contained in:
parent
a68aefdc46
commit
5645c153e0
@ -16,7 +16,7 @@
|
||||
};
|
||||
|
||||
pub use self::{
|
||||
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp},
|
||||
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
|
||||
extensions::{FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind},
|
||||
generated::*,
|
||||
tokens::*,
|
||||
|
@ -189,6 +189,52 @@ pub fn sub_exprs(&self) -> (Option<ast::Expr>, Option<ast::Expr>) {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
|
||||
pub enum RangeOp {
|
||||
/// `..`
|
||||
Exclusive,
|
||||
/// `..=`
|
||||
Inclusive,
|
||||
}
|
||||
|
||||
impl ast::RangeExpr {
|
||||
fn op_details(&self) -> Option<(usize, SyntaxToken, RangeOp)> {
|
||||
self.syntax().children_with_tokens().enumerate().find_map(|(ix, child)| {
|
||||
let token = child.into_token()?;
|
||||
let bin_op = match token.kind() {
|
||||
T![..] => RangeOp::Exclusive,
|
||||
T![..=] => RangeOp::Inclusive,
|
||||
_ => return None,
|
||||
};
|
||||
Some((ix, token, bin_op))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn op_kind(&self) -> Option<RangeOp> {
|
||||
self.op_details().map(|t| t.2)
|
||||
}
|
||||
|
||||
pub fn op_token(&self) -> Option<SyntaxToken> {
|
||||
self.op_details().map(|t| t.1)
|
||||
}
|
||||
|
||||
pub fn start(&self) -> Option<ast::Expr> {
|
||||
let op_ix = self.op_details()?.0;
|
||||
self.syntax()
|
||||
.children_with_tokens()
|
||||
.take(op_ix)
|
||||
.find_map(|it| ast::Expr::cast(it.into_node()?))
|
||||
}
|
||||
|
||||
pub fn end(&self) -> Option<ast::Expr> {
|
||||
let op_ix = self.op_details()?.0;
|
||||
self.syntax()
|
||||
.children_with_tokens()
|
||||
.skip(op_ix + 1)
|
||||
.find_map(|it| ast::Expr::cast(it.into_node()?))
|
||||
}
|
||||
}
|
||||
|
||||
impl ast::IndexExpr {
|
||||
pub fn base(&self) -> Option<ast::Expr> {
|
||||
children(self).nth(0)
|
||||
|
@ -230,14 +230,10 @@ fn validate_visibility(vis: ast::Visibility, errors: &mut Vec<SyntaxError>) {
|
||||
}
|
||||
|
||||
fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) {
|
||||
let last_child = match expr.syntax().last_child_or_token() {
|
||||
Some(it) => it,
|
||||
None => return,
|
||||
};
|
||||
if last_child.kind() == T![..=] {
|
||||
if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() {
|
||||
errors.push(SyntaxError::new(
|
||||
SyntaxErrorKind::InclusiveRangeMissingEnd,
|
||||
last_child.text_range(),
|
||||
expr.syntax().text_range(),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -26,5 +26,5 @@ SOURCE_FILE@[0; 33)
|
||||
WHITESPACE@[30; 31) "\n"
|
||||
R_CURLY@[31; 32) "}"
|
||||
WHITESPACE@[32; 33) "\n"
|
||||
error [17; 20): An inclusive range must have an end expression
|
||||
error [16; 20): An inclusive range must have an end expression
|
||||
error [26; 29): An inclusive range must have an end expression
|
||||
|
Loading…
Reference in New Issue
Block a user