@@ -13,9 +13,11 @@ use serde_derive::Serialize;
1313use std:: collections:: { BTreeMap , BTreeSet } ;
1414use std:: io;
1515use std:: path:: Path ;
16+ use std:: process:: Command ;
1617
18+ use crate :: core:: build_steps:: compile:: { stream_cargo, CargoMessage } ;
19+ use crate :: core:: builder:: Builder ;
1720use crate :: core:: metadata:: { project_metadata, workspace_members, Dependency } ;
18- use crate :: Config ;
1921
2022#[ derive( Debug , Serialize ) ]
2123/// FIXME(before-merge): doc-comment
@@ -47,8 +49,9 @@ struct Dep {
4749}
4850
4951impl RustAnalyzerProject {
50- #[ allow( dead_code) ] // FIXME(before-merge): remove this
51- pub ( crate ) fn collect_ra_project_data ( config : & Config ) -> Self {
52+ pub ( crate ) fn collect_ra_project_data ( builder : & Builder < ' _ > ) -> Self {
53+ let config = & builder. config ;
54+
5255 let mut ra_project = RustAnalyzerProject {
5356 crates : vec ! [ ] ,
5457 sysroot : format ! ( "{}" , config. out. join( "host" ) . join( "stage0" ) . display( ) ) ,
@@ -86,11 +89,6 @@ impl RustAnalyzerProject {
8689 krate. is_workspace_member = workspace_members. iter ( ) . any ( |p| p. name == target. name ) ;
8790 krate. is_proc_macro = target. crate_types . contains ( & "proc-macro" . to_string ( ) ) ;
8891
89- // FIXME(before-merge): We need to figure out how to find proc-macro dylibs.
90- // if krate.is_proc_macro {
91- // krate.proc_macro_dylib_path =
92- // }
93-
9492 krate. env . insert ( "RUSTC_BOOTSTRAP" . into ( ) , "1" . into ( ) ) ;
9593
9694 if target
@@ -109,14 +107,51 @@ impl RustAnalyzerProject {
109107
110108 // Find and fill dependencies of crates.
111109 for package in packages {
112- if package. dependencies . is_empty ( ) {
113- continue ;
114- }
110+ if let Some ( index) =
111+ ra_project. crates . iter ( ) . position ( |c| c. display_name == package. name )
112+ {
113+ assert ! (
114+ !package. manifest_path. is_empty( ) ,
115+ "manifest_path must be valid for proc-macro crates."
116+ ) ;
117+
118+ let mut cargo = Command :: new ( & builder. initial_cargo ) ;
119+ cargo
120+ . env ( "RUSTC_BOOTSTRAP" , "1" )
121+ . arg ( "build" )
122+ . arg ( "--manifest-path" )
123+ . arg ( package. manifest_path ) ;
124+
125+ if ra_project. crates [ index] . is_proc_macro {
126+ // FIXME(before-merge): use `CARGO_TARGET_DIR` to place shared libraries in the build output directory.
127+ let ok = stream_cargo ( builder, cargo. into ( ) , vec ! [ ] , & mut |msg| {
128+ let filenames = match msg {
129+ CargoMessage :: CompilerArtifact { filenames, .. } => filenames,
130+ _ => return ,
131+ } ;
132+
133+ for filename in filenames {
134+ let snake_case_name = ra_project. crates [ index]
135+ . display_name
136+ . replace ( '-' , "_" )
137+ . to_lowercase ( ) ;
138+
139+ if filename. ends_with ( ".so" )
140+ && ( filename. contains ( & format ! (
141+ "lib{}" ,
142+ ra_project. crates[ index] . display_name
143+ ) ) || filename. contains ( & format ! ( "lib{}" , snake_case_name) ) )
144+ {
145+ ra_project. crates [ index] . proc_macro_dylib_path =
146+ Some ( filename. to_string ( ) ) ;
147+ }
148+ }
149+ } ) ;
115150
116- for dependency in package . dependencies {
117- if let Some ( index ) =
118- ra_project . crates . iter ( ) . position ( |c| c . display_name == package . name )
119- {
151+ assert ! ( ok ) ;
152+ }
153+
154+ for dependency in package . dependencies {
120155 if let Some ( dependency_index) =
121156 ra_project. crates . iter ( ) . position ( |c| c. display_name == dependency. name )
122157 {
@@ -138,7 +173,6 @@ impl RustAnalyzerProject {
138173 ra_project
139174 }
140175
141- #[ allow( dead_code) ] // FIXME(before-merge): remove this
142176 pub ( crate ) fn generate_file ( & self , path : & Path ) -> io:: Result < ( ) > {
143177 if path. exists ( ) {
144178 return Err ( io:: Error :: new (
0 commit comments