Simplify CB names (#7534)

1. When opening CB with source node, the type name is skipped and only method names are displayed. Fixes #7471
2. When entered Main module of some library, the module names are no longer displayed with their full qualified name.

![image](https://github.com/enso-org/enso/assets/3919101/2d1fe4ad-6391-41d6-89a1-410492457b57)

# Important Notes
Refactoring: I changed the internal representation of `ImString` to `Rc<str>` instead of `Rc<String>` to reduce the number of allocations and memory jumps. I even tried to remove `ImString` altogether, but it was not easy, and the main problem was lacking Default implementation.
This commit is contained in:
Adam Obuchowicz 2023-08-14 09:22:50 +02:00 committed by GitHub
parent fd972f8b0a
commit 334ed64b99
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 66 additions and 40 deletions

View File

@ -131,16 +131,8 @@ impl Component {
id: entry::Id,
entry: Rc<Entry>,
group_id: Option<usize>,
label: ImString,
) -> Self {
let label = match entry.kind {
entry::Kind::Module
if entry.defined_in.is_main_module() || entry.defined_in.is_top_element() =>
format!("{}", entry.defined_in).into(),
_ => match entry.self_type.as_ref() {
Some(self_type) => format!("{}.{}", self_type.alias_name(), entry.name).into(),
None => entry.name.to_im_string(),
},
};
let aliases =
entry.aliases().map(|alias| format!("{alias} ({label})").into()).collect_vec().into();
let data = Suggestion::FromDatabase { id, entry };

View File

@ -286,7 +286,16 @@ impl<'a> Builder<'a> {
None => WhenDisplayed::in_base_mode(&entry, group_id.is_some()),
};
let when_displayed = when_displayed.consider_tags(&entry);
let component = Component::new_from_database_entry(id, entry, group_id);
let label = match entry.kind {
suggestion_database::entry::Kind::Module if self.inside_module.is_none() =>
format!("{}", entry.defined_in).into(),
_ => match entry.self_type.as_ref() {
Some(self_type) if self.this_type.is_none() =>
format!("{}.{}", self_type.alias_name(), entry.name).into(),
_ => entry.name.to_im_string(),
},
};
let component = Component::new_from_database_entry(id, entry, group_id, label);
if matches!(when_displayed, WhenDisplayed::Always) {
self.built_list.displayed_by_default.push(component.clone());
}
@ -482,6 +491,35 @@ mod tests {
]);
}
#[test]
fn building_main_module_content_list() {
let database = mock_database();
let groups = mock_groups();
let (module_id, _) = database
.lookup_by_qualified_name(&QualifiedName::from_text("test.Test").unwrap())
.unwrap();
let mut builder = Builder::new_inside_module(&database, &groups, module_id);
builder.add_components_from_db(database.keys());
let list = builder.build();
check_displayed_components(&list, vec!["TopModule1", "TopModule2"]);
check_groups(&list, vec![None, None]);
check_filterable_components(&list, vec![
"TopModule1",
"TopModule1.fun1",
"TopModule1.fun2",
"SubModule1",
"SubModule1.fun4",
"SubModule2",
"SubModule2.fun5",
"SubModule3",
"SubModule3.fun6",
"TopModule2",
"TopModule2.fun0",
]);
}
#[test]

View File

@ -163,7 +163,7 @@ impl Path {
if let [ref _src, ref dirs @ .., _] = *self.file_path.segments.as_slice() {
// Path must designate a valid module and must be able to designate any valid module.
// Therefore, unwraps in this method are safe.
let parent_modules = dirs.iter().map(ImString::new).collect();
let parent_modules = dirs.iter().map(ImString::from).collect();
let name = ImString::new(self.module_name());
Id { parent_modules, name }
} else {

View File

@ -160,17 +160,16 @@ impl AsRef<str> for CowString {
// ================
/// Immutable string implementation with a fast clone implementation.
#[derive(Clone, CloneRef, Default, Eq, Hash, PartialEq, Ord, PartialOrd)]
#[derive(Clone, CloneRef, Eq, Hash, PartialEq, Ord, PartialOrd)]
#[derive(Deserialize, Serialize)]
pub struct ImString {
content: Rc<String>,
content: Rc<str>,
}
impl ImString {
/// Constructor.
pub fn new(content: impl Into<String>) -> Self {
let content = Rc::new(content.into());
Self { content }
pub fn new(content: impl Into<Rc<str>>) -> Self {
Self { content: content.into() }
}
/// Extract a string slice containing the entire string.
@ -179,6 +178,12 @@ impl ImString {
}
}
impl Default for ImString {
fn default() -> Self {
"".into()
}
}
impl std::fmt::Display for ImString {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.content, f)
@ -204,12 +209,6 @@ impl AsRef<ImString> for ImString {
}
}
impl AsRef<String> for ImString {
fn as_ref(&self) -> &String {
self.content.as_ref()
}
}
impl AsRef<str> for ImString {
fn as_ref(&self) -> &str {
self.content.as_ref()
@ -222,9 +221,9 @@ impl Borrow<str> for ImString {
}
}
impl Borrow<String> for ImString {
fn borrow(&self) -> &String {
&self.content
impl From<Rc<str>> for ImString {
fn from(content: Rc<str>) -> Self {
Self { content }
}
}
@ -236,13 +235,13 @@ impl From<String> for ImString {
impl From<&String> for ImString {
fn from(t: &String) -> Self {
Self::new(t)
Self::new(t.as_str())
}
}
impl From<&&String> for ImString {
fn from(t: &&String) -> Self {
Self::new(*t)
Self::new(t.as_str())
}
}
@ -264,18 +263,21 @@ impl From<Cow<'_, str>> for ImString {
}
}
impl From<ImString> for Rc<str> {
fn from(t: ImString) -> Self {
t.content
}
}
impl From<ImString> for String {
fn from(value: ImString) -> Self {
match Rc::try_unwrap(value.content) {
Ok(str) => str,
Err(rc) => rc.deref().clone(),
}
value.as_str().into()
}
}
impl PartialEq<&str> for ImString {
fn eq(&self, other: &&str) -> bool {
self.content.as_ref().eq(other)
self.content.as_ref().eq(*other)
}
}
@ -287,7 +289,7 @@ impl PartialEq<str> for ImString {
impl PartialEq<ImString> for &str {
fn eq(&self, other: &ImString) -> bool {
self.eq(other.content.as_ref())
self.eq(&other.content.as_ref())
}
}
@ -410,12 +412,6 @@ macro_rules! im_string_newtype_without_serde {
}
}
impl AsRef<String> for $name {
fn as_ref(&self) -> &String {
self.content.as_ref()
}
}
impl AsRef<str> for $name {
fn as_ref(&self) -> &str {
self.content.as_ref()

View File

@ -942,7 +942,7 @@ impl From<Rope> for String {
impl From<Rope> for ImString {
fn from(t: Rope) -> Self {
ImString::new(t)
ImString::new(t.to_im_string())
}
}