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_hir/src/expr.rs | 141 ++++++++++--------------- crates/ra_hir/src/name.rs | 2 +- crates/ra_hir/src/ty.rs | 46 ++++---- crates/ra_hir/src/ty/tests.rs | 5 +- crates/ra_hir/src/ty/tests/data/binary_op.txt | 86 +++++++-------- crates/ra_hir/src/ty/tests/data/literals.txt | 3 +- crates/ra_hir/src/ty/tests/data/tuple.txt | 18 ++-- 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 - 12 files changed, 283 insertions(+), 211 deletions(-) (limited to 'crates') diff --git a/crates/ra_hir/src/expr.rs b/crates/ra_hir/src/expr.rs index 3f2689781..2f3432870 100644 --- a/crates/ra_hir/src/expr.rs +++ b/crates/ra_hir/src/expr.rs @@ -6,12 +6,11 @@ use rustc_hash::FxHashMap; use ra_arena::{Arena, RawId, impl_arena_id, map::ArenaMap}; use ra_db::{LocalSyntaxPtr, Cancelable}; use ra_syntax::{ - SyntaxKind, - ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner} + ast::{self, AstNode, LoopBodyOwner, ArgListOwner, NameOwner, LiteralFlavor} }; use crate::{Path, type_ref::{Mutability, TypeRef}, Name, HirDatabase, DefId, Def, name::AsName}; -use crate::ty::primitive::{UintTy, IntTy, FloatTy, UncertainIntTy, UncertainFloatTy}; +use crate::ty::primitive::{UintTy, UncertainIntTy, UncertainFloatTy}; #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct ExprId(RawId); @@ -649,93 +648,59 @@ impl ExprCollector { let exprs = e.exprs().map(|expr| self.collect_expr(expr)).collect(); self.alloc_expr(Expr::Tuple { exprs }, syntax_ptr) } - 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(); - - // FIXME: don't do it like this. maybe use something like - // the IntTy::from_name functions - let ty = if text.ends_with("isize") { - UncertainIntTy::Signed(IntTy::Isize) - } else if text.ends_with("i128") { - UncertainIntTy::Signed(IntTy::I128) - } else if text.ends_with("i64") { - UncertainIntTy::Signed(IntTy::I64) - } else if text.ends_with("i32") { - UncertainIntTy::Signed(IntTy::I32) - } else if text.ends_with("i16") { - UncertainIntTy::Signed(IntTy::I16) - } else if text.ends_with("i8") { - UncertainIntTy::Signed(IntTy::I8) - } else if text.ends_with("usize") { - UncertainIntTy::Unsigned(UintTy::Usize) - } else if text.ends_with("u128") { - UncertainIntTy::Unsigned(UintTy::U128) - } else if text.ends_with("u64") { - UncertainIntTy::Unsigned(UintTy::U64) - } else if text.ends_with("u32") { - UncertainIntTy::Unsigned(UintTy::U32) - } else if text.ends_with("u16") { - UncertainIntTy::Unsigned(UintTy::U16) - } else if text.ends_with("u8") { - UncertainIntTy::Unsigned(UintTy::U8) - } else { - UncertainIntTy::Unknown - }; - - // TODO: actually parse integer - Literal::Int(0u64, ty) - } - SyntaxKind::FLOAT_NUMBER => { - let text = c.text().to_string(); - - // FIXME: don't do it like this. maybe use something like - // the IntTy::from_name functions - let ty = if text.ends_with("f64") { - UncertainFloatTy::Known(FloatTy::F64) - } else if text.ends_with("f32") { - UncertainFloatTy::Known(FloatTy::F32) - } else { - UncertainFloatTy::Unknown - }; - - // TODO: actually parse value - Literal::Float(0, ty) - } - SyntaxKind::STRING => { - // FIXME: this likely includes the " characters - let text = c.text().to_string(); - Literal::String(text) - } - SyntaxKind::TRUE_KW => Literal::Bool(true), - SyntaxKind::FALSE_KW => Literal::Bool(false), - SyntaxKind::BYTE_STRING => { - // FIXME: this is completely incorrect for a variety - // of reasons, but at least it gives the right type - let bytes = c.text().to_string().into_bytes(); - Literal::ByteString(bytes) - } - SyntaxKind::CHAR => { - let character = c.text().char_at(1).unwrap_or('X'); - Literal::Char(character) + ast::ExprKind::Literal(e) => { + let child = if let Some(child) = e.literal_expr() { + child + } else { + return self.alloc_expr(Expr::Missing, syntax_ptr); + }; + let c = child.syntax(); + + let lit = match child.flavor() { + LiteralFlavor::IntNumber { suffix } => { + let known_name = suffix + .map(|s| Name::new(s)) + .and_then(|name| UncertainIntTy::from_name(&name)); + + if let Some(kn) = known_name { + Literal::Int(0u64, kn) + } else { + Literal::Int(0u64, UncertainIntTy::Unknown) } - SyntaxKind::BYTE => { - let character = c.text().char_at(1).unwrap_or('X'); - Literal::Int( - character as u8 as u64, - UncertainIntTy::Unsigned(UintTy::U8), - ) + } + LiteralFlavor::FloatNumber { suffix } => { + let known_name = suffix + .map(|s| Name::new(s)) + .and_then(|name| UncertainFloatTy::from_name(&name)); + + if let Some(kn) = known_name { + Literal::Float(0u64, kn) + } else { + Literal::Float(0u64, UncertainFloatTy::Unknown) } - _ => return self.alloc_expr(Expr::Missing, syntax_ptr), - }; - - self.alloc_expr(Expr::Literal(lit), syntax_ptr) - } else { - self.alloc_expr(Expr::Missing, syntax_ptr) - } + } + LiteralFlavor::ByteString => { + // FIXME: this is completely incorrect for a variety + // of reasons, but at least it gives the right type + let bytes = c.text().to_string().into_bytes(); + Literal::ByteString(bytes) + } + LiteralFlavor::String => { + // FIXME: this likely includes the " characters + let text = c.text().to_string(); + Literal::String(text) + } + LiteralFlavor::Byte => { + let character = c.text().char_at(1).unwrap_or('X'); + Literal::Int(character as u8 as u64, UncertainIntTy::Unsigned(UintTy::U8)) + } + LiteralFlavor::Bool => Literal::Bool(true), + LiteralFlavor::Char => { + let character = c.text().char_at(1).unwrap_or('X'); + Literal::Char(character) + } + }; + self.alloc_expr(Expr::Literal(lit), syntax_ptr) } // TODO implement HIR for these: diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs index d9683549c..8d786d2ac 100644 --- a/crates/ra_hir/src/name.rs +++ b/crates/ra_hir/src/name.rs @@ -23,7 +23,7 @@ impl fmt::Debug for Name { } impl Name { - fn new(text: SmolStr) -> Name { + pub(crate) fn new(text: SmolStr) -> Name { Name { text } } diff --git a/crates/ra_hir/src/ty.rs b/crates/ra_hir/src/ty.rs index de5ec5b46..b6577ee5e 100644 --- a/crates/ra_hir/src/ty.rs +++ b/crates/ra_hir/src/ty.rs @@ -111,7 +111,7 @@ impl UnifyValue for TypeVarValue { /// values for general types, and for integer and float variables. The latter /// two are used for inference of literal values (e.g. `100` could be one of /// several integer types). -#[derive(Clone, PartialEq, Eq, Hash, Debug)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug)] pub enum InferTy { TypeVar(TypeVarId), IntVar(TypeVarId), @@ -119,6 +119,12 @@ pub enum InferTy { } impl InferTy { + fn to_inner(self) -> TypeVarId { + match self { + InferTy::TypeVar(ty) | InferTy::IntVar(ty) | InferTy::FloatVar(ty) => ty, + } + } + fn fallback_value(self) -> Ty { match self { InferTy::TypeVar(..) => Ty::Unknown, @@ -326,18 +332,19 @@ impl Ty { path: &Path, ) -> Cancelable { if let Some(name) = path.as_ident() { - if let Some(KnownName::Bool) = name.as_known_name() { - return Ok(Ty::Bool); - } else if let Some(KnownName::Char) = name.as_known_name() { - return Ok(Ty::Char); - } else if let Some(KnownName::Str) = name.as_known_name() { - return Ok(Ty::Str); - } else if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { + if let Some(int_ty) = primitive::UncertainIntTy::from_name(name) { return Ok(Ty::Int(int_ty)); } else if let Some(float_ty) = primitive::UncertainFloatTy::from_name(name) { return Ok(Ty::Float(float_ty)); } else if name.as_known_name() == Some(KnownName::SelfType) { return Ty::from_hir_opt(db, module, None, impl_block.map(|i| i.target_type())); + } else if let Some(known) = name.as_known_name() { + match known { + KnownName::Bool => return Ok(Ty::Bool), + KnownName::Char => return Ok(Ty::Char), + KnownName::Str => return Ok(Ty::Str), + _ => {} + } } } @@ -793,10 +800,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// known type. fn resolve_ty_as_possible(&mut self, ty: Ty) -> Ty { ty.fold(&mut |ty| match ty { - Ty::Infer(InferTy::TypeVar(tv)) - | Ty::Infer(InferTy::IntVar(tv)) - | Ty::Infer(InferTy::FloatVar(tv)) => { - if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { + Ty::Infer(tv) => { + let inner = tv.to_inner(); + if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { // known_ty may contain other variables that are known by now self.resolve_ty_as_possible(known_ty.clone()) } else { @@ -811,8 +817,9 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// otherwise, return ty. fn resolve_ty_shallow<'b>(&mut self, ty: &'b Ty) -> Cow<'b, Ty> { match ty { - Ty::Infer(InferTy::TypeVar(tv)) => { - match self.var_unification_table.probe_value(*tv).known() { + Ty::Infer(tv) => { + let inner = tv.to_inner(); + match self.var_unification_table.probe_value(inner).known() { Some(known_ty) => { // The known_ty can't be a type var itself Cow::Owned(known_ty.clone()) @@ -828,16 +835,13 @@ impl<'a, D: HirDatabase> InferenceContext<'a, D> { /// replaced by Ty::Unknown. fn resolve_ty_completely(&mut self, ty: Ty) -> Ty { ty.fold(&mut |ty| match ty { - Ty::Infer(i) => { - let tv = match i { - InferTy::TypeVar(tv) | InferTy::IntVar(tv) | InferTy::FloatVar(tv) => tv, - }; - - if let Some(known_ty) = self.var_unification_table.probe_value(tv).known() { + Ty::Infer(tv) => { + let inner = tv.to_inner(); + if let Some(known_ty) = self.var_unification_table.probe_value(inner).known() { // known_ty may contain other variables that are known by now self.resolve_ty_completely(known_ty.clone()) } else { - i.fallback_value() + tv.fallback_value() } } _ => ty, diff --git a/crates/ra_hir/src/ty/tests.rs b/crates/ra_hir/src/ty/tests.rs index 53ea99874..cbdb2a4b7 100644 --- a/crates/ra_hir/src/ty/tests.rs +++ b/crates/ra_hir/src/ty/tests.rs @@ -145,6 +145,7 @@ fn test() { 3.14; 5000; false; + true; } "#, "literals.txt", @@ -199,7 +200,7 @@ fn f(x: bool) -> i32 { 0i32 } -fn test() { +fn test() -> bool { let x = a && b; let y = true || false; let z = x == y; @@ -296,8 +297,6 @@ fn test(x: &str, y: isize) { let b = (a, x); let c = (y, x); let d = (c, x); - - // we have not infered these case yet. let e = (1, "e"); let f = (e, "d"); } diff --git a/crates/ra_hir/src/ty/tests/data/binary_op.txt b/crates/ra_hir/src/ty/tests/data/binary_op.txt index 7fdb8a900..58a727691 100644 --- a/crates/ra_hir/src/ty/tests/data/binary_op.txt +++ b/crates/ra_hir/src/ty/tests/data/binary_op.txt @@ -1,46 +1,46 @@ [6; 7) 'x': bool [22; 34) '{ 0i32 }': i32 [28; 32) '0i32': i32 -[46; 342) '{ ... < 3 }': bool -[56; 57) 'x': bool -[60; 61) 'a': bool -[60; 66) 'a && b': bool -[65; 66) 'b': bool -[76; 77) 'y': bool -[80; 84) 'true': bool -[80; 93) 'true || false': bool -[88; 93) 'false': bool -[103; 104) 'z': bool -[107; 108) 'x': bool -[107; 113) 'x == y': bool -[112; 113) 'y': bool -[123; 134) 'minus_forty': isize -[144; 152) '-40isize': isize -[145; 152) '40isize': isize -[162; 163) 'h': bool -[166; 177) 'minus_forty': isize -[166; 188) 'minus_...ONST_2': bool -[181; 188) 'CONST_2': isize -[198; 199) 'c': i32 -[202; 203) 'f': fn(bool) -> i32 -[202; 211) 'f(z || y)': i32 -[202; 215) 'f(z || y) + 5': i32 -[204; 205) 'z': bool -[204; 210) 'z || y': bool -[209; 210) 'y': bool -[214; 215) '5': i32 -[225; 226) 'd': [unknown] -[229; 230) 'b': [unknown] -[240; 241) 'g': () -[244; 255) 'minus_forty': isize -[244; 260) 'minus_...y ^= i': () -[259; 260) 'i': isize -[270; 273) 'ten': usize -[283; 285) '10': usize -[295; 308) 'ten_is_eleven': bool -[311; 314) 'ten': usize -[311; 326) 'ten == some_num': bool -[318; 326) 'some_num': usize -[333; 336) 'ten': usize -[333; 340) 'ten < 3': bool -[339; 340) '3': usize +[54; 350) '{ ... < 3 }': bool +[64; 65) 'x': bool +[68; 69) 'a': bool +[68; 74) 'a && b': bool +[73; 74) 'b': bool +[84; 85) 'y': bool +[88; 92) 'true': bool +[88; 101) 'true || false': bool +[96; 101) 'false': bool +[111; 112) 'z': bool +[115; 116) 'x': bool +[115; 121) 'x == y': bool +[120; 121) 'y': bool +[131; 142) 'minus_forty': isize +[152; 160) '-40isize': isize +[153; 160) '40isize': isize +[170; 171) 'h': bool +[174; 185) 'minus_forty': isize +[174; 196) 'minus_...ONST_2': bool +[189; 196) 'CONST_2': isize +[206; 207) 'c': i32 +[210; 211) 'f': fn(bool) -> i32 +[210; 219) 'f(z || y)': i32 +[210; 223) 'f(z || y) + 5': i32 +[212; 213) 'z': bool +[212; 218) 'z || y': bool +[217; 218) 'y': bool +[222; 223) '5': i32 +[233; 234) 'd': [unknown] +[237; 238) 'b': [unknown] +[248; 249) 'g': () +[252; 263) 'minus_forty': isize +[252; 268) 'minus_...y ^= i': () +[267; 268) 'i': isize +[278; 281) 'ten': usize +[291; 293) '10': usize +[303; 316) 'ten_is_eleven': bool +[319; 322) 'ten': usize +[319; 334) 'ten == some_num': bool +[326; 334) 'some_num': usize +[341; 344) 'ten': usize +[341; 348) 'ten < 3': bool +[347; 348) '3': usize diff --git a/crates/ra_hir/src/ty/tests/data/literals.txt b/crates/ra_hir/src/ty/tests/data/literals.txt index 8d6079c98..6e82f458f 100644 --- a/crates/ra_hir/src/ty/tests/data/literals.txt +++ b/crates/ra_hir/src/ty/tests/data/literals.txt @@ -1,4 +1,4 @@ -[11; 101) '{ ...lse; }': () +[11; 111) '{ ...rue; }': () [17; 21) '5i32': i32 [27; 34) '"hello"': &str [40; 48) 'b"bytes"': &[u8] @@ -7,3 +7,4 @@ [73; 77) '3.14': f64 [83; 87) '5000': i32 [93; 98) 'false': bool +[104; 108) 'true': bool diff --git a/crates/ra_hir/src/ty/tests/data/tuple.txt b/crates/ra_hir/src/ty/tests/data/tuple.txt index 96169180d..a95d3c286 100644 --- a/crates/ra_hir/src/ty/tests/data/tuple.txt +++ b/crates/ra_hir/src/ty/tests/data/tuple.txt @@ -1,6 +1,6 @@ [9; 10) 'x': &str [18; 19) 'y': isize -[28; 214) '{ ...d"); }': () +[28; 170) '{ ...d"); }': () [38; 39) 'a': (u32, &str) [55; 63) '(1, "a")': (u32, &str) [56; 57) '1': u32 @@ -17,11 +17,11 @@ [117; 123) '(c, x)': ((isize, &str), &str) [118; 119) 'c': (isize, &str) [121; 122) 'x': &str -[177; 178) 'e': ([unknown], [unknown]) -[181; 189) '(1, "e")': ([unknown], [unknown]) -[182; 183) '1': [unknown] -[185; 188) '"e"': [unknown] -[199; 200) 'f': (([unknown], [unknown]), [unknown]) -[203; 211) '(e, "d")': (([unknown], [unknown]), [unknown]) -[204; 205) 'e': ([unknown], [unknown]) -[207; 210) '"d"': [unknown] +[133; 134) 'e': (i32, &str) +[137; 145) '(1, "e")': (i32, &str) +[138; 139) '1': i32 +[141; 144) '"e"': &str +[155; 156) 'f': ((i32, &str), &str) +[159; 167) '(e, "d")': ((i32, &str), &str) +[160; 161) 'e': (i32, &str) +[163; 166) '"d"': &str 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