Attempt to implement typed accessors
This commit is contained in:
parent
a68aefdc46
commit
5645c153e0
@ -16,7 +16,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub use self::{
|
pub use self::{
|
||||||
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp},
|
expr_extensions::{ArrayExprKind, BinOp, ElseBranch, LiteralKind, PrefixOp, RangeOp},
|
||||||
extensions::{FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind},
|
extensions::{FieldKind, PathSegmentKind, SelfParamKind, StructKind, TypeBoundKind},
|
||||||
generated::*,
|
generated::*,
|
||||||
tokens::*,
|
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 {
|
impl ast::IndexExpr {
|
||||||
pub fn base(&self) -> Option<ast::Expr> {
|
pub fn base(&self) -> Option<ast::Expr> {
|
||||||
children(self).nth(0)
|
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>) {
|
fn validate_range_expr(expr: ast::RangeExpr, errors: &mut Vec<SyntaxError>) {
|
||||||
let last_child = match expr.syntax().last_child_or_token() {
|
if expr.op_kind() == Some(ast::RangeOp::Inclusive) && expr.end().is_none() {
|
||||||
Some(it) => it,
|
|
||||||
None => return,
|
|
||||||
};
|
|
||||||
if last_child.kind() == T![..=] {
|
|
||||||
errors.push(SyntaxError::new(
|
errors.push(SyntaxError::new(
|
||||||
SyntaxErrorKind::InclusiveRangeMissingEnd,
|
SyntaxErrorKind::InclusiveRangeMissingEnd,
|
||||||
last_child.text_range(),
|
expr.syntax().text_range(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,5 +26,5 @@ SOURCE_FILE@[0; 33)
|
|||||||
WHITESPACE@[30; 31) "\n"
|
WHITESPACE@[30; 31) "\n"
|
||||||
R_CURLY@[31; 32) "}"
|
R_CURLY@[31; 32) "}"
|
||||||
WHITESPACE@[32; 33) "\n"
|
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
|
error [26; 29): An inclusive range must have an end expression
|
||||||
|
Loading…
Reference in New Issue
Block a user