mirror of
https://github.com/rust-lang/rust-analyzer
synced 2024-11-10 07:04:22 +00:00
internal: make sure that proc macro machinery doesn't depend on cwd
This commit is contained in:
parent
9318c643f1
commit
8df38aa797
9 changed files with 52 additions and 22 deletions
4
Cargo.lock
generated
4
Cargo.lock
generated
|
@ -1042,6 +1042,9 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "paths"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
|
@ -1109,6 +1112,7 @@ dependencies = [
|
|||
"log",
|
||||
"memmap2",
|
||||
"object",
|
||||
"paths",
|
||||
"profile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
|
|
@ -7,3 +7,6 @@ edition = "2018"
|
|||
|
||||
[lib]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
serde = "1"
|
||||
|
|
|
@ -66,6 +66,27 @@ impl PartialEq<AbsPath> for AbsPathBuf {
|
|||
}
|
||||
}
|
||||
|
||||
impl serde::Serialize for AbsPathBuf {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
self.0.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::Deserialize<'de> for AbsPathBuf {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
let path = PathBuf::deserialize(deserializer)?;
|
||||
AbsPathBuf::try_from(path).map_err(|path| {
|
||||
serde::de::Error::custom(format!("expected absolute path, got {}", path.display()))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl AbsPathBuf {
|
||||
/// Wrap the given absolute path in `AbsPathBuf`
|
||||
///
|
||||
|
|
|
@ -18,6 +18,7 @@ memmap2 = "0.3.0"
|
|||
object = { version = "0.25.3", default-features = false, features = ["std", "read_core", "elf", "macho", "pe"] }
|
||||
snap = "1.0"
|
||||
|
||||
paths = { path = "../paths", version = "0.0.0" }
|
||||
tt = { path = "../tt", version = "0.0.0" }
|
||||
base_db = { path = "../base_db", version = "0.0.0" }
|
||||
stdx = { path = "../stdx", version = "0.0.0" }
|
||||
|
|
|
@ -11,10 +11,10 @@ mod rpc;
|
|||
mod version;
|
||||
|
||||
use base_db::{Env, ProcMacro};
|
||||
use paths::{AbsPath, AbsPathBuf};
|
||||
use std::{
|
||||
ffi::OsStr,
|
||||
io,
|
||||
path::{Path, PathBuf},
|
||||
sync::{Arc, Mutex},
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@ pub use version::{read_dylib_info, RustCInfo};
|
|||
#[derive(Debug, Clone)]
|
||||
struct ProcMacroProcessExpander {
|
||||
process: Arc<Mutex<ProcMacroProcessSrv>>,
|
||||
dylib_path: PathBuf,
|
||||
dylib_path: AbsPathBuf,
|
||||
name: SmolStr,
|
||||
}
|
||||
|
||||
|
@ -79,26 +79,25 @@ pub struct ProcMacroClient {
|
|||
impl ProcMacroClient {
|
||||
/// Spawns an external process as the proc macro server and returns a client connected to it.
|
||||
pub fn extern_process(
|
||||
process_path: PathBuf,
|
||||
process_path: AbsPathBuf,
|
||||
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
|
||||
) -> io::Result<ProcMacroClient> {
|
||||
let process = ProcMacroProcessSrv::run(process_path, args)?;
|
||||
Ok(ProcMacroClient { process: Arc::new(Mutex::new(process)) })
|
||||
}
|
||||
|
||||
// TODO: use paths::AbsPath here
|
||||
pub fn by_dylib_path(&self, dylib_path: &Path) -> Vec<ProcMacro> {
|
||||
pub fn by_dylib_path(&self, dylib_path: &AbsPath) -> Vec<ProcMacro> {
|
||||
let _p = profile::span("ProcMacroClient::by_dylib_path");
|
||||
match version::read_dylib_info(dylib_path) {
|
||||
Ok(info) => {
|
||||
if info.version.0 < 1 || info.version.1 < 47 {
|
||||
eprintln!("proc-macro {} built by {:#?} is not supported by Rust Analyzer, please update your rust version.", dylib_path.to_string_lossy(), info);
|
||||
eprintln!("proc-macro {} built by {:#?} is not supported by Rust Analyzer, please update your rust version.", dylib_path.display(), info);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
eprintln!(
|
||||
"proc-macro {} failed to find the given version. Reason: {}",
|
||||
dylib_path.to_string_lossy(),
|
||||
dylib_path.display(),
|
||||
err
|
||||
);
|
||||
}
|
||||
|
@ -129,7 +128,7 @@ impl ProcMacroClient {
|
|||
let expander = Arc::new(ProcMacroProcessExpander {
|
||||
process: self.process.clone(),
|
||||
name: name.clone(),
|
||||
dylib_path: dylib_path.into(),
|
||||
dylib_path: dylib_path.to_path_buf(),
|
||||
});
|
||||
|
||||
ProcMacro { name, kind, expander }
|
||||
|
|
|
@ -4,10 +4,10 @@ use std::{
|
|||
convert::{TryFrom, TryInto},
|
||||
ffi::{OsStr, OsString},
|
||||
io::{self, BufRead, BufReader, Write},
|
||||
path::{Path, PathBuf},
|
||||
process::{Child, ChildStdin, ChildStdout, Command, Stdio},
|
||||
};
|
||||
|
||||
use paths::{AbsPath, AbsPathBuf};
|
||||
use stdx::JodChild;
|
||||
|
||||
use crate::{
|
||||
|
@ -24,7 +24,7 @@ pub(crate) struct ProcMacroProcessSrv {
|
|||
|
||||
impl ProcMacroProcessSrv {
|
||||
pub(crate) fn run(
|
||||
process_path: PathBuf,
|
||||
process_path: AbsPathBuf,
|
||||
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
|
||||
) -> io::Result<ProcMacroProcessSrv> {
|
||||
let mut process = Process::run(process_path, args)?;
|
||||
|
@ -37,7 +37,7 @@ impl ProcMacroProcessSrv {
|
|||
|
||||
pub(crate) fn find_proc_macros(
|
||||
&mut self,
|
||||
dylib_path: &Path,
|
||||
dylib_path: &AbsPath,
|
||||
) -> Result<Vec<(String, ProcMacroKind)>, tt::ExpansionError> {
|
||||
let task = ListMacrosTask { lib: dylib_path.to_path_buf() };
|
||||
|
||||
|
@ -84,7 +84,7 @@ struct Process {
|
|||
|
||||
impl Process {
|
||||
fn run(
|
||||
path: PathBuf,
|
||||
path: AbsPathBuf,
|
||||
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
|
||||
) -> io::Result<Process> {
|
||||
let args: Vec<OsString> = args.into_iter().map(|s| s.as_ref().into()).collect();
|
||||
|
@ -101,8 +101,11 @@ impl Process {
|
|||
}
|
||||
}
|
||||
|
||||
fn mk_child(path: &Path, args: impl IntoIterator<Item = impl AsRef<OsStr>>) -> io::Result<Child> {
|
||||
Command::new(&path)
|
||||
fn mk_child(
|
||||
path: &AbsPath,
|
||||
args: impl IntoIterator<Item = impl AsRef<OsStr>>,
|
||||
) -> io::Result<Child> {
|
||||
Command::new(path.as_os_str())
|
||||
.args(args)
|
||||
.stdin(Stdio::piped())
|
||||
.stdout(Stdio::piped())
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
//! to be much easier, we deliberately duplicate `tt` structs with `#[serde(with = "XXDef")]`
|
||||
//! for separation of code responsibility.
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
use paths::AbsPathBuf;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tt::{
|
||||
Delimiter, DelimiterKind, Ident, Leaf, Literal, Punct, SmolStr, Spacing, Subtree, TokenId,
|
||||
|
@ -16,7 +15,7 @@ use tt::{
|
|||
|
||||
#[derive(Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
pub struct ListMacrosTask {
|
||||
pub lib: PathBuf,
|
||||
pub lib: AbsPathBuf,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
|
||||
|
@ -50,7 +49,7 @@ pub struct ExpansionTask {
|
|||
#[serde(with = "opt_subtree_def")]
|
||||
pub attributes: Option<Subtree>,
|
||||
|
||||
pub lib: PathBuf,
|
||||
pub lib: AbsPathBuf,
|
||||
|
||||
/// Environment variables to set during macro expansion.
|
||||
pub env: Vec<(String, String)>,
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
use std::{
|
||||
fs::File,
|
||||
io::{self, Read},
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use memmap2::Mmap;
|
||||
use object::read::{File as BinaryFile, Object, ObjectSection};
|
||||
use paths::AbsPath;
|
||||
use snap::read::FrameDecoder as SnapDecoder;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -19,7 +19,7 @@ pub struct RustCInfo {
|
|||
}
|
||||
|
||||
/// Read rustc dylib information
|
||||
pub fn read_dylib_info(dylib_path: &Path) -> io::Result<RustCInfo> {
|
||||
pub fn read_dylib_info(dylib_path: &AbsPath) -> io::Result<RustCInfo> {
|
||||
macro_rules! err {
|
||||
($e:literal) => {
|
||||
io::Error::new(io::ErrorKind::InvalidData, $e)
|
||||
|
@ -96,7 +96,7 @@ fn read_section<'a>(dylib_binary: &'a [u8], section_name: &str) -> io::Result<&'
|
|||
/// * [some more bytes that we don really care but still there] :-)
|
||||
/// Check this issue for more about the bytes layout:
|
||||
/// <https://github.com/rust-analyzer/rust-analyzer/issues/6174>
|
||||
fn read_version(dylib_path: &Path) -> io::Result<String> {
|
||||
fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
|
||||
let dylib_file = File::open(dylib_path)?;
|
||||
let dylib_mmaped = unsafe { Mmap::map(&dylib_file) }?;
|
||||
|
||||
|
|
|
@ -312,7 +312,7 @@ impl ProjectWorkspace {
|
|||
) -> CrateGraph {
|
||||
let _p = profile::span("ProjectWorkspace::to_crate_graph");
|
||||
let proc_macro_loader = |path: &AbsPath| match proc_macro_client {
|
||||
Some(client) => client.by_dylib_path(path.as_ref()), // TODO
|
||||
Some(client) => client.by_dylib_path(path),
|
||||
None => Vec::new(),
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue