Attempt to implement typed accessors

This commit is contained in:
Geoffry Song 2019-11-15 12:05:29 -08:00
parent a68aefdc46
commit 5645c153e0
4 changed files with 50 additions and 8 deletions

View File

@ -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::*,

View File

@ -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)

View File

@ -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(),
));
}
}

View File

@ -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