From 6a4c9fc9fd6cb9ecf08bd5a22890eb19d22ad34e Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Mon, 17 Aug 2020 16:11:29 +0200 Subject: [PATCH] Don't make fields private unless you have to --- crates/assists/src/lib.rs | 37 ++++++++-------------------- crates/rust-analyzer/src/handlers.rs | 4 +-- crates/rust-analyzer/src/to_proto.rs | 8 +++--- docs/dev/style.md | 29 ++++++++++++++++++++++ 4 files changed, 45 insertions(+), 33 deletions(-) diff --git a/crates/assists/src/lib.rs b/crates/assists/src/lib.rs index ae90d68a35..c589b08dc4 100644 --- a/crates/assists/src/lib.rs +++ b/crates/assists/src/lib.rs @@ -66,13 +66,13 @@ pub struct GroupLabel(pub String); #[derive(Debug, Clone)] pub struct Assist { - id: AssistId, + pub id: AssistId, /// Short description of the assist, as shown in the UI. label: String, - group: Option, + pub group: Option, /// Target ranges are used to sort assists: the smaller the target range, /// the more specific assist is, and so it should be sorted first. - target: TextRange, + pub target: TextRange, } #[derive(Debug, Clone)] @@ -82,6 +82,11 @@ pub struct ResolvedAssist { } impl Assist { + fn new(id: AssistId, label: String, group: Option, target: TextRange) -> Assist { + assert!(label.starts_with(char::is_uppercase)); + Assist { id, label, group, target } + } + /// Return all the assists applicable at the given position. /// /// Assists are returned in the "unresolved" state, that is only labels are @@ -114,30 +119,8 @@ impl Assist { acc.finish_resolved() } - pub(crate) fn new( - id: AssistId, - label: String, - group: Option, - target: TextRange, - ) -> Assist { - assert!(label.starts_with(|c: char| c.is_uppercase())); - Assist { id, label, group, target } - } - - pub fn id(&self) -> AssistId { - self.id - } - - pub fn label(&self) -> String { - self.label.clone() - } - - pub fn group(&self) -> Option { - self.group.clone() - } - - pub fn target(&self) -> TextRange { - self.target + pub fn label(&self) -> &str { + self.label.as_str() } } diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 74f73655a4..e05ffc768e 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -859,10 +859,10 @@ pub(crate) fn handle_resolve_code_action( .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?; - let (id_string, index) = split_once(¶ms.id, ':').unwrap(); + let (id, index) = split_once(¶ms.id, ':').unwrap(); let index = index.parse::().unwrap(); let assist = &assists[index]; - assert!(assist.assist.id().0 == id_string); + assert!(assist.assist.id.0 == id); Ok(to_proto::resolved_code_action(&snap, assist.clone())?.edit) } diff --git a/crates/rust-analyzer/src/to_proto.rs b/crates/rust-analyzer/src/to_proto.rs index 8a2cfa2aee..535de2f71a 100644 --- a/crates/rust-analyzer/src/to_proto.rs +++ b/crates/rust-analyzer/src/to_proto.rs @@ -704,10 +704,10 @@ pub(crate) fn unresolved_code_action( index: usize, ) -> Result { let res = lsp_ext::CodeAction { - title: assist.label(), - id: Some(format!("{}:{}", assist.id().0.to_owned(), index.to_string())), - group: assist.group().filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), - kind: Some(code_action_kind(assist.id().1)), + title: assist.label().to_string(), + id: Some(format!("{}:{}", assist.id.0, index.to_string())), + group: assist.group.filter(|_| snap.config.client_caps.code_action_group).map(|gr| gr.0), + kind: Some(code_action_kind(assist.id.1)), edit: None, is_preferred: None, }; diff --git a/docs/dev/style.md b/docs/dev/style.md index 963a6d73d0..8effddcda5 100644 --- a/docs/dev/style.md +++ b/docs/dev/style.md @@ -176,6 +176,35 @@ fn frobnicate(walrus: Option) { } ``` +# Getters & Setters + +If a field can have any value without breaking invariants, make the field public. +Conversely, if there is an invariant, document it, enforce it in the "constructor" function, make the field private, and provide a getter. +Never provide setters. + +Getters should return borrowed data: + +``` +struct Person { + // Invariant: never empty + first_name: String, + middle_name: Option +} + +// Good +impl Person { + fn first_name(&self) -> &str { self.first_name.as_str() } + fn middle_name(&self) -> Option<&str> { self.middle_name.as_ref() } +} + +// Not as good +impl Person { + fn first_name(&self) -> String { self.first_name.clone() } + fn middle_name(&self) -> &Option { &self.middle_name } +} +``` + + # Premature Pessimization Avoid writing code which is slower than it needs to be.