Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit 64b2ec3

Browse files
committed
Clean up prototype implementation
1 parent 940ffe6 commit 64b2ec3

File tree

1 file changed

+93
-106
lines changed

1 file changed

+93
-106
lines changed

src/build.rs

Lines changed: 93 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ extern crate syntax;
1818

1919
use cargo::core::{PackageId, Shell, Workspace, Verbosity};
2020
use cargo::ops::{compile_with_exec, Executor, Context, Packages, CompileOptions, CompileMode, CompileFilter, Unit};
21-
use cargo::util::{Config as CargoConfig, ProcessBuilder, homedir, ConfigValue};
22-
use cargo::util::{CargoResult, important_paths};
21+
use cargo::util::{Config as CargoConfig, ProcessBuilder, homedir, important_paths, ConfigValue, CargoResult};
2322

2423
use data::Analysis;
2524
use vfs::Vfs;
@@ -256,7 +255,7 @@ impl BuildQueue {
256255
let result = self.cargo(build_dir.clone());
257256

258257
match result {
259-
BuildResult::Err |
258+
BuildResult::Err => return BuildResult::Err,
260259
_ if workspace_mode => return result,
261260
_ => {},
262261
};
@@ -275,23 +274,25 @@ impl BuildQueue {
275274
compilation_cx: Arc<Mutex<CompilationContext>>,
276275
cur_package_id: Mutex<Option<PackageId>>,
277276
config: Arc<Mutex<Config>>,
278-
/// Packages which are directly a member of the workspace, currently
279-
/// RLS shouldn't provide analysis for upstream packages to those
280277
workspace_mode: bool,
278+
/// Packages which are directly a member of the workspace, for which
279+
/// analysis and diagnostics will be provided
281280
member_packages: Mutex<HashSet<PackageId>>,
282281
/// JSON compiler messages emitted for each primary compiled crate
283282
compiler_messages: Arc<Mutex<Vec<String>>>,
284283
}
285284

286285
impl RlsExecutor {
287286
fn new(compilation_cx: Arc<Mutex<CompilationContext>>,
288-
config: Arc<Mutex<Config>>, compiler_messages: Arc<Mutex<Vec<String>>>)
289-
-> RlsExecutor {
287+
config: Arc<Mutex<Config>>,
288+
compiler_messages: Arc<Mutex<Vec<String>>>)
289+
-> RlsExecutor {
290+
let workspace_mode = config.lock().unwrap().workspace_mode;
290291
RlsExecutor {
291-
compilation_cx: compilation_cx,
292+
compilation_cx,
292293
cur_package_id: Mutex::new(None),
293294
config,
294-
workspace_mode: config.lock().unwrap().workspace_mode,
295+
workspace_mode,
295296
member_packages: Mutex::new(HashSet::new()),
296297
compiler_messages,
297298
}
@@ -303,7 +304,7 @@ impl BuildQueue {
303304
} else {
304305
let cur_package_id = self.cur_package_id.lock().unwrap();
305306
id == cur_package_id.as_ref().expect("Executor has not been initialised")
306-
};
307+
}
307308
}
308309
}
309310

