mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Support setting cargo features
This commit is contained in:
parent
5eb5e80de9
commit
af4eb26645
@ -22,7 +22,7 @@ fn vfs_root_to_id(r: ra_vfs::VfsRoot) -> SourceRootId {
|
|||||||
|
|
||||||
pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> {
|
pub fn load_cargo(root: &Path) -> Result<(AnalysisHost, FxHashMap<SourceRootId, PackageRoot>)> {
|
||||||
let root = std::env::current_dir()?.join(root);
|
let root = std::env::current_dir()?.join(root);
|
||||||
let ws = ProjectWorkspace::discover(root.as_ref())?;
|
let ws = ProjectWorkspace::discover(root.as_ref(), &Default::default())?;
|
||||||
let project_roots = ws.to_roots();
|
let project_roots = ws.to_roots();
|
||||||
let (sender, receiver) = unbounded();
|
let (sender, receiver) = unbounded();
|
||||||
let sender = Box::new(move |t| sender.send(t).unwrap());
|
let sender = Box::new(move |t| sender.send(t).unwrap());
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
|
||||||
|
use ra_project_model::CargoFeatures;
|
||||||
use serde::{Deserialize, Deserializer};
|
use serde::{Deserialize, Deserializer};
|
||||||
|
|
||||||
/// Client provided initialization options
|
/// Client provided initialization options
|
||||||
@ -37,6 +38,9 @@ pub struct ServerConfig {
|
|||||||
|
|
||||||
/// Fine grained feature flags to disable specific features.
|
/// Fine grained feature flags to disable specific features.
|
||||||
pub feature_flags: FxHashMap<String, bool>,
|
pub feature_flags: FxHashMap<String, bool>,
|
||||||
|
|
||||||
|
/// Cargo feature configurations.
|
||||||
|
pub cargo_features: CargoFeatures,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ServerConfig {
|
impl Default for ServerConfig {
|
||||||
@ -49,6 +53,7 @@ impl Default for ServerConfig {
|
|||||||
max_inlay_hint_length: None,
|
max_inlay_hint_length: None,
|
||||||
with_sysroot: true,
|
with_sysroot: true,
|
||||||
feature_flags: FxHashMap::default(),
|
feature_flags: FxHashMap::default(),
|
||||||
|
cargo_features: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,6 +67,7 @@ pub fn main_loop(
|
|||||||
let workspace = ra_project_model::ProjectWorkspace::discover_with_sysroot(
|
let workspace = ra_project_model::ProjectWorkspace::discover_with_sysroot(
|
||||||
ws_root.as_path(),
|
ws_root.as_path(),
|
||||||
config.with_sysroot,
|
config.with_sysroot,
|
||||||
|
&config.cargo_features,
|
||||||
);
|
);
|
||||||
match workspace {
|
match workspace {
|
||||||
Ok(workspace) => loaded_workspaces.push(workspace),
|
Ok(workspace) => loaded_workspaces.push(workspace),
|
||||||
|
@ -6,6 +6,7 @@ use cargo_metadata::{CargoOpt, MetadataCommand};
|
|||||||
use ra_arena::{impl_arena_id, Arena, RawId};
|
use ra_arena::{impl_arena_id, Arena, RawId};
|
||||||
use ra_db::Edition;
|
use ra_db::Edition;
|
||||||
use rustc_hash::FxHashMap;
|
use rustc_hash::FxHashMap;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
use crate::Result;
|
use crate::Result;
|
||||||
|
|
||||||
@ -23,6 +24,20 @@ pub struct CargoWorkspace {
|
|||||||
pub(crate) workspace_root: PathBuf,
|
pub(crate) workspace_root: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Clone, Debug, PartialEq, Eq, Default)]
|
||||||
|
#[serde(rename_all = "camelCase", default)]
|
||||||
|
pub struct CargoFeatures {
|
||||||
|
/// Do not activate the `default` feature.
|
||||||
|
pub no_default_features: bool,
|
||||||
|
|
||||||
|
/// Activate all available features
|
||||||
|
pub all_features: bool,
|
||||||
|
|
||||||
|
/// List of features to activate.
|
||||||
|
/// This will be ignored if `cargo_all_features` is true.
|
||||||
|
pub features: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
|
||||||
pub struct Package(RawId);
|
pub struct Package(RawId);
|
||||||
impl_arena_id!(Package);
|
impl_arena_id!(Package);
|
||||||
@ -132,9 +147,21 @@ impl Target {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl CargoWorkspace {
|
impl CargoWorkspace {
|
||||||
pub fn from_cargo_metadata(cargo_toml: &Path) -> Result<CargoWorkspace> {
|
pub fn from_cargo_metadata(
|
||||||
|
cargo_toml: &Path,
|
||||||
|
cargo_features: &CargoFeatures,
|
||||||
|
) -> Result<CargoWorkspace> {
|
||||||
let mut meta = MetadataCommand::new();
|
let mut meta = MetadataCommand::new();
|
||||||
meta.manifest_path(cargo_toml).features(CargoOpt::AllFeatures);
|
meta.manifest_path(cargo_toml);
|
||||||
|
if cargo_features.all_features {
|
||||||
|
meta.features(CargoOpt::AllFeatures);
|
||||||
|
} else if cargo_features.no_default_features {
|
||||||
|
// FIXME: `NoDefaultFeatures` is mutual exclusive with `SomeFeatures`
|
||||||
|
// https://github.com/oli-obk/cargo_metadata/issues/79
|
||||||
|
meta.features(CargoOpt::NoDefaultFeatures);
|
||||||
|
} else {
|
||||||
|
meta.features(CargoOpt::SomeFeatures(cargo_features.features.clone()));
|
||||||
|
}
|
||||||
if let Some(parent) = cargo_toml.parent() {
|
if let Some(parent) = cargo_toml.parent() {
|
||||||
meta.current_dir(parent);
|
meta.current_dir(parent);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ use rustc_hash::FxHashMap;
|
|||||||
use serde_json::from_reader;
|
use serde_json::from_reader;
|
||||||
|
|
||||||
pub use crate::{
|
pub use crate::{
|
||||||
cargo_workspace::{CargoWorkspace, Package, Target, TargetKind},
|
cargo_workspace::{CargoFeatures, CargoWorkspace, Package, Target, TargetKind},
|
||||||
json_project::JsonProject,
|
json_project::JsonProject,
|
||||||
sysroot::Sysroot,
|
sysroot::Sysroot,
|
||||||
};
|
};
|
||||||
@ -60,11 +60,15 @@ impl PackageRoot {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ProjectWorkspace {
|
impl ProjectWorkspace {
|
||||||
pub fn discover(path: &Path) -> Result<ProjectWorkspace> {
|
pub fn discover(path: &Path, cargo_features: &CargoFeatures) -> Result<ProjectWorkspace> {
|
||||||
ProjectWorkspace::discover_with_sysroot(path, true)
|
ProjectWorkspace::discover_with_sysroot(path, true, cargo_features)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn discover_with_sysroot(path: &Path, with_sysroot: bool) -> Result<ProjectWorkspace> {
|
pub fn discover_with_sysroot(
|
||||||
|
path: &Path,
|
||||||
|
with_sysroot: bool,
|
||||||
|
cargo_features: &CargoFeatures,
|
||||||
|
) -> Result<ProjectWorkspace> {
|
||||||
match find_rust_project_json(path) {
|
match find_rust_project_json(path) {
|
||||||
Some(json_path) => {
|
Some(json_path) => {
|
||||||
let file = File::open(json_path)?;
|
let file = File::open(json_path)?;
|
||||||
@ -73,7 +77,7 @@ impl ProjectWorkspace {
|
|||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
let cargo_toml = find_cargo_toml(path)?;
|
let cargo_toml = find_cargo_toml(path)?;
|
||||||
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml)?;
|
let cargo = CargoWorkspace::from_cargo_metadata(&cargo_toml, cargo_features)?;
|
||||||
let sysroot =
|
let sysroot =
|
||||||
if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() };
|
if with_sysroot { Sysroot::discover(&cargo_toml)? } else { Sysroot::default() };
|
||||||
Ok(ProjectWorkspace::Cargo { cargo, sysroot })
|
Ok(ProjectWorkspace::Cargo { cargo, sysroot })
|
||||||
|
@ -278,6 +278,21 @@
|
|||||||
"type": "number",
|
"type": "number",
|
||||||
"default": 20,
|
"default": 20,
|
||||||
"description": "Maximum length for inlay hints"
|
"description": "Maximum length for inlay hints"
|
||||||
|
},
|
||||||
|
"rust-analyzer.cargoFeatures.noDefaultFeatures": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Do not activate the `default` feature"
|
||||||
|
},
|
||||||
|
"rust-analyzer.cargoFeatures.allFeatures": {
|
||||||
|
"type": "boolean",
|
||||||
|
"default": false,
|
||||||
|
"description": "Activate all available features"
|
||||||
|
},
|
||||||
|
"rust-analyzer.cargoFeatures.features": {
|
||||||
|
"type": "array",
|
||||||
|
"default": [],
|
||||||
|
"description": "List of features to activate"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -15,6 +15,12 @@ export interface CargoWatchOptions {
|
|||||||
ignore: string[];
|
ignore: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface CargoFeatures {
|
||||||
|
noDefaultFeatures: boolean;
|
||||||
|
allFeatures: boolean;
|
||||||
|
features: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export class Config {
|
export class Config {
|
||||||
public highlightingOn = true;
|
public highlightingOn = true;
|
||||||
public rainbowHighlightingOn = false;
|
public rainbowHighlightingOn = false;
|
||||||
@ -35,8 +41,14 @@ export class Config {
|
|||||||
command: '',
|
command: '',
|
||||||
ignore: [],
|
ignore: [],
|
||||||
};
|
};
|
||||||
|
public cargoFeatures: CargoFeatures = {
|
||||||
|
noDefaultFeatures: false,
|
||||||
|
allFeatures: false,
|
||||||
|
features: [],
|
||||||
|
};
|
||||||
|
|
||||||
private prevEnhancedTyping: null | boolean = null;
|
private prevEnhancedTyping: null | boolean = null;
|
||||||
|
private prevCargoFeatures: null | CargoFeatures = null;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
vscode.workspace.onDidChangeConfiguration(_ =>
|
vscode.workspace.onDidChangeConfiguration(_ =>
|
||||||
@ -47,6 +59,8 @@ export class Config {
|
|||||||
|
|
||||||
public userConfigChanged() {
|
public userConfigChanged() {
|
||||||
const config = vscode.workspace.getConfiguration('rust-analyzer');
|
const config = vscode.workspace.getConfiguration('rust-analyzer');
|
||||||
|
let requireReloadMessage = null;
|
||||||
|
|
||||||
if (config.has('highlightingOn')) {
|
if (config.has('highlightingOn')) {
|
||||||
this.highlightingOn = config.get('highlightingOn') as boolean;
|
this.highlightingOn = config.get('highlightingOn') as boolean;
|
||||||
}
|
}
|
||||||
@ -74,19 +88,7 @@ export class Config {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.prevEnhancedTyping !== this.enableEnhancedTyping) {
|
if (this.prevEnhancedTyping !== this.enableEnhancedTyping) {
|
||||||
const reloadAction = 'Reload now';
|
requireReloadMessage = 'Changing enhanced typing setting requires a reload';
|
||||||
vscode.window
|
|
||||||
.showInformationMessage(
|
|
||||||
'Changing enhanced typing setting requires a reload',
|
|
||||||
reloadAction,
|
|
||||||
)
|
|
||||||
.then(selectedAction => {
|
|
||||||
if (selectedAction === reloadAction) {
|
|
||||||
vscode.commands.executeCommand(
|
|
||||||
'workbench.action.reloadWindow',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.prevEnhancedTyping = this.enableEnhancedTyping;
|
this.prevEnhancedTyping = this.enableEnhancedTyping;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,5 +155,47 @@ export class Config {
|
|||||||
if (config.has('withSysroot')) {
|
if (config.has('withSysroot')) {
|
||||||
this.withSysroot = config.get('withSysroot') || false;
|
this.withSysroot = config.get('withSysroot') || false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (config.has('cargoFeatures.noDefaultFeatures')) {
|
||||||
|
this.cargoFeatures.noDefaultFeatures = config.get(
|
||||||
|
'cargoFeatures.noDefaultFeatures',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (config.has('cargoFeatures.allFeatures')) {
|
||||||
|
this.cargoFeatures.allFeatures = config.get(
|
||||||
|
'cargoFeatures.allFeatures',
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (config.has('cargoFeatures.features')) {
|
||||||
|
this.cargoFeatures.features = config.get(
|
||||||
|
'cargoFeatures.features',
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.prevCargoFeatures !== null && (
|
||||||
|
this.cargoFeatures.allFeatures !== this.prevCargoFeatures.allFeatures ||
|
||||||
|
this.cargoFeatures.noDefaultFeatures !== this.prevCargoFeatures.noDefaultFeatures ||
|
||||||
|
this.cargoFeatures.features.length !== this.prevCargoFeatures.features.length ||
|
||||||
|
this.cargoFeatures.features.some((v, i) => v !== this.prevCargoFeatures!.features[i])
|
||||||
|
)) {
|
||||||
|
requireReloadMessage = 'Changing cargo features requires a reload';
|
||||||
|
}
|
||||||
|
this.prevCargoFeatures = { ...this.cargoFeatures };
|
||||||
|
|
||||||
|
if (requireReloadMessage !== null) {
|
||||||
|
const reloadAction = 'Reload now';
|
||||||
|
vscode.window
|
||||||
|
.showInformationMessage(requireReloadMessage, reloadAction)
|
||||||
|
.then(selectedAction => {
|
||||||
|
if (selectedAction === reloadAction) {
|
||||||
|
vscode.commands.executeCommand(
|
||||||
|
'workbench.action.reloadWindow',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ export class Server {
|
|||||||
useClientWatching: Server.config.useClientWatching,
|
useClientWatching: Server.config.useClientWatching,
|
||||||
featureFlags: Server.config.featureFlags,
|
featureFlags: Server.config.featureFlags,
|
||||||
withSysroot: Server.config.withSysroot,
|
withSysroot: Server.config.withSysroot,
|
||||||
|
cargoFeatures: Server.config.cargoFeatures,
|
||||||
},
|
},
|
||||||
traceOutputChannel,
|
traceOutputChannel,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user