aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/name.rs
diff options
context:
space:
mode:
authoruHOOCCOOHu <[email protected]>2019-09-26 19:04:47 +0100
committeruHOOCCOOHu <[email protected]>2019-09-26 19:04:47 +0100
commit128dc5355b81b0217fede903ae79f75ba0124716 (patch)
tree7ded1337bc7a77c66098d4307a2d381cb9a1f3b2 /crates/ra_hir/src/name.rs
parent53a30d9e69ee5149e4fdb1c6fe4081281e879d0e (diff)
Refactor `Name` ready for hygienic macro
Diffstat (limited to 'crates/ra_hir/src/name.rs')
-rw-r--r--crates/ra_hir/src/name.rs157
1 files changed, 79 insertions, 78 deletions
diff --git a/crates/ra_hir/src/name.rs b/crates/ra_hir/src/name.rs
index 1bf993ffb..d50867f5d 100644
--- a/crates/ra_hir/src/name.rs
+++ b/crates/ra_hir/src/name.rs
@@ -5,20 +5,21 @@ use ra_syntax::{ast, SmolStr};
5/// `Name` is a wrapper around string, which is used in hir for both references 5/// `Name` is a wrapper around string, which is used in hir for both references
6/// and declarations. In theory, names should also carry hygiene info, but we are 6/// and declarations. In theory, names should also carry hygiene info, but we are
7/// not there yet! 7/// not there yet!
8#[derive(Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] 8#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
9pub struct Name { 9pub struct Name(Repr);
10 text: SmolStr,
11}
12 10
13impl fmt::Display for Name { 11#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
14 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 12enum Repr {
15 fmt::Display::fmt(&self.text, f) 13 Text(SmolStr),
16 } 14 TupleField(usize),
17} 15}
18 16
19impl fmt::Debug for Name { 17impl fmt::Display for Name {
20 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 18 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
21 fmt::Debug::fmt(&self.text, f) 19 match &self.0 {
20 Repr::Text(text) => fmt::Display::fmt(&text, f),
21 Repr::TupleField(idx) => fmt::Display::fmt(&idx, f),
22 }
22 } 23 }
23} 24}
24 25
@@ -26,29 +27,38 @@ impl Name {
26 /// Note: this is private to make creating name from random string hard. 27 /// Note: this is private to make creating name from random string hard.
27 /// Hopefully, this should allow us to integrate hygiene cleaner in the 28 /// Hopefully, this should allow us to integrate hygiene cleaner in the
28 /// future, and to switch to interned representation of names. 29 /// future, and to switch to interned representation of names.
29 const fn new(text: SmolStr) -> Name { 30 const fn new_text(text: SmolStr) -> Name {
30 Name { text } 31 Name(Repr::Text(text))
31 } 32 }
32 33
33 pub(crate) fn missing() -> Name { 34 pub(crate) fn new_tuple_field(idx: usize) -> Name {
34 Name::new("[missing name]".into()) 35 Name(Repr::TupleField(idx))
35 } 36 }
36 37
37 pub(crate) fn tuple_field_name(idx: usize) -> Name { 38 /// Shortcut to create inline plain text name
38 Name::new(idx.to_string().into()) 39 const fn new_inline_ascii(len: usize, text: &[u8]) -> Name {
40 Name::new_text(SmolStr::new_inline_from_ascii(len, text))
39 } 41 }
40 42
41 // There's should be no way to extract a string out of `Name`: `Name` in the 43 /// Resolve a name from the text of token.
42 // future, `Name` will include hygiene information, and you can't encode 44 fn resolve(raw_text: &SmolStr) -> Name {
43 // hygiene into a String. 45 let raw_start = "r#";
44 // 46 if raw_text.as_str().starts_with(raw_start) {
45 // If you need to compare something with `Name`, compare `Name`s directly. 47 Name::new_text(SmolStr::new(&raw_text[raw_start.len()..]))
46 // 48 } else {
47 // If you need to render `Name` for the user, use the `Display` impl, but be 49 Name::new_text(raw_text.clone())
48 // aware that it strips hygiene info. 50 }
49 #[deprecated(note = "use to_string instead")] 51 }
50 pub fn as_smolstr(&self) -> &SmolStr { 52
51 &self.text 53 pub(crate) fn missing() -> Name {
54 Name::new_text("[missing name]".into())
55 }
56
57 pub(crate) fn as_tuple_index(&self) -> Option<usize> {
58 match self.0 {
59 Repr::TupleField(idx) => Some(idx),
60 _ => None,
61 }
52 } 62 }
53} 63}
54 64
@@ -58,15 +68,16 @@ pub(crate) trait AsName {
58 68
59impl AsName for ast::NameRef { 69impl AsName for ast::NameRef {
60 fn as_name(&self) -> Name { 70 fn as_name(&self) -> Name {
61 let name = resolve_name(self.text()); 71 match self.as_tuple_field() {
62 Name::new(name) 72 Some(idx) => Name::new_tuple_field(idx),
73 None => Name::resolve(self.text()),
74 }
63 } 75 }
64} 76}
65 77
66impl AsName for ast::Name { 78impl AsName for ast::Name {
67 fn as_name(&self) -> Name { 79 fn as_name(&self) -> Name {
68 let name = resolve_name(self.text()); 80 Name::resolve(self.text())
69 Name::new(name)
70 } 81 }
71} 82}
72 83
@@ -74,66 +85,56 @@ impl AsName for ast::FieldKind {
74 fn as_name(&self) -> Name { 85 fn as_name(&self) -> Name {
75 match self { 86 match self {
76 ast::FieldKind::Name(nr) => nr.as_name(), 87 ast::FieldKind::Name(nr) => nr.as_name(),
77 ast::FieldKind::Index(idx) => Name::new(idx.text().clone()), 88 ast::FieldKind::Index(idx) => Name::new_tuple_field(idx.text().parse().unwrap()),
78 } 89 }
79 } 90 }
80} 91}
81 92
82impl AsName for ra_db::Dependency { 93impl AsName for ra_db::Dependency {
83 fn as_name(&self) -> Name { 94 fn as_name(&self) -> Name {
84 Name::new(self.name.clone()) 95 Name::new_text(self.name.clone())
85 } 96 }
86} 97}
87 98
88// Primitives 99// Primitives
89pub(crate) const ISIZE: Name = Name::new(SmolStr::new_inline_from_ascii(5, b"isize")); 100pub(crate) const ISIZE: Name = Name::new_inline_ascii(5, b"isize");
90pub(crate) const I8: Name = Name::new(SmolStr::new_inline_from_ascii(2, b"i8")); 101pub(crate) const I8: Name = Name::new_inline_ascii(2, b"i8");
91pub(crate) const I16: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"i16")); 102pub(crate) const I16: Name = Name::new_inline_ascii(3, b"i16");
92pub(crate) const I32: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"i32")); 103pub(crate) const I32: Name = Name::new_inline_ascii(3, b"i32");
93pub(crate) const I64: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"i64")); 104pub(crate) const I64: Name = Name::new_inline_ascii(3, b"i64");
94pub(crate) const I128: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"i128")); 105pub(crate) const I128: Name = Name::new_inline_ascii(4, b"i128");
95pub(crate) const USIZE: Name = Name::new(SmolStr::new_inline_from_ascii(5, b"usize")); 106pub(crate) const USIZE: Name = Name::new_inline_ascii(5, b"usize");
96pub(crate) const U8: Name = Name::new(SmolStr::new_inline_from_ascii(2, b"u8")); 107pub(crate) const U8: Name = Name::new_inline_ascii(2, b"u8");
97pub(crate) const U16: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"u16")); 108pub(crate) const U16: Name = Name::new_inline_ascii(3, b"u16");
98pub(crate) const U32: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"u32")); 109pub(crate) const U32: Name = Name::new_inline_ascii(3, b"u32");
99pub(crate) const U64: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"u64")); 110pub(crate) const U64: Name = Name::new_inline_ascii(3, b"u64");
100pub(crate) const U128: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"u128")); 111pub(crate) const U128: Name = Name::new_inline_ascii(4, b"u128");
101pub(crate) const F32: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"f32")); 112pub(crate) const F32: Name = Name::new_inline_ascii(3, b"f32");
102pub(crate) const F64: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"f64")); 113pub(crate) const F64: Name = Name::new_inline_ascii(3, b"f64");
103pub(crate) const BOOL: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"bool")); 114pub(crate) const BOOL: Name = Name::new_inline_ascii(4, b"bool");
104pub(crate) const CHAR: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"char")); 115pub(crate) const CHAR: Name = Name::new_inline_ascii(4, b"char");
105pub(crate) const STR: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"str")); 116pub(crate) const STR: Name = Name::new_inline_ascii(3, b"str");
106 117
107// Special names 118// Special names
108pub(crate) const SELF_PARAM: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"self")); 119pub(crate) const SELF_PARAM: Name = Name::new_inline_ascii(4, b"self");
109pub(crate) const SELF_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"Self")); 120pub(crate) const SELF_TYPE: Name = Name::new_inline_ascii(4, b"Self");
110pub(crate) const MACRO_RULES: Name = Name::new(SmolStr::new_inline_from_ascii(11, b"macro_rules")); 121pub(crate) const MACRO_RULES: Name = Name::new_inline_ascii(11, b"macro_rules");
111 122
112// Components of known path (value or mod name) 123// Components of known path (value or mod name)
113pub(crate) const STD: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"std")); 124pub(crate) const STD: Name = Name::new_inline_ascii(3, b"std");
114pub(crate) const ITER: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"iter")); 125pub(crate) const ITER: Name = Name::new_inline_ascii(4, b"iter");
115pub(crate) const OPS: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"ops")); 126pub(crate) const OPS: Name = Name::new_inline_ascii(3, b"ops");
116pub(crate) const FUTURE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"future")); 127pub(crate) const FUTURE: Name = Name::new_inline_ascii(6, b"future");
117pub(crate) const RESULT: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"result")); 128pub(crate) const RESULT: Name = Name::new_inline_ascii(6, b"result");
118pub(crate) const BOXED: Name = Name::new(SmolStr::new_inline_from_ascii(5, b"boxed")); 129pub(crate) const BOXED: Name = Name::new_inline_ascii(5, b"boxed");
119 130
120// Components of known path (type name) 131// Components of known path (type name)
121pub(crate) const INTO_ITERATOR_TYPE: Name = 132pub(crate) const INTO_ITERATOR_TYPE: Name = Name::new_inline_ascii(12, b"IntoIterator");
122 Name::new(SmolStr::new_inline_from_ascii(12, b"IntoIterator")); 133pub(crate) const ITEM_TYPE: Name = Name::new_inline_ascii(4, b"Item");
123pub(crate) const ITEM_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(4, b"Item")); 134pub(crate) const TRY_TYPE: Name = Name::new_inline_ascii(3, b"Try");
124pub(crate) const TRY_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Try")); 135pub(crate) const OK_TYPE: Name = Name::new_inline_ascii(2, b"Ok");
125pub(crate) const OK_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(2, b"Ok")); 136pub(crate) const FUTURE_TYPE: Name = Name::new_inline_ascii(6, b"Future");
126pub(crate) const FUTURE_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Future")); 137pub(crate) const RESULT_TYPE: Name = Name::new_inline_ascii(6, b"Result");
127pub(crate) const RESULT_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Result")); 138pub(crate) const OUTPUT_TYPE: Name = Name::new_inline_ascii(6, b"Output");
128pub(crate) const OUTPUT_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Output")); 139pub(crate) const TARGET_TYPE: Name = Name::new_inline_ascii(6, b"Target");
129pub(crate) const TARGET_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(6, b"Target")); 140pub(crate) const BOX_TYPE: Name = Name::new_inline_ascii(3, b"Box");
130pub(crate) const BOX_TYPE: Name = Name::new(SmolStr::new_inline_from_ascii(3, b"Box"));
131
132fn resolve_name(text: &SmolStr) -> SmolStr {
133 let raw_start = "r#";
134 if text.as_str().starts_with(raw_start) {
135 SmolStr::new(&text[raw_start.len()..])
136 } else {
137 text.clone()
138 }
139}