@@ -417,7 +418,9 @@ impl BuildQueue {
417418
for a in &args {
418419
// Emitting only dep-info is possible only for final crate type, as
419420
// as others may emit required metadata for dependent crate types
420-
if a.starts_with("--emit") && is_final_crate_type && !workspace_mode {
421+
// In workspace_mode we don't run follow-up rustc, so don't omit anything,
422+
// as we need the generated save-analysis file
423+
if a.starts_with("--emit") && is_final_crate_type && !self.workspace_mode {
421424
cmd.arg("--emit=dep-info");
422425
} else {
423426
cmd.arg(a);
@@ -429,8 +432,7 @@ impl BuildQueue {
429432
}
430433
}
431434

432-
// Different path for workspace_mode just to be 110% sure it doesn't affect old behaviour
433-
if workspace_mode {
435+
if self.workspace_mode {
434436
let output = cmd.output().expect("Couldn't execute rustc");
435437
let mut stderr_json_msg = convert_message_to_json_strings(output.stderr);
436438
self.compiler_messages.lock().unwrap().append(&mut stderr_json_msg);
@@ -464,64 +466,27 @@ impl BuildQueue {
464466
// However, if Cargo doesn't run a separate thread, then we'll just wait
465467
// forever. Therefore, we spawn an extra thread here to be safe.
466468
let handle = thread::spawn(move || {
467-
#[allow(dead_code)]
468469
#[derive(Debug)]
469470
struct CargoOptions {
470-
flag_package: Vec<String>,
471-
flag_jobs: Option<u32>,
472-
flag_features: Vec<String>,
473-
flag_all_features: bool,
474-
flag_no_default_features: bool,
475-
flag_target: Option<String>,
476-
flag_manifest_path: Option<String>,
477-
flag_verbose: u32,
478-
flag_quiet: Option<bool>,
479-
flag_color: Option<String>,
480-
//flag_message_format: MessageFormat,
481-
flag_release: bool,
482-
flag_lib: bool,
483-
flag_bin: Vec<String>,
484-
flag_bins: bool,
485-
flag_example: Vec<String>,
486-
flag_examples: bool,
487-
flag_test: Vec<String>,
488-
flag_tests: bool,
489-
flag_bench: Vec<String>,
490-
flag_benches: bool,
491-
flag_locked: bool,
492-
flag_frozen: bool,
493-
flag_all: bool,
494-
flag_exclude: Vec<String>,
471+
package: Vec<String>,
472+
target: Option<String>,
473+
lib: bool,
474+
bin: Vec<String>,
475+
bins: bool,
476+
all: bool,
477+
exclude: Vec<String>,
495478
}
496479

497480
impl CargoOptions {
498481
fn default() -> CargoOptions {
499482
CargoOptions {
500-
flag_package: vec![],
501-
flag_jobs: None,
502-
flag_features: vec![],
503-
flag_all_features: false,
504-
flag_no_default_features: false,
505-
flag_target: None,
506-
flag_manifest_path: None,
507-
flag_verbose: 0, // u32?
508-
flag_quiet: None,
509-
flag_color: None,
510-
//flag_message_format: MessageFormat::Human,
511-
flag_release: false,
512-
flag_lib: false,
513-
flag_bin: vec![],
514-
flag_bins: false,
515-
flag_example: vec![],
516-
flag_examples: false,
517-
flag_test: vec![],
518-
flag_tests: false,
519-
flag_bench: vec![],
520-
flag_benches: false,
521-
flag_locked: false,
522-
flag_frozen: false,
523-
flag_all: false,
524-
flag_exclude: vec![],
483+
package: vec![],
484+
target: None,
485+
lib: false,
486+
bin: vec![],
487+
bins: false,
488+
all: false,
489+
exclude: vec![],
525490
}
526491
}
527492

@@ -533,13 +498,13 @@ impl BuildQueue {
533498
};
534499

535500
CargoOptions {
536-
flag_package: package,
537-
flag_all: all,
538-
flag_target: config.target.clone(),
501+
package,
502+
all,
503+
target: config.target.clone(),
539504
.. CargoOptions::default()
540505
}
541506
} else {
542-
// In non-workspace mode we currently support only one crate target,
507+
// In single-crate mode we currently support only one crate target,
543508
// and if lib is set, then we ignore bin target config
544509
let (lib, bin) = match config.build_lib {
545510
true => (true, vec![]),
@@ -553,70 +518,92 @@ impl BuildQueue {
553518
};
554519

555520
CargoOptions {
556-
flag_lib: lib,
557-
flag_bin: bin,
558-
flag_target: config.target.clone(),
521+
lib,
522+
bin,
523+
target: config.target.clone(),
559524
.. CargoOptions::default()
560525
}
561526
}
562527
}
563528
}
564529

530+
fn prepare_cargo_rustflags(config: &Config) -> String {
531+
let mut flags = "-Zunstable-options -Zsave-analysis --error-format=json \
532+
-Zcontinue-parse-after-error".to_owned();
533+
534+
if let Some(ref sysroot) = config.sysroot {
535+
flags.push_str(&format!(" --sysroot {}", sysroot));
536+
}
537+
538+
flags = format!("{} {} {}",
539+
env::var("RUSTFLAGS").unwrap_or(String::new()),
540+
config.rustflags.as_ref().unwrap_or(&String::new()),
541+
flags);
542+
543+
dedup_flags(&flags)
544+
}
545+
565546
// Note that this may not be equal build_dir when inside a workspace member
566547
let manifest_path = important_paths::find_root_manifest_for_wd(None, &build_dir)
567548
.expect(&format!("Couldn't find a root manifest for cwd: {:?}", &build_dir));
568549
trace!("root manifest_path: {:?}", &manifest_path);
569550

570551
let mut shell = Shell::from_write(Box::new(BufWriter(out.clone())));
571552
shell.set_verbosity(Verbosity::Quiet);
572-
// We construct relative paths from the manifest dir, so we have to omit the filename
573-
let config = make_cargo_config(manifest_path.parent().unwrap(), shell);
553+
554+
// Cargo constructs relative paths from the manifest dir, so we have to pop "Cargo.toml"
555+
let manifest_dir = manifest_path.parent().unwrap();
556+
let config = make_cargo_config(manifest_dir, shell);
574557

575558
let ws = Workspace::new(&manifest_path, &config).expect("could not create cargo workspace");
576559

577-
// Copy over relevant options without locking whole config, as compilation procedure
578-
// will need those and we don't want to lock whole config file during that period
579-
// TODO: Keep this structure cached and regenerate it on every relevant configuration change
580-
let rls_config = rls_config.lock().unwrap().clone();
560+
// TODO: It might be feasible to keep this CargoOptions structure cached and regenerate
561+
// it on every relevant configuration change
562+
let (opts, rustflags) = {
563+
// We mustn't lock configuration for the whole build process
564+
let rls_config = rls_config.lock().unwrap();
581565

582-
let opts = CargoOptions::new(&rls_config);
583-
trace!("Current Cargo compilation options:\n{:?}", opts);
566+
let opts = CargoOptions::new(&rls_config);
567+
trace!("Cargo compilation options:\n{:?}", opts);
584568

585-
let spec = Packages::from_flags(opts.flag_all, &opts.flag_exclude, &opts.flag_package)
569+
// Warn about invalid specified bin target or package depending on current mode
570+
// TODO: Return client notifications along with diagnostics to inform the user
571+
if !rls_config.workspace_mode {
572+
let cur_pkg_targets = ws.current().unwrap().targets();
573+
574+
if let Some(ref build_bin) = rls_config.build_bin {
575+
let mut bins = cur_pkg_targets.iter().filter(|x| x.is_bin());
576+
if let None = bins.find(|x| x.name() == build_bin) {
577+
warn!("cargo - couldn't find binary `{}` specified in \"build_bin\" configuration", build_bin);
578+
}
579+
}
580+
} else {
581+
for package in &opts.package {
582+
if let None = ws.members().find(|x| x.name() == package) {
583+
warn!("cargo - couldn't find member package `{}` specified in \"analyze_package\" configuration", package);
584+
}
585+
}
586+
}
587+
588+
let rustflags = prepare_cargo_rustflags(&rls_config);
589+
(opts, rustflags)
590+
};
591+
592+
let spec = Packages::from_flags(opts.all, &opts.exclude, &opts.package)
586593
.expect("Couldn't create Packages for Cargo");
587594

588595
let compile_opts = CompileOptions {
589-
target: opts.flag_target.as_ref().map(|t| &t[..]),
596+
target: opts.target.as_ref().map(|t| &t[..]),
590597
spec: spec,
591-
filter: CompileFilter::new(opts.flag_lib,
592-
&opts.flag_bin, opts.flag_bins,
593-
// TODO: Support more crate target types
594-
&[], false, &[], false, &[], false),
598+
filter: CompileFilter::new(opts.lib,
599+
&opts.bin, opts.bins,
600+
// TODO: Support more crate target types
601+
&[], false, &[], false, &[], false),
595602
.. CompileOptions::default(&config, CompileMode::Check)
596603
};
597-
598-
599-
let rustflags = {
600-
let mut flags = "-Zunstable-options -Zsave-analysis --error-format=json \
601-
-Zcontinue-parse-after-error".to_owned();
602-
603-
// TODO: Needed? since it's also pushed in exec()
604-
if let Some(ref sysroot) = rls_config.sysroot {
605-
flags.push_str(&format!(" --sysroot {}", sysroot));
606-
}
607-
608-
flags = format!("{} {} {}",
609-
env::var("RUSTFLAGS").unwrap_or(String::new()),
610-
rls_config.rustflags.as_ref().unwrap_or(&String::new()),
611-
flags);
612-
613-
dedup_flags(&flags)
614-
};
604+
615605
env::set_var("RUSTFLAGS", rustflags);
616606

617-
// let current_package = ws.current().unwrap();
618-
// let targets = current_package.targets();
619-
620607
compile_with_exec(&ws, &compile_opts, Arc::new(exec)).expect("could not run cargo");
621608
});
622609

0 commit comments

Comments
 (0)