mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-08-18 17:40:29 +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
|
@ -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) }?;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue