mirror of
https://github.com/denoland/deno.git
synced 2025-01-18 11:53:59 -05:00
feat(lsp): add workspace symbol provider (#12787)
This commit is contained in:
parent
3abe31252e
commit
bf5657cd59
8 changed files with 303 additions and 24 deletions
|
@ -12,6 +12,7 @@ use lspower::lsp::CodeActionOptions;
|
||||||
use lspower::lsp::CodeActionProviderCapability;
|
use lspower::lsp::CodeActionProviderCapability;
|
||||||
use lspower::lsp::CodeLensOptions;
|
use lspower::lsp::CodeLensOptions;
|
||||||
use lspower::lsp::CompletionOptions;
|
use lspower::lsp::CompletionOptions;
|
||||||
|
use lspower::lsp::DocumentSymbolOptions;
|
||||||
use lspower::lsp::FoldingRangeProviderCapability;
|
use lspower::lsp::FoldingRangeProviderCapability;
|
||||||
use lspower::lsp::HoverProviderCapability;
|
use lspower::lsp::HoverProviderCapability;
|
||||||
use lspower::lsp::ImplementationProviderCapability;
|
use lspower::lsp::ImplementationProviderCapability;
|
||||||
|
@ -114,9 +115,13 @@ pub fn server_capabilities(
|
||||||
)),
|
)),
|
||||||
references_provider: Some(OneOf::Left(true)),
|
references_provider: Some(OneOf::Left(true)),
|
||||||
document_highlight_provider: Some(OneOf::Left(true)),
|
document_highlight_provider: Some(OneOf::Left(true)),
|
||||||
// TODO: Provide a label once https://github.com/gluon-lang/lsp-types/pull/207 is merged
|
document_symbol_provider: Some(OneOf::Right(DocumentSymbolOptions {
|
||||||
document_symbol_provider: Some(OneOf::Left(true)),
|
label: Some("Deno".to_string()),
|
||||||
workspace_symbol_provider: None,
|
work_done_progress_options: WorkDoneProgressOptions {
|
||||||
|
work_done_progress: None,
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
workspace_symbol_provider: Some(OneOf::Left(true)),
|
||||||
code_action_provider: Some(code_action_provider),
|
code_action_provider: Some(code_action_provider),
|
||||||
code_lens_provider: Some(CodeLensOptions {
|
code_lens_provider: Some(CodeLensOptions {
|
||||||
resolve_provider: Some(true),
|
resolve_provider: Some(true),
|
||||||
|
|
|
@ -2270,6 +2270,44 @@ impl Inner {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn symbol(
|
||||||
|
&mut self,
|
||||||
|
params: WorkspaceSymbolParams,
|
||||||
|
) -> LspResult<Option<Vec<SymbolInformation>>> {
|
||||||
|
let mark = self.performance.mark("symbol", Some(¶ms));
|
||||||
|
|
||||||
|
let req = tsc::RequestMethod::GetNavigateToItems {
|
||||||
|
search: params.query,
|
||||||
|
// this matches vscode's hard coded result count
|
||||||
|
max_result_count: Some(256),
|
||||||
|
file: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
let navigate_to_items: Vec<tsc::NavigateToItem> = self
|
||||||
|
.ts_server
|
||||||
|
.request(self.snapshot()?, req)
|
||||||
|
.await
|
||||||
|
.map_err(|err| {
|
||||||
|
error!("Failed request to tsserver: {}", err);
|
||||||
|
LspError::invalid_request()
|
||||||
|
})?;
|
||||||
|
|
||||||
|
let maybe_symbol_information = if navigate_to_items.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let mut symbol_information = Vec::new();
|
||||||
|
for item in navigate_to_items {
|
||||||
|
if let Some(info) = item.to_symbol_information(self).await {
|
||||||
|
symbol_information.push(info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(symbol_information)
|
||||||
|
};
|
||||||
|
|
||||||
|
self.performance.measure(mark);
|
||||||
|
Ok(maybe_symbol_information)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[lspower::async_trait]
|
#[lspower::async_trait]
|
||||||
|
@ -2481,6 +2519,13 @@ impl lspower::LanguageServer for LanguageServer {
|
||||||
) -> LspResult<Option<SignatureHelp>> {
|
) -> LspResult<Option<SignatureHelp>> {
|
||||||
self.0.lock().await.signature_help(params).await
|
self.0.lock().await.signature_help(params).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn symbol(
|
||||||
|
&self,
|
||||||
|
params: WorkspaceSymbolParams,
|
||||||
|
) -> LspResult<Option<Vec<SymbolInformation>>> {
|
||||||
|
self.0.lock().await.symbol(params).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// These are implementations of custom commands supported by the LSP
|
// These are implementations of custom commands supported by the LSP
|
||||||
|
|
|
@ -12,6 +12,9 @@ use lspower::lsp::SemanticTokens;
|
||||||
use lspower::lsp::SemanticTokensLegend;
|
use lspower::lsp::SemanticTokensLegend;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
|
|
||||||
|
pub(crate) const MODIFIER_MASK: u32 = 255;
|
||||||
|
pub(crate) const TYPE_OFFSET: u32 = 8;
|
||||||
|
|
||||||
enum TokenType {
|
enum TokenType {
|
||||||
Class = 0,
|
Class = 0,
|
||||||
Enum = 1,
|
Enum = 1,
|
||||||
|
@ -78,12 +81,12 @@ pub fn get_legend() -> SemanticTokensLegend {
|
||||||
token_types[TokenType::Method] = "method".into();
|
token_types[TokenType::Method] = "method".into();
|
||||||
|
|
||||||
let mut token_modifiers = vec![SemanticTokenModifier::from(""); 6];
|
let mut token_modifiers = vec![SemanticTokenModifier::from(""); 6];
|
||||||
token_modifiers[TokenModifier::Declaration] = "declaration".into();
|
|
||||||
token_modifiers[TokenModifier::Static] = "static".into();
|
|
||||||
token_modifiers[TokenModifier::Async] = "async".into();
|
token_modifiers[TokenModifier::Async] = "async".into();
|
||||||
|
token_modifiers[TokenModifier::Declaration] = "declaration".into();
|
||||||
token_modifiers[TokenModifier::Readonly] = "readonly".into();
|
token_modifiers[TokenModifier::Readonly] = "readonly".into();
|
||||||
token_modifiers[TokenModifier::DefaultLibrary] = "defaultLibrary".into();
|
token_modifiers[TokenModifier::Static] = "static".into();
|
||||||
token_modifiers[TokenModifier::Local] = "local".into();
|
token_modifiers[TokenModifier::Local] = "local".into();
|
||||||
|
token_modifiers[TokenModifier::DefaultLibrary] = "defaultLibrary".into();
|
||||||
|
|
||||||
SemanticTokensLegend {
|
SemanticTokensLegend {
|
||||||
token_types,
|
token_types,
|
||||||
|
@ -91,11 +94,6 @@ pub fn get_legend() -> SemanticTokensLegend {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum TsTokenEncodingConsts {
|
|
||||||
TypeOffset = 8,
|
|
||||||
ModifierMask = 255,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SemanticTokensBuilder {
|
pub struct SemanticTokensBuilder {
|
||||||
prev_line: u32,
|
prev_line: u32,
|
||||||
prev_char: u32,
|
prev_char: u32,
|
||||||
|
|
113
cli/lsp/tsc.rs
113
cli/lsp/tsc.rs
|
@ -9,8 +9,8 @@ use super::refactor::ALL_KNOWN_REFACTOR_ACTION_KINDS;
|
||||||
use super::refactor::EXTRACT_CONSTANT;
|
use super::refactor::EXTRACT_CONSTANT;
|
||||||
use super::refactor::EXTRACT_INTERFACE;
|
use super::refactor::EXTRACT_INTERFACE;
|
||||||
use super::refactor::EXTRACT_TYPE;
|
use super::refactor::EXTRACT_TYPE;
|
||||||
|
use super::semantic_tokens;
|
||||||
use super::semantic_tokens::SemanticTokensBuilder;
|
use super::semantic_tokens::SemanticTokensBuilder;
|
||||||
use super::semantic_tokens::TsTokenEncodingConsts;
|
|
||||||
use super::text;
|
use super::text;
|
||||||
use super::text::LineIndex;
|
use super::text::LineIndex;
|
||||||
use super::urls::INVALID_SPECIFIER;
|
use super::urls::INVALID_SPECIFIER;
|
||||||
|
@ -507,6 +507,9 @@ impl From<ScriptElementKind> for lsp::SymbolKind {
|
||||||
fn from(kind: ScriptElementKind) -> Self {
|
fn from(kind: ScriptElementKind) -> Self {
|
||||||
match kind {
|
match kind {
|
||||||
ScriptElementKind::ModuleElement => Self::Module,
|
ScriptElementKind::ModuleElement => Self::Module,
|
||||||
|
// this is only present in `getSymbolKind` in `workspaceSymbols` in
|
||||||
|
// vscode, but seems strange it isn't consistent.
|
||||||
|
ScriptElementKind::TypeElement => Self::Class,
|
||||||
ScriptElementKind::ClassElement => Self::Class,
|
ScriptElementKind::ClassElement => Self::Class,
|
||||||
ScriptElementKind::EnumElement => Self::Enum,
|
ScriptElementKind::EnumElement => Self::Enum,
|
||||||
ScriptElementKind::EnumMemberElement => Self::EnumMember,
|
ScriptElementKind::EnumMemberElement => Self::EnumMember,
|
||||||
|
@ -514,9 +517,12 @@ impl From<ScriptElementKind> for lsp::SymbolKind {
|
||||||
ScriptElementKind::IndexSignatureElement => Self::Method,
|
ScriptElementKind::IndexSignatureElement => Self::Method,
|
||||||
ScriptElementKind::CallSignatureElement => Self::Method,
|
ScriptElementKind::CallSignatureElement => Self::Method,
|
||||||
ScriptElementKind::MemberFunctionElement => Self::Method,
|
ScriptElementKind::MemberFunctionElement => Self::Method,
|
||||||
ScriptElementKind::MemberVariableElement => Self::Property,
|
// workspaceSymbols in vscode treats them as fields, which does seem more
|
||||||
ScriptElementKind::MemberGetAccessorElement => Self::Property,
|
// semantically correct while `fromProtocolScriptElementKind` treats them
|
||||||
ScriptElementKind::MemberSetAccessorElement => Self::Property,
|
// as properties.
|
||||||
|
ScriptElementKind::MemberVariableElement => Self::Field,
|
||||||
|
ScriptElementKind::MemberGetAccessorElement => Self::Field,
|
||||||
|
ScriptElementKind::MemberSetAccessorElement => Self::Field,
|
||||||
ScriptElementKind::VariableElement => Self::Variable,
|
ScriptElementKind::VariableElement => Self::Variable,
|
||||||
ScriptElementKind::LetElement => Self::Variable,
|
ScriptElementKind::LetElement => Self::Variable,
|
||||||
ScriptElementKind::ConstElement => Self::Variable,
|
ScriptElementKind::ConstElement => Self::Variable,
|
||||||
|
@ -672,6 +678,71 @@ impl DocumentSpan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub enum MatchKind {
|
||||||
|
#[serde(rename = "exact")]
|
||||||
|
Exact,
|
||||||
|
#[serde(rename = "prefix")]
|
||||||
|
Prefix,
|
||||||
|
#[serde(rename = "substring")]
|
||||||
|
Substring,
|
||||||
|
#[serde(rename = "camelCase")]
|
||||||
|
CamelCase,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct NavigateToItem {
|
||||||
|
name: String,
|
||||||
|
kind: ScriptElementKind,
|
||||||
|
kind_modifiers: String,
|
||||||
|
match_kind: MatchKind,
|
||||||
|
is_case_sensitive: bool,
|
||||||
|
file_name: String,
|
||||||
|
text_span: TextSpan,
|
||||||
|
container_name: Option<String>,
|
||||||
|
container_kind: ScriptElementKind,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NavigateToItem {
|
||||||
|
pub(crate) async fn to_symbol_information(
|
||||||
|
&self,
|
||||||
|
language_server: &mut language_server::Inner,
|
||||||
|
) -> Option<lsp::SymbolInformation> {
|
||||||
|
let specifier = normalize_specifier(&self.file_name).ok()?;
|
||||||
|
let asset_or_doc = language_server
|
||||||
|
.get_asset_or_document(&specifier)
|
||||||
|
.await
|
||||||
|
.ok()?;
|
||||||
|
let line_index = asset_or_doc.line_index();
|
||||||
|
let uri = language_server
|
||||||
|
.url_map
|
||||||
|
.normalize_specifier(&specifier)
|
||||||
|
.ok()?;
|
||||||
|
let range = self.text_span.to_range(line_index);
|
||||||
|
let location = lsp::Location { uri, range };
|
||||||
|
|
||||||
|
let mut tags: Option<Vec<lsp::SymbolTag>> = None;
|
||||||
|
let kind_modifiers = parse_kind_modifier(&self.kind_modifiers);
|
||||||
|
if kind_modifiers.contains("deprecated") {
|
||||||
|
tags = Some(vec![lsp::SymbolTag::Deprecated]);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The field `deprecated` is deprecated but SymbolInformation does not have
|
||||||
|
// a default, therefore we have to supply the deprecated deprecated
|
||||||
|
// field. It is like a bad version of Inception.
|
||||||
|
#[allow(deprecated)]
|
||||||
|
Some(lsp::SymbolInformation {
|
||||||
|
name: self.name.clone(),
|
||||||
|
kind: self.kind.clone().into(),
|
||||||
|
tags,
|
||||||
|
deprecated: None,
|
||||||
|
location,
|
||||||
|
container_name: self.container_name.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Deserialize)]
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct NavigationTree {
|
pub struct NavigationTree {
|
||||||
|
@ -752,6 +823,16 @@ impl NavigationTree {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let name = match self.kind {
|
||||||
|
ScriptElementKind::MemberGetAccessorElement => {
|
||||||
|
format!("(get) {}", self.text)
|
||||||
|
}
|
||||||
|
ScriptElementKind::MemberSetAccessorElement => {
|
||||||
|
format!("(set) {}", self.text)
|
||||||
|
}
|
||||||
|
_ => self.text.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
let mut tags: Option<Vec<lsp::SymbolTag>> = None;
|
let mut tags: Option<Vec<lsp::SymbolTag>> = None;
|
||||||
let kind_modifiers = parse_kind_modifier(&self.kind_modifiers);
|
let kind_modifiers = parse_kind_modifier(&self.kind_modifiers);
|
||||||
if kind_modifiers.contains("deprecated") {
|
if kind_modifiers.contains("deprecated") {
|
||||||
|
@ -769,7 +850,7 @@ impl NavigationTree {
|
||||||
// field. It is like a bad version of Inception.
|
// field. It is like a bad version of Inception.
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
document_symbols.push(lsp::DocumentSymbol {
|
document_symbols.push(lsp::DocumentSymbol {
|
||||||
name: self.text.clone(),
|
name,
|
||||||
kind: self.kind.clone().into(),
|
kind: self.kind.clone().into(),
|
||||||
range: span.to_range(line_index.clone()),
|
range: span.to_range(line_index.clone()),
|
||||||
selection_range: selection_span.to_range(line_index.clone()),
|
selection_range: selection_span.to_range(line_index.clone()),
|
||||||
|
@ -1166,11 +1247,12 @@ impl Classifications {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_token_type_from_classification(ts_classification: u32) -> u32 {
|
fn get_token_type_from_classification(ts_classification: u32) -> u32 {
|
||||||
(ts_classification >> (TsTokenEncodingConsts::TypeOffset as u32)) - 1
|
assert!(ts_classification > semantic_tokens::MODIFIER_MASK);
|
||||||
|
(ts_classification >> semantic_tokens::TYPE_OFFSET) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_token_modifier_from_classification(ts_classification: u32) -> u32 {
|
fn get_token_modifier_from_classification(ts_classification: u32) -> u32 {
|
||||||
ts_classification & (TsTokenEncodingConsts::ModifierMask as u32)
|
ts_classification & semantic_tokens::MODIFIER_MASK
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2667,6 +2749,12 @@ pub enum RequestMethod {
|
||||||
GetEncodedSemanticClassifications((ModuleSpecifier, TextSpan)),
|
GetEncodedSemanticClassifications((ModuleSpecifier, TextSpan)),
|
||||||
/// Get implementation information for a specific position.
|
/// Get implementation information for a specific position.
|
||||||
GetImplementation((ModuleSpecifier, u32)),
|
GetImplementation((ModuleSpecifier, u32)),
|
||||||
|
/// Get "navigate to" items, which are converted to workspace symbols
|
||||||
|
GetNavigateToItems {
|
||||||
|
search: String,
|
||||||
|
max_result_count: Option<u32>,
|
||||||
|
file: Option<String>,
|
||||||
|
},
|
||||||
/// Get a "navigation tree" for a specifier.
|
/// Get a "navigation tree" for a specifier.
|
||||||
GetNavigationTree(ModuleSpecifier),
|
GetNavigationTree(ModuleSpecifier),
|
||||||
/// Get outlining spans for a specifier.
|
/// Get outlining spans for a specifier.
|
||||||
|
@ -2808,6 +2896,17 @@ impl RequestMethod {
|
||||||
"specifier": state.denormalize_specifier(specifier),
|
"specifier": state.denormalize_specifier(specifier),
|
||||||
"position": position,
|
"position": position,
|
||||||
}),
|
}),
|
||||||
|
RequestMethod::GetNavigateToItems {
|
||||||
|
search,
|
||||||
|
max_result_count,
|
||||||
|
file,
|
||||||
|
} => json!({
|
||||||
|
"id": id,
|
||||||
|
"method": "getNavigateToItems",
|
||||||
|
"search": search,
|
||||||
|
"maxResultCount": max_result_count,
|
||||||
|
"file": file,
|
||||||
|
}),
|
||||||
RequestMethod::GetNavigationTree(specifier) => json!({
|
RequestMethod::GetNavigationTree(specifier) => json!({
|
||||||
"id": id,
|
"id": id,
|
||||||
"method": "getNavigationTree",
|
"method": "getNavigationTree",
|
||||||
|
|
|
@ -3775,6 +3775,120 @@ fn lsp_configuration_did_change() {
|
||||||
shutdown(&mut client);
|
shutdown(&mut client);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn lsp_workspace_symbol() {
|
||||||
|
let mut client = init("initialize_params.json");
|
||||||
|
did_open(
|
||||||
|
&mut client,
|
||||||
|
json!({
|
||||||
|
"textDocument": {
|
||||||
|
"uri": "file:///a/file.ts",
|
||||||
|
"languageId": "typescript",
|
||||||
|
"version": 1,
|
||||||
|
"text": "export class A {\n fieldA: string;\n fieldB: string;\n}\n",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
did_open(
|
||||||
|
&mut client,
|
||||||
|
json!({
|
||||||
|
"textDocument": {
|
||||||
|
"uri": "file:///a/file_01.ts",
|
||||||
|
"languageId": "typescript",
|
||||||
|
"version": 1,
|
||||||
|
"text": "export class B {\n fieldC: string;\n fieldD: string;\n}\n",
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
let (maybe_res, maybe_err) = client
|
||||||
|
.write_request(
|
||||||
|
"workspace/symbol",
|
||||||
|
json!({
|
||||||
|
"query": "field"
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
assert!(maybe_err.is_none());
|
||||||
|
assert_eq!(
|
||||||
|
maybe_res,
|
||||||
|
Some(json!([
|
||||||
|
{
|
||||||
|
"name": "fieldA",
|
||||||
|
"kind": 8,
|
||||||
|
"location": {
|
||||||
|
"uri": "file:///a/file.ts",
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 2
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerName": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fieldB",
|
||||||
|
"kind": 8,
|
||||||
|
"location": {
|
||||||
|
"uri": "file:///a/file.ts",
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 2,
|
||||||
|
"character": 2
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 2,
|
||||||
|
"character": 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerName": "A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fieldC",
|
||||||
|
"kind": 8,
|
||||||
|
"location": {
|
||||||
|
"uri": "file:///a/file_01.ts",
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 2
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 1,
|
||||||
|
"character": 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerName": "B"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "fieldD",
|
||||||
|
"kind": 8,
|
||||||
|
"location": {
|
||||||
|
"uri": "file:///a/file_01.ts",
|
||||||
|
"range": {
|
||||||
|
"start": {
|
||||||
|
"line": 2,
|
||||||
|
"character": 2
|
||||||
|
},
|
||||||
|
"end": {
|
||||||
|
"line": 2,
|
||||||
|
"character": 17
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"containerName": "B"
|
||||||
|
}
|
||||||
|
]))
|
||||||
|
);
|
||||||
|
shutdown(&mut client);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn lsp_code_actions_ignore_lint() {
|
fn lsp_code_actions_ignore_lint() {
|
||||||
let mut client = init("initialize_params.json");
|
let mut client = init("initialize_params.json");
|
||||||
|
|
|
@ -148,7 +148,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "staticBar",
|
"name": "staticBar",
|
||||||
"kind": 7,
|
"kind": 8,
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 11,
|
"line": 11,
|
||||||
|
@ -171,8 +171,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "value",
|
"name": "(get) value",
|
||||||
"kind": 7,
|
"kind": 8,
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 9,
|
"line": 9,
|
||||||
|
@ -195,8 +195,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "value",
|
"name": "(set) value",
|
||||||
"kind": 7,
|
"kind": 8,
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 10,
|
"line": 10,
|
||||||
|
@ -220,7 +220,7 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "x",
|
"name": "x",
|
||||||
"kind": 7,
|
"kind": 8,
|
||||||
"range": {
|
"range": {
|
||||||
"start": {
|
"start": {
|
||||||
"line": 5,
|
"line": 5,
|
||||||
|
|
|
@ -743,6 +743,16 @@ delete Object.prototype.__proto__;
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
case "getNavigateToItems": {
|
||||||
|
return respond(
|
||||||
|
id,
|
||||||
|
languageService.getNavigateToItems(
|
||||||
|
request.search,
|
||||||
|
request.maxResultCount,
|
||||||
|
request.fileName,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
case "getNavigationTree": {
|
case "getNavigationTree": {
|
||||||
return respond(
|
return respond(
|
||||||
id,
|
id,
|
||||||
|
|
8
cli/tsc/compiler.d.ts
vendored
8
cli/tsc/compiler.d.ts
vendored
|
@ -58,6 +58,7 @@ declare global {
|
||||||
| GetDocumentHighlightsRequest
|
| GetDocumentHighlightsRequest
|
||||||
| GetEncodedSemanticClassifications
|
| GetEncodedSemanticClassifications
|
||||||
| GetImplementationRequest
|
| GetImplementationRequest
|
||||||
|
| GetNavigateToItems
|
||||||
| GetNavigationTree
|
| GetNavigationTree
|
||||||
| GetOutliningSpans
|
| GetOutliningSpans
|
||||||
| GetQuickInfoRequest
|
| GetQuickInfoRequest
|
||||||
|
@ -173,6 +174,13 @@ declare global {
|
||||||
position: number;
|
position: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface GetNavigateToItems extends BaseLanguageServerRequest {
|
||||||
|
method: "getNavigateToItems";
|
||||||
|
search: string;
|
||||||
|
maxResultCount?: number;
|
||||||
|
fileName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface GetNavigationTree extends BaseLanguageServerRequest {
|
interface GetNavigationTree extends BaseLanguageServerRequest {
|
||||||
method: "getNavigationTree";
|
method: "getNavigationTree";
|
||||||
specifier: string;
|
specifier: string;
|
||||||
|
|
Loading…
Add table
Reference in a new issue