Skip to content

Commit

Permalink
reimplement the world
Browse files Browse the repository at this point in the history
  • Loading branch information
ShuiRuTian committed Jun 1, 2023
1 parent a646439 commit 6ee2ebe
Show file tree
Hide file tree
Showing 27 changed files with 2,038 additions and 38 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion crates/ide-db/src/search.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ impl SearchScope {
}

/// Build a search scope spanning the entire crate graph of files.
fn crate_graph(db: &RootDatabase) -> SearchScope {
pub fn crate_graph(db: &RootDatabase) -> SearchScope {
let mut entries = NoHashHashMap::default();

let graph = db.crate_graph();
Expand Down
5 changes: 5 additions & 0 deletions crates/ide/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ mod parent_module;
mod references;
mod rename;
mod runnables;
mod test_items;
mod ssr;
mod static_index;
mod status;
Expand Down Expand Up @@ -522,6 +523,10 @@ impl Analysis {
self.with_db(|db| runnables::runnables(db, file_id))
}

pub fn test_runnables_in_file(&self, file_id: FileId) -> Cancellable<Vec<Runnable>> {
self.with_db(|db| test_items::test_runnables_in_file(db, file_id))
}

/// Returns the set of tests for the given file position.
pub fn related_tests(
&self,
Expand Down
26 changes: 14 additions & 12 deletions crates/ide/src/runnables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ fn parent_test_module(sema: &Semantics<'_, RootDatabase>, fn_def: &ast::Fn) -> O
let module = ast::Module::cast(node)?;
let module = sema.to_def(&module)?;

if has_test_function_or_multiple_test_submodules(sema, &module) {
if has_test_function_recursively(sema, &module) {
Some(module)
} else {
None
Expand Down Expand Up @@ -346,7 +346,7 @@ pub(crate) fn runnable_mod(
sema: &Semantics<'_, RootDatabase>,
def: hir::Module,
) -> Option<Runnable> {
if !has_test_function_or_multiple_test_submodules(sema, &def) {
if !has_test_function_recursively(sema, &def) {
return None;
}
let path =
Expand Down Expand Up @@ -388,7 +388,7 @@ fn runnable_mod_outline_definition(
sema: &Semantics<'_, RootDatabase>,
def: hir::Module,
) -> Option<Runnable> {
if !has_test_function_or_multiple_test_submodules(sema, &def) {
if !has_test_function_recursively(sema, &def) {
return None;
}
let path =
Expand Down Expand Up @@ -514,14 +514,16 @@ fn has_runnable_doc_test(attrs: &hir::Attrs) -> bool {
})
}

// Argue:
// Should we return when `number_of_test_submodules > 0` or `number_of_test_submodules > 1`?
// Support `> 1`:
// We could create runnables for modules with number_of_test_submodules > 0,
// but that bloats the runnables for no real benefit, since all tests can be run by the submodule already
fn has_test_function_or_multiple_test_submodules(
sema: &Semantics<'_, RootDatabase>,
module: &hir::Module,
) -> bool {
let mut number_of_test_submodules = 0;

// Support `> 0`:
// This will be helpful to rebuild the test item tree for VSCode, although it might should use another function or API.
// A bit faster
// Tell that there are some tests in the module when there is only declaration "mod SomeModule;"
fn has_test_function_recursively(sema: &Semantics<'_, RootDatabase>, module: &hir::Module) -> bool {
for item in module.declarations(sema.db) {
match item {
hir::ModuleDef::Function(f) => {
Expand All @@ -532,15 +534,15 @@ fn has_test_function_or_multiple_test_submodules(
}
}
hir::ModuleDef::Module(submodule) => {
if has_test_function_or_multiple_test_submodules(sema, &submodule) {
number_of_test_submodules += 1;
if has_test_function_recursively(sema, &submodule) {
return true;
}
}
_ => (),
}
}

number_of_test_submodules > 1
return false;
}

#[cfg(test)]
Expand Down
32 changes: 32 additions & 0 deletions crates/ide/src/test_items.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/// This mod is mainly to support vscode native test extension
/// please reference: https://code.visualstudio.com/api/extension-guides/testing
// It's a pretty rough implementation for now, reuse a lot of logic from runnable.
use ide_db::{
base_db::{FileId},
RootDatabase,
};

use crate::{runnables::runnables, Runnable, RunnableKind};

pub(crate) fn test_runnables_in_file(db: &RootDatabase, file_id: FileId) -> Vec<Runnable> {
return test_runnables_in_file_iter(db, file_id).collect();
}

fn test_runnables_in_file_iter(
db: &RootDatabase,
file_id: FileId,
) -> impl Iterator<Item = Runnable> {
// TODO: Maybe should extract another function with another optional RunnableKind,
// so that we could collect specfic Runnables on the fly, rather than fileter all agagin.
let all_runnables = runnables(db, file_id);
let tests = all_runnables.into_iter().filter(is_test_runnable);
return tests;

fn is_test_runnable(runnable: &Runnable) -> bool {
match runnable.kind {
RunnableKind::Test { .. } => true,
RunnableKind::TestMod { .. } => true,
_ => false,
}
}
}
26 changes: 23 additions & 3 deletions crates/project-model/src/cargo_workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,31 @@ use crate::{CfgOverrides, InvocationStrategy};
///
/// We use absolute paths here, `cargo metadata` guarantees to always produce
/// abs paths.
#[derive(Debug, Clone, Eq, PartialEq)]
#[derive(Debug, Clone)]
pub struct CargoWorkspace {
packages: Arena<PackageData>,
targets: Arena<TargetData>,
workspace_root: AbsPathBuf,
// Hack, this should be an implmentation detail, however,
// sometimes it's useful to let the client know the project
// structure.
// This property should only be used as JSON
pub origin_metadata: cargo_metadata::Metadata,
}

impl PartialEq for CargoWorkspace {
fn eq(&self, other: &Self) -> bool {
self.packages == other.packages
&& self.targets == other.targets
&& self.workspace_root == other.workspace_root
// Do not compare the origin data
// It's only used to be transfer as JSON
// && self.origin_metadata == other.origin_metadata
}
}

impl Eq for CargoWorkspace {}

impl ops::Index<Package> for CargoWorkspace {
type Output = PackageData;
fn index(&self, index: Package) -> &PackageData {
Expand Down Expand Up @@ -328,9 +346,11 @@ impl CargoWorkspace {
let mut pkg_by_id = FxHashMap::default();
let mut packages = Arena::default();
let mut targets = Arena::default();

// let tmp = Box::new(meta);
let ws_members = &meta.workspace_members;

let origin_metadata = meta.clone();

meta.packages.sort_by(|a, b| a.id.cmp(&b.id));
for meta_pkg in meta.packages {
let cargo_metadata::Package {
Expand Down Expand Up @@ -411,7 +431,7 @@ impl CargoWorkspace {
let workspace_root =
AbsPathBuf::assert(PathBuf::from(meta.workspace_root.into_os_string()));

CargoWorkspace { packages, targets, workspace_root }
CargoWorkspace { packages, targets, workspace_root, origin_metadata }
}

pub fn packages(&self) -> impl Iterator<Item = Package> + ExactSizeIterator + '_ {
Expand Down
1 change: 1 addition & 0 deletions crates/rust-analyzer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ path = "src/bin/main.rs"

[dependencies]
anyhow = "1.0.62"
cargo_metadata = "0.15.0"
crossbeam-channel = "0.5.5"
dissimilar = "1.0.4"
itertools = "0.10.5"
Expand Down
38 changes: 38 additions & 0 deletions crates/rust-analyzer/src/handlers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use ide::{
RunnableKind, SingleResolve, SourceChange, TextEdit,
};
use ide_db::SymbolKind;
use itertools::Itertools;
use lsp_server::ErrorCode;
use lsp_types::{
CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem,
Expand Down Expand Up @@ -804,6 +805,43 @@ pub(crate) fn handle_runnables(
Ok(res)
}

pub(crate) fn handle_cargo_workspaces(
snap: GlobalStateSnapshot,
_: (),
) -> Result<Vec<cargo_metadata::Metadata>> {
let _p = profile::span("cargo_workspaces");
let res = snap
.workspaces
.iter()
.filter_map(|workspace| {
if let ProjectWorkspace::Cargo { cargo, .. } = workspace {
Some(cargo.origin_metadata.clone())
} else {
None
}
})
.collect_vec();
Ok(res)
}

pub(crate) fn handle_test_runnables_in_file(
snap: GlobalStateSnapshot,
params: lsp_ext::TestRunnablesInFileParams,
) -> Result<Vec<lsp_ext::Runnable>> {
let _p = profile::span("handle_test_runnables_in_file");

let file_id = from_proto::file_id(&snap, &params.text_document.uri)?;
let test_runnables = snap.analysis.test_runnables_in_file(file_id)?;

let mut res = Vec::new();
for runnable in test_runnables {
let runnable = to_proto::runnable(&snap, runnable)?;
res.push(runnable);
}

Ok(res)
}

fn should_skip_for_offset(runnable: &Runnable, offset: Option<TextSize>) -> bool {
match offset {
None => false,
Expand Down
22 changes: 22 additions & 0 deletions crates/rust-analyzer/src/lsp_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,12 @@ pub struct RunnablesParams {
pub position: Option<Position>,
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct TestRunnablesInFileParams {
pub text_document: TextDocumentIdentifier,
}

#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Runnable {
Expand Down Expand Up @@ -290,6 +296,22 @@ pub struct TestInfo {
pub runnable: Runnable,
}

pub enum CargoWorkspaces{}

impl Request for CargoWorkspaces{
type Params = ();
type Result = Vec<cargo_metadata::Metadata>;
const METHOD: &'static str = "rust-analyzer/cargoWorkspaces";
}

pub enum TestRunnablesInFile {}

impl Request for TestRunnablesInFile {
type Params = TestRunnablesInFileParams;
type Result = Vec<Runnable>;
const METHOD: &'static str = "rust-analyzer/testRunnablesInFile";
}

#[derive(Serialize, Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct InlayHintsParams {
Expand Down
2 changes: 2 additions & 0 deletions crates/rust-analyzer/src/main_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,8 @@ impl GlobalState {
.on::<lsp_ext::ExpandMacro>(handlers::handle_expand_macro)
.on::<lsp_ext::ParentModule>(handlers::handle_parent_module)
.on::<lsp_ext::Runnables>(handlers::handle_runnables)
.on::<lsp_ext::CargoWorkspaces>(handlers:: handle_cargo_workspaces)
.on::<lsp_ext::TestRunnablesInFile>(handlers::handle_test_runnables_in_file)
.on::<lsp_ext::RelatedTests>(handlers::handle_related_tests)
.on::<lsp_ext::CodeActionRequest>(handlers::handle_code_action)
.on::<lsp_ext::CodeActionResolveRequest>(handlers::handle_code_action_resolve)
Expand Down
16 changes: 8 additions & 8 deletions editors/code/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion editors/code/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
"ovsx": "^0.5.2",
"prettier": "^2.7.1",
"tslib": "^2.4.0",
"typescript": "^4.7.4",
"typescript": "^5.0.0",
"vsce": "^2.9.2"
},
"activationEvents": [
Expand Down
7 changes: 3 additions & 4 deletions editors/code/src/debug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,6 @@ async function getDebugConfiguration(
ctx: Ctx,
runnable: ra.Runnable
): Promise<vscode.DebugConfiguration | undefined> {
const editor = ctx.activeRustEditor;
if (!editor) return;

const knownEngines: Record<string, DebugConfigProvider> = {
"vadimcn.vscode-lldb": getLldbDebugConfig,
Expand All @@ -91,7 +89,7 @@ async function getDebugConfiguration(
if (!debugEngine) {
await vscode.window.showErrorMessage(
`Install [CodeLLDB](https://marketplace.visualstudio.com/items?itemName=vadimcn.vscode-lldb)` +
` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`
` or [MS C++ tools](https://marketplace.visualstudio.com/items?itemName=ms-vscode.cpptools) extension for debugging.`
);
return;
}
Expand All @@ -109,7 +107,7 @@ async function getDebugConfiguration(
!isMultiFolderWorkspace || !runnable.args.workspaceRoot
? firstWorkspace
: workspaceFolders.find((w) => runnable.args.workspaceRoot?.includes(w.uri.fsPath)) ||
firstWorkspace;
firstWorkspace;

const wsFolder = path.normalize(workspace.uri.fsPath);
const workspaceQualifier = isMultiFolderWorkspace ? `:${workspace.name}` : "";
Expand Down Expand Up @@ -201,5 +199,6 @@ function getCppvsDebugConfig(
cwd: runnable.args.workspaceRoot,
sourceFileMap,
env,

};
}
Loading

0 comments on commit 6ee2ebe

Please sign in to comment.