From 606d66a714bb8fe07f35a6af83d04ab576b9a0e1 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Fri, 11 Jan 2019 11:27:07 +0100 Subject: Start moving literal interpretation to the AST (WIP) --- crates/ra_hir/src/expr.rs | 7 +- crates/ra_syntax/src/ast/generated.rs | 114 ++++++++++++++++++++++++- crates/ra_syntax/src/grammar.ron | 18 +++- crates/ra_syntax/src/syntax_kinds/generated.rs | 2 + 4 files changed, 131 insertions(+), 10 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 52af2af45..3f2689781 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -649,10 +649,9 @@ impl ExprCollector { let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) } - ast::ExprKind::Literal(e) => { - let child = e.syntax().children().next(); - - if let Some(c) = child { + ast::ExprKind::LiteralExpr(e) => { + if let Some(child) = e.literal() { + let c = child.syntax(); let lit = match c.kind() { SyntaxKind::INT_NUMBER => { let text = c.text().to_string(); diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 94842a514..442659aee 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -664,7 +664,7 @@ pub enum ExprKind<'a> { PrefixExpr(&'a PrefixExpr), RangeExpr(&'a RangeExpr), BinExpr(&'a BinExpr), - Literal(&'a Literal), + LiteralExpr(&'a LiteralExpr), } impl AstNode for Expr { @@ -696,7 +696,7 @@ impl AstNode for Expr { | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR - | LITERAL => Some(Expr::from_repr(syntax.into_repr())), + | LITERAL_EXPR => Some(Expr::from_repr(syntax.into_repr())), _ => None, } } @@ -733,7 +733,7 @@ impl Expr { PREFIX_EXPR => ExprKind::PrefixExpr(PrefixExpr::cast(&self.syntax).unwrap()), RANGE_EXPR => ExprKind::RangeExpr(RangeExpr::cast(&self.syntax).unwrap()), BIN_EXPR => ExprKind::BinExpr(BinExpr::cast(&self.syntax).unwrap()), - LITERAL => ExprKind::Literal(Literal::cast(&self.syntax).unwrap()), + LITERAL_EXPR => ExprKind::LiteralExpr(LiteralExpr::cast(&self.syntax).unwrap()), _ => unreachable!(), } } @@ -849,6 +849,31 @@ impl AstNode for FieldPatList { impl FieldPatList {} +// FloatNumber +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct FloatNumber { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for FloatNumber { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for FloatNumber { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + FLOAT_NUMBER => Some(FloatNumber::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreePtr { TreePtr::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for FloatNumber {} +impl FloatNumber {} + // FnDef #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -1130,6 +1155,31 @@ impl AstNode for IndexExpr { impl IndexExpr {} +// IntNumber +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct IntNumber { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for IntNumber { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for IntNumber { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + INT_NUMBER => Some(IntNumber::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreePtr { TreePtr::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for IntNumber {} +impl IntNumber {} + // ItemList #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -1315,10 +1365,25 @@ unsafe impl TransparentNewType for Literal { type Repr = rowan::SyntaxNode; } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LiteralKind<'a> { + String(&'a String), + ByteString(&'a ByteString), + Char(&'a Char), + Byte(&'a Byte), + IntNumber(&'a IntNumber), + FloatNumber(&'a FloatNumber), +} + impl AstNode for Literal { fn cast(syntax: &SyntaxNode) -> Option<&Self> { match syntax.kind() { - LITERAL => Some(Literal::from_repr(syntax.into_repr())), + | STRING + | BYTE_STRING + | CHAR + | BYTE + | INT_NUMBER + | FLOAT_NUMBER => Some(Literal::from_repr(syntax.into_repr())), _ => None, } } @@ -1326,9 +1391,50 @@ impl AstNode for Literal { fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } } +impl Literal { + pub fn kind(&self) -> LiteralKind { + match self.syntax.kind() { + STRING => LiteralKind::String(String::cast(&self.syntax).unwrap()), + BYTE_STRING => LiteralKind::ByteString(ByteString::cast(&self.syntax).unwrap()), + CHAR => LiteralKind::Char(Char::cast(&self.syntax).unwrap()), + BYTE => LiteralKind::Byte(Byte::cast(&self.syntax).unwrap()), + INT_NUMBER => LiteralKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()), + FLOAT_NUMBER => LiteralKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()), + _ => unreachable!(), + } + } +} impl Literal {} +// LiteralExpr +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct LiteralExpr { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for LiteralExpr { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for LiteralExpr { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + LITERAL_EXPR => Some(LiteralExpr::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreePtr { TreePtr::cast(self.syntax.to_owned()) } +} + + +impl LiteralExpr { + pub fn literal(&self) -> Option<&Literal> { + super::child_opt(self) + } +} + // LoopExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index dfd88bd10..49b297696 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -215,6 +215,7 @@ Grammar( "PATH", "PATH_SEGMENT", "LITERAL", + "LITERAL_EXPR", "ALIAS", "VISIBILITY", "WHERE_CLAUSE", @@ -426,11 +427,24 @@ Grammar( "PrefixExpr": (options: ["Expr"]), "RangeExpr": (), "BinExpr": (), + + "IntNumber": ( traits: ["AstToken"] ), + "FloatNumber": ( traits: ["AstToken"] ), "String": ( traits: ["AstToken"] ), "Byte": ( traits: ["AstToken"] ), "ByteString": ( traits: ["AstToken"] ), "Char": ( traits: ["AstToken"] ), - "Literal": (), + "Literal": ( + enum: [ + "String", + "ByteString", + "Char", + "Byte", + "IntNumber", + "FloatNumber", + ] + ), + "LiteralExpr": (options: ["Literal"]), "Expr": ( enum: [ @@ -460,7 +474,7 @@ Grammar( "PrefixExpr", "RangeExpr", "BinExpr", - "Literal", + "LiteralExpr", ], ), diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs index 830fac9f4..46795d6e9 100644 --- a/crates/ra_syntax/src/syntax_kinds/generated.rs +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs @@ -205,6 +205,7 @@ pub enum SyntaxKind { PATH, PATH_SEGMENT, LITERAL, + LITERAL_EXPR, ALIAS, VISIBILITY, WHERE_CLAUSE, @@ -467,6 +468,7 @@ impl SyntaxKind { PATH => &SyntaxInfo { name: "PATH" }, PATH_SEGMENT => &SyntaxInfo { name: "PATH_SEGMENT" }, LITERAL => &SyntaxInfo { name: "LITERAL" }, + LITERAL_EXPR => &SyntaxInfo { name: "LITERAL_EXPR" }, ALIAS => &SyntaxInfo { name: "ALIAS" }, VISIBILITY => &SyntaxInfo { name: "VISIBILITY" }, WHERE_CLAUSE => &SyntaxInfo { name: "WHERE_CLAUSE" }, -- cgit v1.2.3