Skip to content

Commit

Permalink
Simple rename impl (#305)
Browse files Browse the repository at this point in the history
  • Loading branch information
piotmag769 authored Feb 20, 2025
1 parent 8a0aaac commit c4e52a5
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 5 deletions.
65 changes: 61 additions & 4 deletions src/ide/navigation/rename.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,64 @@
use lsp_types::{RenameParams, WorkspaceEdit};
use std::collections::HashMap;

use crate::lang::db::AnalysisDatabase;
use anyhow::anyhow;
use itertools::Itertools;
use lsp_server::ErrorCode;
use lsp_types::{Location, RenameParams, TextEdit, WorkspaceEdit};

pub fn rename(_params: RenameParams, _db: &AnalysisDatabase) -> Option<WorkspaceEdit> {
None
use crate::lang::db::{AnalysisDatabase, LsSyntaxGroup};
use crate::lang::defs::SymbolDef;
use crate::lang::lsp::{LsProtoGroup, ToCairo};
use crate::lsp::result::{LSPError, LSPResult};

pub fn rename(params: RenameParams, db: &AnalysisDatabase) -> LSPResult<Option<WorkspaceEdit>> {
let new_name = params.new_name;

// Copied from https://github.com/starkware-libs/cairo/blob/cefadd5ea60d9f0790d71ae14c97d48aa93bd5bf/crates/cairo-lang-parser/src/lexer.rs#L197.
let is_valid_ident = new_name.chars().all(|c| c.is_ascii_alphanumeric() || c == '_');

if !is_valid_ident {
return Err(LSPError::new(
anyhow!("`{new_name}` is not a valid identifier"),
ErrorCode::RequestFailed,
));
}

let symbol = || {
let file = db.file_for_url(&params.text_document_position.text_document.uri)?;
let position = params.text_document_position.position.to_cairo();
let identifier = db.find_identifier_at_position(file, position)?;

SymbolDef::find(db, &identifier)
};
let Some(symbol) = symbol() else {
return Ok(None);
};

// TODO: handle non-inline modules and crates separately (files need to be renamed too).
if matches!(symbol, SymbolDef::Module(_)) {
return Err(LSPError::new(
anyhow!("Rename for crate/modules is not yet supported"),
ErrorCode::RequestFailed,
));
}

let locations: Vec<_> = symbol
.usages(db)
.include_declaration(true)
.locations()
.unique()
.filter_map(|loc| db.lsp_location(loc))
.collect();

let changes: HashMap<_, Vec<TextEdit>> =
locations.into_iter().fold(HashMap::new(), |mut acc, Location { uri, range }| {
acc.entry(uri).or_default().push(TextEdit { range, new_text: new_name.clone() });
acc
});

Ok(Some(WorkspaceEdit {
changes: Some(changes),
document_changes: None,
change_annotations: None,
}))
}
2 changes: 1 addition & 1 deletion src/server/routing/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,7 +389,7 @@ impl BackgroundDocumentRequestHandler for Rename {
_notifier: Notifier,
params: RenameParams,
) -> LSPResult<Option<WorkspaceEdit>> {
Ok(ide::navigation::rename::rename(params, &snapshot.db))
ide::navigation::rename::rename(params, &snapshot.db)
}
}

Expand Down

0 comments on commit c4e52a5

Please sign in to comment.