mirror of
https://github.com/nushell/nushell.git
synced 2025-05-31 23:26:11 +02:00
perf: early skip for special calls
This commit is contained in:
parent
7915e14463
commit
49dc162f08
@ -2,7 +2,7 @@ use crate::Id;
|
|||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::{Argument, Block, Call, Expr, Expression, FindMapResult, ListItem, PathMember, Traverse},
|
ast::{Argument, Block, Call, Expr, Expression, FindMapResult, ListItem, PathMember, Traverse},
|
||||||
engine::StateWorkingSet,
|
engine::StateWorkingSet,
|
||||||
Span,
|
ModuleId, Span,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@ -58,6 +58,12 @@ fn try_find_id_in_def(
|
|||||||
location: Option<&usize>,
|
location: Option<&usize>,
|
||||||
id_ref: Option<&Id>,
|
id_ref: Option<&Id>,
|
||||||
) -> Option<(Id, Span)> {
|
) -> Option<(Id, Span)> {
|
||||||
|
// skip if the id to search is not a declaration id
|
||||||
|
if let Some(id_ref) = id_ref {
|
||||||
|
if !matches!(id_ref, Id::Declaration(_)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut span = None;
|
let mut span = None;
|
||||||
for arg in call.arguments.iter() {
|
for arg in call.arguments.iter() {
|
||||||
if location.is_none_or(|pos| arg.span().contains(*pos)) {
|
if location.is_none_or(|pos| arg.span().contains(*pos)) {
|
||||||
@ -108,6 +114,12 @@ fn try_find_id_in_mod(
|
|||||||
location: Option<&usize>,
|
location: Option<&usize>,
|
||||||
id_ref: Option<&Id>,
|
id_ref: Option<&Id>,
|
||||||
) -> Option<(Id, Span)> {
|
) -> Option<(Id, Span)> {
|
||||||
|
// skip if the id to search is not a module id
|
||||||
|
if let Some(id_ref) = id_ref {
|
||||||
|
if !matches!(id_ref, Id::Module(_, _)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
let check_location = |span: &Span| location.is_none_or(|pos| span.contains(*pos));
|
let check_location = |span: &Span| location.is_none_or(|pos| span.contains(*pos));
|
||||||
|
|
||||||
call.arguments.first().and_then(|arg| {
|
call.arguments.first().and_then(|arg| {
|
||||||
@ -117,7 +129,24 @@ fn try_find_id_in_mod(
|
|||||||
match arg {
|
match arg {
|
||||||
Argument::Positional(expr) => {
|
Argument::Positional(expr) => {
|
||||||
let name = expr.as_string()?;
|
let name = expr.as_string()?;
|
||||||
let module_id = working_set.find_module(name.as_bytes())?;
|
let module_id = working_set.find_module(name.as_bytes()).or_else(|| {
|
||||||
|
// in case the module is hidden
|
||||||
|
let mut any_id = true;
|
||||||
|
let mut id_num_ref = 0;
|
||||||
|
if let Some(Id::Module(id_ref, _)) = id_ref {
|
||||||
|
any_id = false;
|
||||||
|
id_num_ref = id_ref.get();
|
||||||
|
}
|
||||||
|
(0..working_set.num_modules())
|
||||||
|
.find(|id| {
|
||||||
|
(any_id || id_num_ref == *id)
|
||||||
|
&& working_set
|
||||||
|
.get_module(ModuleId::new(*id))
|
||||||
|
.span
|
||||||
|
.is_some_and(|mod_span| call.span().contains_span(mod_span))
|
||||||
|
})
|
||||||
|
.map(ModuleId::new)
|
||||||
|
})?;
|
||||||
let found_id = Id::Module(module_id, name.as_bytes().to_vec());
|
let found_id = Id::Module(module_id, name.as_bytes().to_vec());
|
||||||
let found_span = strip_quotes(arg.span(), working_set).1;
|
let found_span = strip_quotes(arg.span(), working_set).1;
|
||||||
id_ref
|
id_ref
|
||||||
@ -139,7 +168,7 @@ fn try_find_id_in_use(
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
location: Option<&usize>,
|
location: Option<&usize>,
|
||||||
id: Option<&Id>,
|
id_ref: Option<&Id>,
|
||||||
) -> Option<(Id, Span)> {
|
) -> Option<(Id, Span)> {
|
||||||
// NOTE: `call.parser_info` contains a 'import_pattern' field for `use`/`hide` commands,
|
// NOTE: `call.parser_info` contains a 'import_pattern' field for `use`/`hide` commands,
|
||||||
// If it's missing, usually it means the PWD env is not correctly set,
|
// If it's missing, usually it means the PWD env is not correctly set,
|
||||||
@ -155,7 +184,7 @@ fn try_find_id_in_use(
|
|||||||
|
|
||||||
let find_by_name = |name: &[u8]| {
|
let find_by_name = |name: &[u8]| {
|
||||||
let module = working_set.get_module(module_id);
|
let module = working_set.get_module(module_id);
|
||||||
match id {
|
match id_ref {
|
||||||
Some(Id::Variable(var_id_ref)) => module
|
Some(Id::Variable(var_id_ref)) => module
|
||||||
.constants
|
.constants
|
||||||
.get(name)
|
.get(name)
|
||||||
@ -196,7 +225,7 @@ fn try_find_id_in_use(
|
|||||||
let module_name = call.arguments.first()?;
|
let module_name = call.arguments.first()?;
|
||||||
let span = module_name.span();
|
let span = module_name.span();
|
||||||
let (span_content, clean_span) = strip_quotes(span, working_set);
|
let (span_content, clean_span) = strip_quotes(span, working_set);
|
||||||
if let Some(Id::Module(id_ref, name_ref)) = id {
|
if let Some(Id::Module(id_ref, name_ref)) = id_ref {
|
||||||
// still need to check the rest, if id not matched
|
// still need to check the rest, if id not matched
|
||||||
if module_id == *id_ref && *name_ref == span_content {
|
if module_id == *id_ref && *name_ref == span_content {
|
||||||
return Some((Id::Module(module_id, span_content.to_vec()), clean_span));
|
return Some((Id::Module(module_id, span_content.to_vec()), clean_span));
|
||||||
@ -262,8 +291,14 @@ fn try_find_id_in_overlay(
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
working_set: &StateWorkingSet,
|
working_set: &StateWorkingSet,
|
||||||
location: Option<&usize>,
|
location: Option<&usize>,
|
||||||
id: Option<&Id>,
|
id_ref: Option<&Id>,
|
||||||
) -> Option<(Id, Span)> {
|
) -> Option<(Id, Span)> {
|
||||||
|
// skip if the id to search is not a module id
|
||||||
|
if let Some(id_ref) = id_ref {
|
||||||
|
if !matches!(id_ref, Id::Module(_, _)) {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
let check_location = |span: &Span| location.is_none_or(|pos| span.contains(*pos));
|
let check_location = |span: &Span| location.is_none_or(|pos| span.contains(*pos));
|
||||||
let module_from_parser_info = |span: Span, name: &str| {
|
let module_from_parser_info = |span: Span, name: &str| {
|
||||||
let Expression {
|
let Expression {
|
||||||
@ -274,7 +309,8 @@ fn try_find_id_in_overlay(
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let found_id = Id::Module(*module_id, name.as_bytes().to_vec());
|
let found_id = Id::Module(*module_id, name.as_bytes().to_vec());
|
||||||
id.is_none_or(|id_r| found_id == *id_r)
|
id_ref
|
||||||
|
.is_none_or(|id_r| found_id == *id_r)
|
||||||
.then_some((found_id, strip_quotes(span, working_set).1))
|
.then_some((found_id, strip_quotes(span, working_set).1))
|
||||||
};
|
};
|
||||||
// NOTE: `overlay_expr` doesn't exist for `overlay hide`
|
// NOTE: `overlay_expr` doesn't exist for `overlay hide`
|
||||||
@ -283,7 +319,8 @@ fn try_find_id_in_overlay(
|
|||||||
working_set.find_overlay(name.as_bytes())?.origin,
|
working_set.find_overlay(name.as_bytes())?.origin,
|
||||||
name.as_bytes().to_vec(),
|
name.as_bytes().to_vec(),
|
||||||
);
|
);
|
||||||
id.is_none_or(|id_r| found_id == *id_r)
|
id_ref
|
||||||
|
.is_none_or(|id_r| found_id == *id_r)
|
||||||
.then_some((found_id, strip_quotes(span, working_set).1))
|
.then_some((found_id, strip_quotes(span, working_set).1))
|
||||||
};
|
};
|
||||||
|
|
||||||
|
1
tests/fixtures/lsp/workspace/foo.nu
vendored
1
tests/fixtures/lsp/workspace/foo.nu
vendored
@ -7,6 +7,7 @@ export def foooo [
|
|||||||
export def "foo str" [] { "foo" }
|
export def "foo str" [] { "foo" }
|
||||||
|
|
||||||
export module "mod name" {
|
export module "mod name" {
|
||||||
|
# cmt
|
||||||
export module "sub module" {
|
export module "sub module" {
|
||||||
export def "cmd name" [] { }
|
export def "cmd name" [] { }
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user