Use local error macros in references/rename

This commit is contained in:
Lukas Wirth 2021-01-10 21:59:44 +01:00
parent 919a1d7b27
commit 2347944aae

View file

@ -36,6 +36,15 @@ impl fmt::Display for RenameError {
impl Error for RenameError {} impl Error for RenameError {}
macro_rules! format_err {
($fmt:expr) => {RenameError(format!($fmt))};
($fmt:expr, $($arg:tt)+) => {RenameError(format!($fmt, $($arg)+))}
}
macro_rules! bail {
($($tokens:tt)*) => {return Err(format_err!($($tokens)*))}
}
pub(crate) fn prepare_rename( pub(crate) fn prepare_rename(
db: &RootDatabase, db: &RootDatabase,
position: FilePosition, position: FilePosition,
@ -119,16 +128,13 @@ fn check_identifier(new_name: &str) -> RenameResult<IdentifierKind> {
Ok(IdentifierKind::Lifetime) Ok(IdentifierKind::Lifetime)
} }
(SyntaxKind::LIFETIME_IDENT, _) => { (SyntaxKind::LIFETIME_IDENT, _) => {
Err(format!("Invalid name `{0}`: Cannot rename lifetime to {0}", new_name)) bail!("Invalid name `{0}`: Cannot rename lifetime to {0}", new_name)
} }
(_, Some(syntax_error)) => { (_, Some(syntax_error)) => bail!("Invalid name `{}`: {}", new_name, syntax_error),
Err(format!("Invalid name `{}`: {}", new_name, syntax_error)) (_, None) => bail!("Invalid name `{}`: not an identifier", new_name),
}
(_, None) => Err(format!("Invalid name `{}`: not an identifier", new_name)),
}, },
None => Err(format!("Invalid name `{}`: not an identifier", new_name)), None => bail!("Invalid name `{}`: not an identifier", new_name),
} }
.map_err(RenameError)
} }
fn find_module_at_offset( fn find_module_at_offset(
@ -164,7 +170,7 @@ fn find_all_refs(
position: FilePosition, position: FilePosition,
) -> RenameResult<RangeInfo<ReferenceSearchResult>> { ) -> RenameResult<RangeInfo<ReferenceSearchResult>> {
crate::references::find_all_refs(sema, position, None) crate::references::find_all_refs(sema, position, None)
.ok_or_else(|| RenameError("No references found at position".to_string())) .ok_or_else(|| format_err!("No references found at position"))
} }
fn source_edit_from_reference( fn source_edit_from_reference(
@ -237,10 +243,7 @@ fn rename_mod(
new_name: &str, new_name: &str,
) -> RenameResult<RangeInfo<SourceChange>> { ) -> RenameResult<RangeInfo<SourceChange>> {
if IdentifierKind::Ident != check_identifier(new_name)? { if IdentifierKind::Ident != check_identifier(new_name)? {
return Err(RenameError(format!( bail!("Invalid name `{0}`: cannot rename module to {0}", new_name);
"Invalid name `{0}`: cannot rename module to {0}",
new_name
)));
} }
let mut source_file_edits = Vec::new(); let mut source_file_edits = Vec::new();
let mut file_system_edits = Vec::new(); let mut file_system_edits = Vec::new();
@ -291,27 +294,26 @@ fn rename_to_self(
let (fn_def, fn_ast) = find_node_at_offset::<ast::Fn>(syn, position.offset) let (fn_def, fn_ast) = find_node_at_offset::<ast::Fn>(syn, position.offset)
.and_then(|fn_ast| sema.to_def(&fn_ast).zip(Some(fn_ast))) .and_then(|fn_ast| sema.to_def(&fn_ast).zip(Some(fn_ast)))
.ok_or_else(|| RenameError("No surrounding method declaration found".to_string()))?; .ok_or_else(|| format_err!("No surrounding method declaration found"))?;
let param_range = fn_ast let param_range = fn_ast
.param_list() .param_list()
.and_then(|p| p.params().next()) .and_then(|p| p.params().next())
.ok_or_else(|| RenameError("Method has no parameters".to_string()))? .ok_or_else(|| format_err!("Method has no parameters"))?
.syntax() .syntax()
.text_range(); .text_range();
if !param_range.contains(position.offset) { if !param_range.contains(position.offset) {
return Err(RenameError("Only the first parameter can be self".to_string())); bail!("Only the first parameter can be self");
} }
let impl_block = find_node_at_offset::<ast::Impl>(syn, position.offset) let impl_block = find_node_at_offset::<ast::Impl>(syn, position.offset)
.and_then(|def| sema.to_def(&def)) .and_then(|def| sema.to_def(&def))
.ok_or_else(|| RenameError("No impl block found for function".to_string()))?; .ok_or_else(|| format_err!("No impl block found for function"))?;
if fn_def.self_param(sema.db).is_some() { if fn_def.self_param(sema.db).is_some() {
return Err(RenameError("Method already has a self parameter".to_string())); bail!("Method already has a self parameter");
} }
let params = fn_def.assoc_fn_params(sema.db); let params = fn_def.assoc_fn_params(sema.db);
let first_param = let first_param = params.first().ok_or_else(|| format_err!("Method has no parameters"))?;
params.first().ok_or_else(|| RenameError("Method has no parameters".into()))?;
let first_param_ty = first_param.ty(); let first_param_ty = first_param.ty();
let impl_ty = impl_block.target_ty(sema.db); let impl_ty = impl_block.target_ty(sema.db);
let (ty, self_param) = if impl_ty.remove_ref().is_some() { let (ty, self_param) = if impl_ty.remove_ref().is_some() {
@ -324,7 +326,7 @@ fn rename_to_self(
}; };
if ty != impl_ty { if ty != impl_ty {
return Err(RenameError("Parameter type differs from impl block type".to_string())); bail!("Parameter type differs from impl block type");
} }
let RangeInfo { range, info: refs } = find_all_refs(sema, position)?; let RangeInfo { range, info: refs } = find_all_refs(sema, position)?;
@ -334,7 +336,7 @@ fn rename_to_self(
.partition(|reference| param_range.intersect(reference.file_range.range).is_some()); .partition(|reference| param_range.intersect(reference.file_range.range).is_some());
if param_ref.is_empty() { if param_ref.is_empty() {
return Err(RenameError("Parameter to rename not found".to_string())); bail!("Parameter to rename not found");
} }
let mut edits = usages let mut edits = usages
@ -385,9 +387,7 @@ fn rename_self_to_param(
) -> Result<RangeInfo<SourceChange>, RenameError> { ) -> Result<RangeInfo<SourceChange>, RenameError> {
let ident_kind = check_identifier(new_name)?; let ident_kind = check_identifier(new_name)?;
match ident_kind { match ident_kind {
IdentifierKind::Lifetime => { IdentifierKind::Lifetime => bail!("Invalid name `{}`: not an identifier", new_name),
return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name)))
}
IdentifierKind::ToSelf => { IdentifierKind::ToSelf => {
// no-op // no-op
return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default())); return Ok(RangeInfo::new(self_token.text_range(), SourceChange::default()));
@ -399,7 +399,7 @@ fn rename_self_to_param(
let text = sema.db.file_text(position.file_id); let text = sema.db.file_text(position.file_id);
let fn_def = find_node_at_offset::<ast::Fn>(syn, position.offset) let fn_def = find_node_at_offset::<ast::Fn>(syn, position.offset)
.ok_or_else(|| RenameError("No surrounding method declaration found".to_string()))?; .ok_or_else(|| format_err!("No surrounding method declaration found"))?;
let search_range = fn_def.syntax().text_range(); let search_range = fn_def.syntax().text_range();
let mut edits: Vec<SourceFileEdit> = vec![]; let mut edits: Vec<SourceFileEdit> = vec![];
@ -414,7 +414,7 @@ fn rename_self_to_param(
{ {
let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) { let edit = if let Some(ref self_param) = ast::SelfParam::cast(usage.parent()) {
text_edit_from_self_param(syn, self_param, new_name) text_edit_from_self_param(syn, self_param, new_name)
.ok_or_else(|| RenameError("No target type found".to_string()))? .ok_or_else(|| format_err!("No target type found"))?
} else { } else {
TextEdit::replace(usage.text_range(), String::from(new_name)) TextEdit::replace(usage.text_range(), String::from(new_name))
}; };
@ -423,9 +423,7 @@ fn rename_self_to_param(
} }
if edits.len() > 1 && ident_kind == IdentifierKind::Underscore { if edits.len() > 1 && ident_kind == IdentifierKind::Underscore {
return Err(RenameError(format!( bail!("Cannot rename reference to `_` as it is being referenced multiple times");
"Cannot rename reference to `_` as it is being referenced multiple times",
)));
} }
let range = ast::SelfParam::cast(self_token.parent()) let range = ast::SelfParam::cast(self_token.parent())
@ -446,15 +444,10 @@ fn rename_reference(
(IdentifierKind::ToSelf, ReferenceKind::Lifetime) (IdentifierKind::ToSelf, ReferenceKind::Lifetime)
| (IdentifierKind::Underscore, ReferenceKind::Lifetime) | (IdentifierKind::Underscore, ReferenceKind::Lifetime)
| (IdentifierKind::Ident, ReferenceKind::Lifetime) => { | (IdentifierKind::Ident, ReferenceKind::Lifetime) => {
return Err(RenameError(format!( bail!("Invalid name `{}`: not a lifetime identifier", new_name)
"Invalid name `{}`: not a lifetime identifier",
new_name
)))
} }
(IdentifierKind::Lifetime, ReferenceKind::Lifetime) => (), (IdentifierKind::Lifetime, ReferenceKind::Lifetime) => (),
(IdentifierKind::Lifetime, _) => { (IdentifierKind::Lifetime, _) => bail!("Invalid name `{}`: not an identifier", new_name),
return Err(RenameError(format!("Invalid name `{}`: not an identifier", new_name)))
}
(IdentifierKind::ToSelf, ReferenceKind::SelfKw) => { (IdentifierKind::ToSelf, ReferenceKind::SelfKw) => {
//no-op //no-op
return Ok(RangeInfo::new(range, SourceChange::default())); return Ok(RangeInfo::new(range, SourceChange::default()));
@ -463,9 +456,7 @@ fn rename_reference(
return rename_to_self(sema, position); return rename_to_self(sema, position);
} }
(IdentifierKind::Underscore, _) if !refs.references.is_empty() => { (IdentifierKind::Underscore, _) if !refs.references.is_empty() => {
return Err(RenameError(format!( bail!("Cannot rename reference to `_` as it is being referenced multiple times")
"Cannot rename reference to `_` as it is being referenced multiple times",
)))
} }
(IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => (), (IdentifierKind::Ident, _) | (IdentifierKind::Underscore, _) => (),
} }