From 1773c6d154abe5da00b31bb16139addcaa443bbb Mon Sep 17 00:00:00 2001 From: Igor Aleksanov Date: Sat, 3 Oct 2020 14:35:26 +0300 Subject: Extract helper functions into a separate module --- crates/hir_ty/src/diagnostics/decl_check.rs | 49 +++++------- .../src/diagnostics/decl_check/str_helpers.rs | 92 ++++++++++++++++++++++ 2 files changed, 112 insertions(+), 29 deletions(-) create mode 100644 crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs diff --git a/crates/hir_ty/src/diagnostics/decl_check.rs b/crates/hir_ty/src/diagnostics/decl_check.rs index 083df3772..1a0906492 100644 --- a/crates/hir_ty/src/diagnostics/decl_check.rs +++ b/crates/hir_ty/src/diagnostics/decl_check.rs @@ -9,6 +9,8 @@ // If you see these lines in the pull request, feel free to call me stupid :P. #![allow(dead_code, unused_imports, unused_variables)] +mod str_helpers; + use std::sync::Arc; use hir_def::{ @@ -18,7 +20,7 @@ use hir_def::{ item_tree::ItemTreeNode, resolver::{resolver_for_expr, ResolveValueResult, ValueNs}, src::HasSource, - AdtId, FunctionId, Lookup, ModuleDefId, + AdtId, EnumId, FunctionId, Lookup, ModuleDefId, StructId, }; use hir_expand::{diagnostics::DiagnosticSink, name::Name}; use syntax::{ @@ -28,7 +30,7 @@ use syntax::{ use crate::{ db::HirDatabase, - diagnostics::{CaseType, IncorrectCase}, + diagnostics::{decl_check::str_helpers::*, CaseType, IncorrectCase}, lower::CallableDefId, ApplicationTy, InferenceResult, Ty, TypeCtor, }; @@ -191,41 +193,30 @@ impl<'a, 'b> DeclValidator<'a, 'b> { } } - fn validate_adt(&mut self, db: &dyn HirDatabase, adt: AdtId) {} -} - -fn pat_equals_to_name(pat: Option, name: &Name) -> bool { - if let Some(ast::Pat::IdentPat(ident)) = pat { - ident.to_string() == name.to_string() - } else { - false + fn validate_adt(&mut self, db: &dyn HirDatabase, adt: AdtId) { + match adt { + AdtId::StructId(struct_id) => self.validate_struct(db, struct_id), + AdtId::EnumId(enum_id) => self.validate_enum(db, enum_id), + AdtId::UnionId(_) => { + // Unions aren't yet supported by this validator. + } + } } -} -fn to_lower_snake_case(ident: &str) -> Option { - // First, assume that it's UPPER_SNAKE_CASE. - if let Some(normalized) = to_lower_snake_case_from_upper_snake_case(ident) { - return Some(normalized); + fn validate_struct(&mut self, db: &dyn HirDatabase, struct_id: StructId) { + let data = db.struct_data(struct_id); } - // Otherwise, assume that it's CamelCase. - let lower_snake_case = stdx::to_lower_snake_case(ident); - - if lower_snake_case == ident { - None - } else { - Some(lower_snake_case) + fn validate_enum(&mut self, db: &dyn HirDatabase, enum_id: EnumId) { + let data = db.enum_data(enum_id); } } -fn to_lower_snake_case_from_upper_snake_case(ident: &str) -> Option { - let is_upper_snake_case = ident.chars().all(|c| c.is_ascii_uppercase() || c == '_'); - - if is_upper_snake_case { - let string = ident.chars().map(|c| c.to_ascii_lowercase()).collect(); - Some(string) +fn pat_equals_to_name(pat: Option, name: &Name) -> bool { + if let Some(ast::Pat::IdentPat(ident)) = pat { + ident.to_string() == name.to_string() } else { - None + false } } diff --git a/crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs b/crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs new file mode 100644 index 000000000..3d8f1b5f2 --- /dev/null +++ b/crates/hir_ty/src/diagnostics/decl_check/str_helpers.rs @@ -0,0 +1,92 @@ +pub fn to_camel_case(ident: &str) -> Option { + let mut output = String::new(); + + if is_camel_case(ident) { + return None; + } + + let mut capital_added = false; + for chr in ident.chars() { + if chr.is_alphabetic() { + if !capital_added { + output.push(chr.to_ascii_uppercase()); + capital_added = true; + } else { + output.push(chr.to_ascii_lowercase()); + } + } else if chr == '_' { + // Skip this character and make the next one capital. + capital_added = false; + } else { + // Put the characted as-is. + output.push(chr); + } + } + + if output == ident { + None + } else { + Some(output) + } +} + +pub fn to_lower_snake_case(ident: &str) -> Option { + // First, assume that it's UPPER_SNAKE_CASE. + if let Some(normalized) = to_lower_snake_case_from_upper_snake_case(ident) { + return Some(normalized); + } + + // Otherwise, assume that it's CamelCase. + let lower_snake_case = stdx::to_lower_snake_case(ident); + + if lower_snake_case == ident { + None + } else { + Some(lower_snake_case) + } +} + +fn to_lower_snake_case_from_upper_snake_case(ident: &str) -> Option { + if is_upper_snake_case(ident) { + let string = ident.chars().map(|c| c.to_ascii_lowercase()).collect(); + Some(string) + } else { + None + } +} + +fn is_upper_snake_case(ident: &str) -> bool { + ident.chars().all(|c| c.is_ascii_uppercase() || c == '_') +} + +fn is_camel_case(ident: &str) -> bool { + // We assume that the string is either snake case or camel case. + ident.chars().all(|c| c != '_') +} + +#[cfg(test)] +mod tests { + use super::*; + use expect_test::{expect, Expect}; + + fn check Option>(fun: F, input: &str, expect: Expect) { + // `None` is translated to empty string, meaning that there is nothing to fix. + let output = fun(input).unwrap_or_default(); + + expect.assert_eq(&output); + } + + #[test] + fn test_to_lower_snake_case() { + check(to_lower_snake_case, "lower_snake_case", expect![[""]]); + check(to_lower_snake_case, "UPPER_SNAKE_CASE", expect![["upper_snake_case"]]); + check(to_lower_snake_case, "CamelCase", expect![["camel_case"]]); + } + + #[test] + fn test_to_camel_case() { + check(to_camel_case, "CamelCase", expect![[""]]); + check(to_camel_case, "lower_snake_case", expect![["LowerSnakeCase"]]); + check(to_camel_case, "UPPER_SNAKE_CASE", expect![["UpperSnakeCase"]]); + } +} -- cgit v1.2.3