From e9e5c6551aa42b4ec047082709e9148233fd5f3f Mon Sep 17 00:00:00 2001 From: Mauro Balbi Date: Fri, 16 Feb 2024 14:18:06 +0100 Subject: [PATCH] Restrict renaming --- crates/glas/src/server.rs | 24 +++++++++++++++++------- crates/ide/Cargo.toml | 2 +- crates/ide/src/base.rs | 4 +++- crates/ide/src/def/hir.rs | 7 +++++++ crates/ide/src/ide/rename.rs | 11 +++++++++++ crates/ide/src/tests.rs | 3 ++- 6 files changed, 41 insertions(+), 10 deletions(-) diff --git a/crates/glas/src/server.rs b/crates/glas/src/server.rs index c1431f6..d7a32e8 100644 --- a/crates/glas/src/server.rs +++ b/crates/glas/src/server.rs @@ -168,7 +168,7 @@ impl Server { .request_snap::(handler::semantic_token_full) .request_snap::(handler::semantic_token_range) //// Events //// - .event(Self::on_set_package_info) + .event(Self::on_set_package_graph) .event(Self::on_update_config) .event(Self::on_update_diagnostics) // Loopback event. @@ -595,7 +595,7 @@ impl Server { graph: &mut PackageGraph, roots: &mut IndexSet, seen: &mut HashMap, - is_local: bool, + is_relative: bool, ) -> Result { roots.insert(PackageRoot { path: root_path.to_path_buf(), @@ -630,7 +630,17 @@ impl Server { let package = match seen.get(name.as_str()) { Some(idx) => idx.clone(), - None => graph.add_package(name.clone(), gleam_file), + None => { + let parent = root_path.parent(); + tracing::info!("PARENT PATH {:?}", parent); + let is_parent_packages = parent.map(|p| p.ends_with("packages")).unwrap_or(false); + let grand_parent = parent.and_then(|p| p.parent()); + + tracing::info!("GPARENT PATH {:?}", grand_parent); + let is_grand_parent_build = grand_parent.map(|p| p.ends_with("build")).unwrap_or(false); + let is_not_local = is_parent_packages && is_grand_parent_build; + graph.add_package(name.clone(), gleam_file, !is_not_local ) + }, }; seen.insert(name, package); @@ -644,7 +654,7 @@ impl Server { graph.add_dep(package, dependency); continue; } - let path = if is_local { + let path = if is_relative { package_dir.join(name) } else { root_path.parent().unwrap().join(name) @@ -654,8 +664,8 @@ impl Server { .and_then(|t| t.get("path")) .and_then(|v| v.as_str()) { - Some(local_path) => { - let local_path = root_path.join(local_path); + Some(relative_path) => { + let local_path = root_path.join(relative_path); let Ok(dep_id) = Self::assemble_graph(vfs, &local_path, graph, roots, seen, true) else { @@ -715,7 +725,7 @@ impl Server { } } - fn on_set_package_info(&mut self, info: SetPackageGraphEvent) -> NotifyResult { + fn on_set_package_graph(&mut self, info: SetPackageGraphEvent) -> NotifyResult { tracing::debug!("Set package info: {:#?}", info.0); let mut vfs = self.vfs.write().unwrap(); diff --git a/crates/ide/Cargo.toml b/crates/ide/Cargo.toml index 28f2cc8..b1478e8 100644 --- a/crates/ide/Cargo.toml +++ b/crates/ide/Cargo.toml @@ -19,6 +19,7 @@ salsa = "0.17.0-pre.2" smallvec = { version = "1.10.0", features = ["const_generics", "union"] } smol_str = "0.1.23" anymap = "0.12.1" +anyhow = "1.0.60" nohash-hasher = "0.2.0" petgraph = "0.6.3" syntax = { path = "../syntax" } @@ -36,6 +37,5 @@ features = [ ] [dev-dependencies] -anyhow = "1.0.60" expect-test = "1.4.0" tracing-test = "0.1" \ No newline at end of file diff --git a/crates/ide/src/base.rs b/crates/ide/src/base.rs index 0073990..dc2536e 100644 --- a/crates/ide/src/base.rs +++ b/crates/ide/src/base.rs @@ -245,11 +245,12 @@ impl PackageGraph { self.target = target; } - pub fn add_package(&mut self, display_name: SmolStr, gleam_toml: FileId) -> PackageId { + pub fn add_package(&mut self, display_name: SmolStr, gleam_toml: FileId, is_local: bool) -> PackageId { let info = PackageInfo { gleam_toml, display_name, dependencies: Vec::new(), + is_local, }; self.arena.alloc(info) } @@ -278,6 +279,7 @@ pub struct PackageInfo { // pub version: Option, pub display_name: SmolStr, pub dependencies: Vec, + pub is_local: bool, } #[derive(Debug, Clone, PartialEq, Eq, Default)] diff --git a/crates/ide/src/def/hir.rs b/crates/ide/src/def/hir.rs index 0dab935..4d4885f 100644 --- a/crates/ide/src/def/hir.rs +++ b/crates/ide/src/def/hir.rs @@ -27,6 +27,13 @@ pub struct Package { } impl Package { + pub fn is_local(self, db: &dyn DefDatabase) -> bool { + let package_id = db.source_root_package(self.id); + let graph = db.package_graph(); + let package = graph[*package_id].clone(); + package.is_local + } + pub fn dependencies(self, db: &dyn DefDatabase) -> Vec { let package_id = db.source_root_package(self.id); let graph = db.package_graph(); diff --git a/crates/ide/src/ide/rename.rs b/crates/ide/src/ide/rename.rs index df8927d..156c19f 100644 --- a/crates/ide/src/ide/rename.rs +++ b/crates/ide/src/ide/rename.rs @@ -1,5 +1,6 @@ use std::collections::{HashMap, HashSet}; +use anyhow::Context; use itertools::Either; use smol_str::SmolStr; use syntax::{ast::AstNode, best_token_at_offset, lexer::GleamLexer, TextRange}; @@ -28,6 +29,16 @@ pub(crate) fn prepare_rename( Either::Right(str) => return Err(str), }; + let is_local = def + .module(sema.db.upcast()) + .ok_or_else(|| "No references found".to_owned())? + .package(sema.db.upcast()) + .is_local(sema.db.upcast()); + + if !is_local { + return Err("Cannot rename a definition from a dependency".to_owned()) + } + let name = match def { Definition::Module(_) | Definition::BuiltIn(_) => { return Err(String::from("No references found")) diff --git a/crates/ide/src/tests.rs b/crates/ide/src/tests.rs index 0357486..e8c99fc 100644 --- a/crates/ide/src/tests.rs +++ b/crates/ide/src/tests.rs @@ -55,7 +55,7 @@ impl TestDB { } change.set_roots(vec![SourceRoot::new(file_set, "/".into())]); let mut package_graph = PackageGraph::default(); - package_graph.add_package(SmolStr::from("test"), FileId(f.files.len() as u32 - 1)); + package_graph.add_package(SmolStr::from("test"), FileId(f.files.len() as u32 - 1), true); change.set_package_graph(package_graph); change.apply(&mut db); @@ -158,6 +158,7 @@ impl Fixture { gleam_toml: FileId(this.files.len() as u32 - 1), dependencies: Default::default(), display_name: "Test".into(), + is_local: true, }); let marker_len = markers