From a6146d35b1615cf5fb908b29f34e58bfde3bf96d Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Thu, 10 Jan 2019 13:54:58 +0100 Subject: Implement type inference for literals (WIP) --- crates/ra_syntax/src/lib.rs | 5 +++++ crates/ra_syntax/src/yellow.rs | 12 ++++++++++++ crates/ra_syntax/src/yellow/syntax_text.rs | 11 ++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 2a095817a..6181df9d7 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -59,24 +59,29 @@ impl SourceFile { assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); TreeArc::cast(root) } + pub fn parse(text: &str) -> TreeArc { let tokens = tokenize(&text); let (green, errors) = parser_impl::parse_with(yellow::GreenBuilder::new(), text, &tokens, grammar::root); SourceFile::new(green, errors) } + pub fn reparse(&self, edit: &AtomTextEdit) -> TreeArc { self.incremental_reparse(edit) .unwrap_or_else(|| self.full_reparse(edit)) } + pub fn incremental_reparse(&self, edit: &AtomTextEdit) -> Option> { reparsing::incremental_reparse(self.syntax(), edit, self.errors()) .map(|(green_node, errors)| SourceFile::new(green_node, errors)) } + fn full_reparse(&self, edit: &AtomTextEdit) -> TreeArc { let text = edit.apply(self.syntax().text().to_string()); SourceFile::parse(&text) } + pub fn errors(&self) -> Vec { let mut errors = self.syntax.root_data().clone(); errors.extend(validation::validate(self)); diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs index 93621d08a..03df00fc6 100644 --- a/crates/ra_syntax/src/yellow.rs +++ b/crates/ra_syntax/src/yellow.rs @@ -128,40 +128,52 @@ impl SyntaxNode { pub(crate) fn root_data(&self) -> &Vec { self.0.root_data() } + pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { self.0.replace_self(replacement) } + pub fn to_owned(&self) -> TreeArc { let ptr = TreeArc(self.0.to_owned()); TreeArc::cast(ptr) } + pub fn kind(&self) -> SyntaxKind { self.0.kind() } + pub fn range(&self) -> TextRange { self.0.range() } + pub fn text(&self) -> SyntaxText { SyntaxText::new(self) } + pub fn is_leaf(&self) -> bool { self.0.is_leaf() } + pub fn parent(&self) -> Option<&SyntaxNode> { self.0.parent().map(SyntaxNode::from_repr) } + pub fn first_child(&self) -> Option<&SyntaxNode> { self.0.first_child().map(SyntaxNode::from_repr) } + pub fn last_child(&self) -> Option<&SyntaxNode> { self.0.last_child().map(SyntaxNode::from_repr) } + pub fn next_sibling(&self) -> Option<&SyntaxNode> { self.0.next_sibling().map(SyntaxNode::from_repr) } + pub fn prev_sibling(&self) -> Option<&SyntaxNode> { self.0.prev_sibling().map(SyntaxNode::from_repr) } + pub fn children(&self) -> SyntaxNodeChildren { SyntaxNodeChildren(self.0.children()) } diff --git a/crates/ra_syntax/src/yellow/syntax_text.rs b/crates/ra_syntax/src/yellow/syntax_text.rs index 08dbe57a2..378cd1b2e 100644 --- a/crates/ra_syntax/src/yellow/syntax_text.rs +++ b/crates/ra_syntax/src/yellow/syntax_text.rs @@ -15,6 +15,7 @@ impl<'a> SyntaxText<'a> { range: node.range(), } } + pub fn chunks(&self) -> impl Iterator { let range = self.range; self.node.descendants().filter_map(move |node| { @@ -24,15 +25,19 @@ impl<'a> SyntaxText<'a> { Some(&text[range]) }) } + pub fn push_to(&self, buf: &mut String) { self.chunks().for_each(|it| buf.push_str(it)); } + pub fn to_string(&self) -> String { self.chunks().collect() } + pub fn contains(&self, c: char) -> bool { self.chunks().any(|it| it.contains(c)) } + pub fn find(&self, c: char) -> Option { let mut acc: TextUnit = 0.into(); for chunk in self.chunks() { @@ -44,9 +49,11 @@ impl<'a> SyntaxText<'a> { } None } + pub fn len(&self) -> TextUnit { self.range.len() } + pub fn slice(&self, range: impl SyntaxTextSlice) -> SyntaxText<'a> { let range = range.restrict(self.range).unwrap_or_else(|| { panic!("invalid slice, range: {:?}, slice: {:?}", self.range, range) @@ -56,8 +63,10 @@ impl<'a> SyntaxText<'a> { range, } } - pub fn char_at(&self, offset: TextUnit) -> Option { + + pub fn char_at(&self, offset: impl Into) -> Option { let mut start: TextUnit = 0.into(); + let offset = offset.into(); for chunk in self.chunks() { let end = start + TextUnit::of_str(chunk); if start <= offset && offset < end { -- cgit v1.2.3 From 5f5dc20d85dead5fbd51d163451f796255c9faea Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Thu, 10 Jan 2019 16:03:15 +0100 Subject: Try implementing integer type inference (WIP) --- crates/ra_syntax/src/yellow.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/yellow.rs b/crates/ra_syntax/src/yellow.rs index 03df00fc6..9b93945cc 100644 --- a/crates/ra_syntax/src/yellow.rs +++ b/crates/ra_syntax/src/yellow.rs @@ -128,7 +128,7 @@ impl SyntaxNode { pub(crate) fn root_data(&self) -> &Vec { self.0.root_data() } - + pub(crate) fn replace_with(&self, replacement: GreenNode) -> GreenNode { self.0.replace_self(replacement) } -- cgit v1.2.3 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_syntax/src/ast/generated.rs | 114 ++++++++++++++++++++++++- crates/ra_syntax/src/grammar.ron | 18 +++- crates/ra_syntax/src/syntax_kinds/generated.rs | 2 + 3 files changed, 128 insertions(+), 6 deletions(-) (limited to 'crates/ra_syntax') 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 From a9a6a50c759302e8a8d59bf6c53c72ec804324b3 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Mon, 14 Jan 2019 19:30:21 +0100 Subject: Fixup tests --- crates/ra_syntax/src/ast.rs | 46 +++++++++ crates/ra_syntax/src/ast/generated.rs | 132 ++++++++++++++++++------- crates/ra_syntax/src/grammar.ron | 11 ++- crates/ra_syntax/src/lib.rs | 2 +- crates/ra_syntax/src/syntax_kinds/generated.rs | 2 - 5 files changed, 148 insertions(+), 45 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast.rs b/crates/ra_syntax/src/ast.rs index 8bf439b60..211ba31e5 100644 --- a/crates/ra_syntax/src/ast.rs +++ b/crates/ra_syntax/src/ast.rs @@ -609,6 +609,52 @@ impl SelfParam { } } +#[derive(Clone, Debug, PartialEq, Eq, Hash)] +pub enum LiteralFlavor { + String, + ByteString, + Char, + Byte, + IntNumber { suffix: Option }, + FloatNumber { suffix: Option }, + Bool, +} + +impl LiteralExpr { + pub fn flavor(&self) -> LiteralFlavor { + let syntax = self.syntax(); + match syntax.kind() { + INT_NUMBER => { + let allowed_suffix_list = [ + "isize", "i128", "i64", "i32", "i16", "i8", "usize", "u128", "u64", "u32", + "u16", "u8", + ]; + let text = syntax.text().to_string(); + let suffix = allowed_suffix_list + .iter() + .find(|&s| text.ends_with(s)) + .map(|&suf| SmolStr::new(suf)); + LiteralFlavor::IntNumber { suffix: suffix } + } + FLOAT_NUMBER => { + let allowed_suffix_list = ["f64", "f32"]; + let text = syntax.text().to_string(); + let suffix = allowed_suffix_list + .iter() + .find(|&s| text.ends_with(s)) + .map(|&suf| SmolStr::new(suf)); + LiteralFlavor::FloatNumber { suffix: suffix } + } + STRING | RAW_STRING => LiteralFlavor::String, + TRUE_KW | FALSE_KW => LiteralFlavor::Bool, + BYTE_STRING | RAW_BYTE_STRING => LiteralFlavor::ByteString, + CHAR => LiteralFlavor::Char, + BYTE => LiteralFlavor::Byte, + _ => unreachable!(), + } + } +} + #[test] fn test_doc_comment_of_items() { let file = SourceFile::parse( diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index 442659aee..cad845ec0 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), - LiteralExpr(&'a LiteralExpr), + Literal(&'a Literal), } impl AstNode for Expr { @@ -696,7 +696,7 @@ impl AstNode for Expr { | PREFIX_EXPR | RANGE_EXPR | BIN_EXPR - | LITERAL_EXPR => Some(Expr::from_repr(syntax.into_repr())), + | LITERAL => 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_EXPR => ExprKind::LiteralExpr(LiteralExpr::cast(&self.syntax).unwrap()), + LITERAL => ExprKind::Literal(Literal::cast(&self.syntax).unwrap()), _ => unreachable!(), } } @@ -793,6 +793,31 @@ impl AstNode for ExternCrateItem { impl ExternCrateItem {} +// FalseKw +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct FalseKw { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for FalseKw { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for FalseKw { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + FALSE_KW => Some(FalseKw::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for FalseKw {} +impl FalseKw {} + // FieldExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -867,7 +892,7 @@ impl AstNode for FloatNumber { } } fn syntax(&self) -> &SyntaxNode { &self.syntax } - fn to_owned(&self) -> TreePtr { TreePtr::cast(self.syntax.to_owned()) } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } } @@ -1173,7 +1198,7 @@ impl AstNode for IntNumber { } } fn syntax(&self) -> &SyntaxNode { &self.syntax } - fn to_owned(&self) -> TreePtr { TreePtr::cast(self.syntax.to_owned()) } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } } @@ -1365,25 +1390,10 @@ 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() { - | STRING - | BYTE_STRING - | CHAR - | BYTE - | INT_NUMBER - | FLOAT_NUMBER => Some(Literal::from_repr(syntax.into_repr())), + LITERAL => Some(Literal::from_repr(syntax.into_repr())), _ => None, } } @@ -1391,22 +1401,13 @@ 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!(), - } + pub fn literal_expr(&self) -> Option<&LiteralExpr> { + super::child_opt(self) } } -impl Literal {} - // LiteralExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -1417,24 +1418,54 @@ unsafe impl TransparentNewType for LiteralExpr { type Repr = rowan::SyntaxNode; } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum LiteralExprKind<'a> { + String(&'a String), + ByteString(&'a ByteString), + Char(&'a Char), + Byte(&'a Byte), + IntNumber(&'a IntNumber), + FloatNumber(&'a FloatNumber), + TrueKw(&'a TrueKw), + FalseKw(&'a FalseKw), +} + impl AstNode for LiteralExpr { fn cast(syntax: &SyntaxNode) -> Option<&Self> { match syntax.kind() { - LITERAL_EXPR => Some(LiteralExpr::from_repr(syntax.into_repr())), + | STRING + | BYTE_STRING + | CHAR + | BYTE + | INT_NUMBER + | FLOAT_NUMBER + | TRUE_KW + | FALSE_KW => 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()) } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } } - impl LiteralExpr { - pub fn literal(&self) -> Option<&Literal> { - super::child_opt(self) + pub fn kind(&self) -> LiteralExprKind { + match self.syntax.kind() { + STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()), + BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()), + CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()), + BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()), + INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()), + FLOAT_NUMBER => LiteralExprKind::FloatNumber(FloatNumber::cast(&self.syntax).unwrap()), + TRUE_KW => LiteralExprKind::TrueKw(TrueKw::cast(&self.syntax).unwrap()), + FALSE_KW => LiteralExprKind::FalseKw(FalseKw::cast(&self.syntax).unwrap()), + _ => unreachable!(), + } } } +impl LiteralExpr {} + // LoopExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] @@ -3025,6 +3056,31 @@ impl ast::AttrsOwner for TraitDef {} impl ast::DocCommentsOwner for TraitDef {} impl TraitDef {} +// TrueKw +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct TrueKw { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for TrueKw { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for TrueKw { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + TRUE_KW => Some(TrueKw::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for TrueKw {} +impl TrueKw {} + // TryExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 49b297696..34d2a27d1 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -215,7 +215,6 @@ Grammar( "PATH", "PATH_SEGMENT", "LITERAL", - "LITERAL_EXPR", "ALIAS", "VISIBILITY", "WHERE_CLAUSE", @@ -434,7 +433,9 @@ Grammar( "Byte": ( traits: ["AstToken"] ), "ByteString": ( traits: ["AstToken"] ), "Char": ( traits: ["AstToken"] ), - "Literal": ( + "TrueKw": ( traits: ["AstToken"] ), + "FalseKw": ( traits: ["AstToken"] ), + "LiteralExpr": ( enum: [ "String", "ByteString", @@ -442,9 +443,11 @@ Grammar( "Byte", "IntNumber", "FloatNumber", + "TrueKw", + "FalseKw", ] ), - "LiteralExpr": (options: ["Literal"]), + "Literal": (options: ["LiteralExpr"]), "Expr": ( enum: [ @@ -474,7 +477,7 @@ Grammar( "PrefixExpr", "RangeExpr", "BinExpr", - "LiteralExpr", + "Literal", ], ), diff --git a/crates/ra_syntax/src/lib.rs b/crates/ra_syntax/src/lib.rs index 6181df9d7..bc311cbbc 100644 --- a/crates/ra_syntax/src/lib.rs +++ b/crates/ra_syntax/src/lib.rs @@ -59,7 +59,7 @@ impl SourceFile { assert_eq!(root.kind(), SyntaxKind::SOURCE_FILE); TreeArc::cast(root) } - + pub fn parse(text: &str) -> TreeArc { let tokens = tokenize(&text); let (green, errors) = diff --git a/crates/ra_syntax/src/syntax_kinds/generated.rs b/crates/ra_syntax/src/syntax_kinds/generated.rs index 46795d6e9..830fac9f4 100644 --- a/crates/ra_syntax/src/syntax_kinds/generated.rs +++ b/crates/ra_syntax/src/syntax_kinds/generated.rs @@ -205,7 +205,6 @@ pub enum SyntaxKind { PATH, PATH_SEGMENT, LITERAL, - LITERAL_EXPR, ALIAS, VISIBILITY, WHERE_CLAUSE, @@ -468,7 +467,6 @@ 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 From d67eabb512a08a451a649c7f20e4e9ae1860a8a0 Mon Sep 17 00:00:00 2001 From: Marcus Klaas de Vries Date: Mon, 14 Jan 2019 20:56:14 +0100 Subject: Fix type inference for raw (byte) strings --- crates/ra_syntax/src/ast/generated.rs | 56 +++++++++++++++++++++++++++++++++++ crates/ra_syntax/src/grammar.ron | 4 +++ crates/ra_syntax/src/lexer/strings.rs | 15 +--------- 3 files changed, 61 insertions(+), 14 deletions(-) (limited to 'crates/ra_syntax') diff --git a/crates/ra_syntax/src/ast/generated.rs b/crates/ra_syntax/src/ast/generated.rs index cad845ec0..3471d5226 100644 --- a/crates/ra_syntax/src/ast/generated.rs +++ b/crates/ra_syntax/src/ast/generated.rs @@ -1422,6 +1422,8 @@ unsafe impl TransparentNewType for LiteralExpr { pub enum LiteralExprKind<'a> { String(&'a String), ByteString(&'a ByteString), + RawString(&'a RawString), + RawByteString(&'a RawByteString), Char(&'a Char), Byte(&'a Byte), IntNumber(&'a IntNumber), @@ -1435,6 +1437,8 @@ impl AstNode for LiteralExpr { match syntax.kind() { | STRING | BYTE_STRING + | RAW_STRING + | RAW_BYTE_STRING | CHAR | BYTE | INT_NUMBER @@ -1453,6 +1457,8 @@ impl LiteralExpr { match self.syntax.kind() { STRING => LiteralExprKind::String(String::cast(&self.syntax).unwrap()), BYTE_STRING => LiteralExprKind::ByteString(ByteString::cast(&self.syntax).unwrap()), + RAW_STRING => LiteralExprKind::RawString(RawString::cast(&self.syntax).unwrap()), + RAW_BYTE_STRING => LiteralExprKind::RawByteString(RawByteString::cast(&self.syntax).unwrap()), CHAR => LiteralExprKind::Char(Char::cast(&self.syntax).unwrap()), BYTE => LiteralExprKind::Byte(Byte::cast(&self.syntax).unwrap()), INT_NUMBER => LiteralExprKind::IntNumber(IntNumber::cast(&self.syntax).unwrap()), @@ -2543,6 +2549,56 @@ impl AstNode for RangePat { impl RangePat {} +// RawByteString +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct RawByteString { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for RawByteString { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for RawByteString { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + RAW_BYTE_STRING => Some(RawByteString::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for RawByteString {} +impl RawByteString {} + +// RawString +#[derive(Debug, PartialEq, Eq, Hash)] +#[repr(transparent)] +pub struct RawString { + pub(crate) syntax: SyntaxNode, +} +unsafe impl TransparentNewType for RawString { + type Repr = rowan::SyntaxNode; +} + +impl AstNode for RawString { + fn cast(syntax: &SyntaxNode) -> Option<&Self> { + match syntax.kind() { + RAW_STRING => Some(RawString::from_repr(syntax.into_repr())), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } + fn to_owned(&self) -> TreeArc { TreeArc::cast(self.syntax.to_owned()) } +} + + +impl ast::AstToken for RawString {} +impl RawString {} + // RefExpr #[derive(Debug, PartialEq, Eq, Hash)] #[repr(transparent)] diff --git a/crates/ra_syntax/src/grammar.ron b/crates/ra_syntax/src/grammar.ron index 34d2a27d1..bd8c5b411 100644 --- a/crates/ra_syntax/src/grammar.ron +++ b/crates/ra_syntax/src/grammar.ron @@ -430,7 +430,9 @@ Grammar( "IntNumber": ( traits: ["AstToken"] ), "FloatNumber": ( traits: ["AstToken"] ), "String": ( traits: ["AstToken"] ), + "RawString": ( traits: ["AstToken"] ), "Byte": ( traits: ["AstToken"] ), + "RawByteString": ( traits: ["AstToken"] ), "ByteString": ( traits: ["AstToken"] ), "Char": ( traits: ["AstToken"] ), "TrueKw": ( traits: ["AstToken"] ), @@ -439,6 +441,8 @@ Grammar( enum: [ "String", "ByteString", + "RawString", + "RawByteString", "Char", "Byte", "IntNumber", diff --git a/crates/ra_syntax/src/lexer/strings.rs b/crates/ra_syntax/src/lexer/strings.rs index 5090feae6..0865b7f3b 100644 --- a/crates/ra_syntax/src/lexer/strings.rs +++ b/crates/ra_syntax/src/lexer/strings.rs @@ -49,7 +49,7 @@ pub(crate) fn scan_byte_char_or_string(ptr: &mut Ptr) -> SyntaxKind { BYTE_STRING } 'r' => { - scan_raw_byte_string(ptr); + scan_raw_string(ptr); RAW_BYTE_STRING } _ => unreachable!(), @@ -108,16 +108,3 @@ fn scan_byte(ptr: &mut Ptr) { fn scan_byte_string(ptr: &mut Ptr) { scan_string(ptr) } - -fn scan_raw_byte_string(ptr: &mut Ptr) { - if !ptr.at('"') { - return; - } - ptr.bump(); - - while let Some(c) = ptr.bump() { - if c == '"' { - return; - } - } -} -- cgit v1.2.3