mirror of
https://github.com/denoland/deno.git
synced 2024-12-21 23:04:45 -05:00
parent
6d2656fd56
commit
7d78f58187
11 changed files with 628 additions and 2 deletions
|
@ -141,6 +141,6 @@ pub fn server_capabilities(
|
|||
"denoConfigTasks": true,
|
||||
"testingApi":true,
|
||||
})),
|
||||
inlay_hint_provider: None,
|
||||
inlay_hint_provider: Some(OneOf::Left(true)),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,101 @@ impl Default for CompletionSettings {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsSettings {
|
||||
#[serde(default)]
|
||||
pub parameter_names: InlayHintsParamNamesOptions,
|
||||
#[serde(default)]
|
||||
pub parameter_types: InlayHintsParamTypesOptions,
|
||||
#[serde(default)]
|
||||
pub variable_types: InlayHintsVarTypesOptions,
|
||||
#[serde(default)]
|
||||
pub property_declaration_types: InlayHintsPropDeclTypesOptions,
|
||||
#[serde(default)]
|
||||
pub function_like_return_types: InlayHintsFuncLikeReturnTypesOptions,
|
||||
#[serde(default)]
|
||||
pub enum_member_values: InlayHintsEnumMemberValuesOptions,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsParamNamesOptions {
|
||||
#[serde(default)]
|
||||
pub enabled: InlayHintsParamNamesEnabled,
|
||||
#[serde(default = "is_true")]
|
||||
pub suppress_when_argument_matches_name: bool,
|
||||
}
|
||||
|
||||
impl Default for InlayHintsParamNamesOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: InlayHintsParamNamesEnabled::None,
|
||||
suppress_when_argument_matches_name: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub enum InlayHintsParamNamesEnabled {
|
||||
None,
|
||||
Literals,
|
||||
All,
|
||||
}
|
||||
|
||||
impl Default for InlayHintsParamNamesEnabled {
|
||||
fn default() -> Self {
|
||||
Self::None
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsParamTypesOptions {
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsVarTypesOptions {
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
#[serde(default = "is_true")]
|
||||
pub suppress_when_argument_matches_name: bool,
|
||||
}
|
||||
|
||||
impl Default for InlayHintsVarTypesOptions {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
enabled: false,
|
||||
suppress_when_argument_matches_name: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsPropDeclTypesOptions {
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsFuncLikeReturnTypesOptions {
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHintsEnumMemberValuesOptions {
|
||||
#[serde(default)]
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ImportCompletionSettings {
|
||||
|
@ -202,6 +297,9 @@ pub struct WorkspaceSettings {
|
|||
#[serde(default)]
|
||||
pub code_lens: CodeLensSettings,
|
||||
|
||||
#[serde(default)]
|
||||
pub inlay_hints: InlayHintsSettings,
|
||||
|
||||
/// A flag that indicates if internal debug logging should be made available.
|
||||
#[serde(default)]
|
||||
pub internal_debug: bool,
|
||||
|
@ -238,6 +336,19 @@ impl WorkspaceSettings {
|
|||
pub fn enabled_code_lens(&self) -> bool {
|
||||
self.code_lens.implementations || self.code_lens.references
|
||||
}
|
||||
|
||||
/// Determine if any inlay hints are enabled. This allows short circuiting
|
||||
/// when there are no inlay hints enabled.
|
||||
pub fn enabled_inlay_hints(&self) -> bool {
|
||||
!matches!(
|
||||
self.inlay_hints.parameter_names.enabled,
|
||||
InlayHintsParamNamesEnabled::None
|
||||
) || self.inlay_hints.parameter_types.enabled
|
||||
|| self.inlay_hints.variable_types.enabled
|
||||
|| self.inlay_hints.property_declaration_types.enabled
|
||||
|| self.inlay_hints.function_like_return_types.enabled
|
||||
|| self.inlay_hints.enum_member_values.enabled
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
@ -566,6 +677,26 @@ mod tests {
|
|||
references_all_functions: false,
|
||||
test: true,
|
||||
},
|
||||
inlay_hints: InlayHintsSettings {
|
||||
parameter_names: InlayHintsParamNamesOptions {
|
||||
enabled: InlayHintsParamNamesEnabled::None,
|
||||
suppress_when_argument_matches_name: true
|
||||
},
|
||||
parameter_types: InlayHintsParamTypesOptions { enabled: false },
|
||||
variable_types: InlayHintsVarTypesOptions {
|
||||
enabled: false,
|
||||
suppress_when_argument_matches_name: true
|
||||
},
|
||||
property_declaration_types: InlayHintsPropDeclTypesOptions {
|
||||
enabled: false
|
||||
},
|
||||
function_like_return_types: InlayHintsFuncLikeReturnTypesOptions {
|
||||
enabled: false
|
||||
},
|
||||
enum_member_values: InlayHintsEnumMemberValuesOptions {
|
||||
enabled: false
|
||||
},
|
||||
},
|
||||
internal_debug: false,
|
||||
lint: true,
|
||||
suggest: CompletionSettings {
|
||||
|
|
|
@ -196,6 +196,13 @@ impl LanguageServer {
|
|||
}
|
||||
}
|
||||
|
||||
pub async fn inlay_hint(
|
||||
&self,
|
||||
params: InlayHintParams,
|
||||
) -> LspResult<Option<Vec<InlayHint>>> {
|
||||
self.0.lock().await.inlay_hint(params).await
|
||||
}
|
||||
|
||||
pub async fn virtual_text_document(
|
||||
&self,
|
||||
params: Option<Value>,
|
||||
|
@ -2896,6 +2903,50 @@ impl Inner {
|
|||
)
|
||||
}
|
||||
|
||||
async fn inlay_hint(
|
||||
&self,
|
||||
params: InlayHintParams,
|
||||
) -> LspResult<Option<Vec<InlayHint>>> {
|
||||
let specifier = self.url_map.normalize_url(¶ms.text_document.uri);
|
||||
let workspace_settings = self.config.get_workspace_settings();
|
||||
if !self.is_diagnosable(&specifier)
|
||||
|| !self.config.specifier_enabled(&specifier)
|
||||
|| !workspace_settings.enabled_inlay_hints()
|
||||
{
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let mark = self.performance.mark("inlay_hint", Some(¶ms));
|
||||
let asset_or_doc = self.get_asset_or_document(&specifier)?;
|
||||
let line_index = asset_or_doc.line_index();
|
||||
let range = tsc::TextSpan::from_range(¶ms.range, line_index.clone())
|
||||
.map_err(|err| {
|
||||
error!("Failed to convert range to text_span: {}", err);
|
||||
LspError::internal_error()
|
||||
})?;
|
||||
let req = tsc::RequestMethod::ProvideInlayHints((
|
||||
specifier.clone(),
|
||||
range,
|
||||
(&workspace_settings).into(),
|
||||
));
|
||||
let maybe_inlay_hints: Option<Vec<tsc::InlayHint>> = self
|
||||
.ts_server
|
||||
.request(self.snapshot(), req)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Unable to get inlay hints: {}", err);
|
||||
LspError::internal_error()
|
||||
})?;
|
||||
let maybe_inlay_hints = maybe_inlay_hints.map(|hints| {
|
||||
hints
|
||||
.iter()
|
||||
.map(|hint| hint.to_lsp(line_index.clone()))
|
||||
.collect()
|
||||
});
|
||||
self.performance.measure(mark);
|
||||
Ok(maybe_inlay_hints)
|
||||
}
|
||||
|
||||
async fn reload_import_registries(&mut self) -> LspResult<Option<Value>> {
|
||||
fs_util::remove_dir_all_if_exists(&self.module_registries_location)
|
||||
.await
|
||||
|
|
|
@ -11,6 +11,9 @@ pub const RELOAD_IMPORT_REGISTRIES_REQUEST: &str =
|
|||
"deno/reloadImportRegistries";
|
||||
pub const VIRTUAL_TEXT_DOCUMENT: &str = "deno/virtualTextDocument";
|
||||
|
||||
// While lsp_types supports inlay hints currently, tower_lsp does not.
|
||||
pub const INLAY_HINT: &str = "textDocument/inlayHint";
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct CacheParams {
|
||||
|
|
|
@ -58,6 +58,7 @@ pub async fn start() -> Result<(), AnyError> {
|
|||
lsp_custom::VIRTUAL_TEXT_DOCUMENT,
|
||||
LanguageServer::virtual_text_document,
|
||||
)
|
||||
.custom_method(lsp_custom::INLAY_HINT, LanguageServer::inlay_hint)
|
||||
.finish();
|
||||
|
||||
Server::new(stdin, stdout, socket).serve(service).await;
|
||||
|
|
|
@ -288,6 +288,7 @@ pub fn get_repl_workspace_settings() -> WorkspaceSettings {
|
|||
cache: None,
|
||||
import_map: None,
|
||||
code_lens: Default::default(),
|
||||
inlay_hints: Default::default(),
|
||||
internal_debug: false,
|
||||
lint: false,
|
||||
tls_certificate: None,
|
||||
|
|
113
cli/lsp/tsc.rs
113
cli/lsp/tsc.rs
|
@ -618,6 +618,15 @@ pub struct TextSpan {
|
|||
}
|
||||
|
||||
impl TextSpan {
|
||||
pub fn from_range(
|
||||
range: &lsp::Range,
|
||||
line_index: Arc<LineIndex>,
|
||||
) -> Result<Self, AnyError> {
|
||||
let start = line_index.offset_tsc(range.start)?;
|
||||
let length = line_index.offset_tsc(range.end)? - start;
|
||||
Ok(Self { start, length })
|
||||
}
|
||||
|
||||
pub fn to_range(&self, line_index: Arc<LineIndex>) -> lsp::Range {
|
||||
lsp::Range {
|
||||
start: line_index.position_tsc(self.start.into()),
|
||||
|
@ -932,6 +941,48 @@ impl NavigateToItem {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
pub enum InlayHintKind {
|
||||
Type,
|
||||
Parameter,
|
||||
Enum,
|
||||
}
|
||||
|
||||
impl InlayHintKind {
|
||||
pub fn to_lsp(&self) -> Option<lsp::InlayHintKind> {
|
||||
match self {
|
||||
Self::Enum => None,
|
||||
Self::Parameter => Some(lsp::InlayHintKind::PARAMETER),
|
||||
Self::Type => Some(lsp::InlayHintKind::TYPE),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct InlayHint {
|
||||
pub text: String,
|
||||
pub position: u32,
|
||||
pub kind: InlayHintKind,
|
||||
pub whitespace_before: Option<bool>,
|
||||
pub whitespace_after: Option<bool>,
|
||||
}
|
||||
|
||||
impl InlayHint {
|
||||
pub fn to_lsp(&self, line_index: Arc<LineIndex>) -> lsp::InlayHint {
|
||||
lsp::InlayHint {
|
||||
position: line_index.position_tsc(self.position.into()),
|
||||
label: lsp::InlayHintLabel::String(self.text.clone()),
|
||||
kind: self.kind.to_lsp(),
|
||||
padding_left: self.whitespace_before,
|
||||
padding_right: self.whitespace_after,
|
||||
text_edits: None,
|
||||
tooltip: None,
|
||||
data: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct NavigationTree {
|
||||
|
@ -2830,6 +2881,18 @@ pub enum IncludeInlayParameterNameHints {
|
|||
All,
|
||||
}
|
||||
|
||||
impl From<&config::InlayHintsParamNamesEnabled>
|
||||
for IncludeInlayParameterNameHints
|
||||
{
|
||||
fn from(setting: &config::InlayHintsParamNamesEnabled) -> Self {
|
||||
match setting {
|
||||
config::InlayHintsParamNamesEnabled::All => Self::All,
|
||||
config::InlayHintsParamNamesEnabled::Literals => Self::Literals,
|
||||
config::InlayHintsParamNamesEnabled::None => Self::None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "kebab-case")]
|
||||
#[allow(dead_code)]
|
||||
|
@ -2910,6 +2973,8 @@ pub struct UserPreferences {
|
|||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub include_inlay_variable_type_hints: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub include_inlay_variable_type_hints_when_type_matches_name: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub include_inlay_property_declaration_type_hints: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub include_inlay_function_like_return_type_hints: Option<bool>,
|
||||
|
@ -2921,6 +2986,43 @@ pub struct UserPreferences {
|
|||
pub auto_import_file_exclude_patterns: Option<Vec<String>>,
|
||||
}
|
||||
|
||||
impl From<&config::WorkspaceSettings> for UserPreferences {
|
||||
fn from(workspace_settings: &config::WorkspaceSettings) -> Self {
|
||||
let inlay_hints = &workspace_settings.inlay_hints;
|
||||
Self {
|
||||
include_inlay_parameter_name_hints: Some(
|
||||
(&inlay_hints.parameter_names.enabled).into(),
|
||||
),
|
||||
include_inlay_parameter_name_hints_when_argument_matches_name: Some(
|
||||
inlay_hints
|
||||
.parameter_names
|
||||
.suppress_when_argument_matches_name,
|
||||
),
|
||||
include_inlay_function_parameter_type_hints: Some(
|
||||
inlay_hints.parameter_types.enabled,
|
||||
),
|
||||
include_inlay_variable_type_hints: Some(
|
||||
inlay_hints.variable_types.enabled,
|
||||
),
|
||||
include_inlay_variable_type_hints_when_type_matches_name: Some(
|
||||
inlay_hints
|
||||
.variable_types
|
||||
.suppress_when_argument_matches_name,
|
||||
),
|
||||
include_inlay_property_declaration_type_hints: Some(
|
||||
inlay_hints.property_declaration_types.enabled,
|
||||
),
|
||||
include_inlay_function_like_return_type_hints: Some(
|
||||
inlay_hints.function_like_return_types.enabled,
|
||||
),
|
||||
include_inlay_enum_member_value_hints: Some(
|
||||
inlay_hints.enum_member_values.enabled,
|
||||
),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SignatureHelpItemsOptions {
|
||||
|
@ -3053,6 +3155,8 @@ pub enum RequestMethod {
|
|||
ProvideCallHierarchyIncomingCalls((ModuleSpecifier, u32)),
|
||||
/// Resolve outgoing call hierarchy items for a specific position.
|
||||
ProvideCallHierarchyOutgoingCalls((ModuleSpecifier, u32)),
|
||||
/// Resolve inlay hints for a specific text span
|
||||
ProvideInlayHints((ModuleSpecifier, TextSpan, UserPreferences)),
|
||||
|
||||
// Special request, used only internally by the LSP
|
||||
Restart,
|
||||
|
@ -3269,6 +3373,15 @@ impl RequestMethod {
|
|||
"position": position
|
||||
})
|
||||
}
|
||||
RequestMethod::ProvideInlayHints((specifier, span, preferences)) => {
|
||||
json!({
|
||||
"id": id,
|
||||
"method": "provideInlayHints",
|
||||
"specifier": state.denormalize_specifier(specifier),
|
||||
"span": span,
|
||||
"preferences": preferences,
|
||||
})
|
||||
}
|
||||
RequestMethod::Restart => json!({
|
||||
"id": id,
|
||||
"method": "restart",
|
||||
|
|
|
@ -1071,6 +1071,213 @@ fn lsp_hover_disabled() {
|
|||
shutdown(&mut client);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_inlay_hints() {
|
||||
let mut client = init("initialize_params_hints.json");
|
||||
did_open(
|
||||
&mut client,
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts",
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": r#"function a(b: string) {
|
||||
return b;
|
||||
}
|
||||
|
||||
a("foo");
|
||||
|
||||
enum C {
|
||||
A,
|
||||
}
|
||||
|
||||
parseInt("123", 8);
|
||||
|
||||
const d = Date.now();
|
||||
|
||||
class E {
|
||||
f = Date.now();
|
||||
}
|
||||
|
||||
["a"].map((v) => v + v);
|
||||
"#
|
||||
}
|
||||
}),
|
||||
);
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request::<_, _, Value>(
|
||||
"textDocument/inlayHint",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts",
|
||||
},
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 19,
|
||||
"character": 0,
|
||||
}
|
||||
}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
assert_eq!(
|
||||
json!(maybe_res),
|
||||
json!([
|
||||
{
|
||||
"position": {
|
||||
"line": 0,
|
||||
"character": 21
|
||||
},
|
||||
"label": ": string",
|
||||
"kind": 1,
|
||||
"paddingLeft": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 4,
|
||||
"character": 10
|
||||
},
|
||||
"label": "b:",
|
||||
"kind": 2,
|
||||
"paddingRight": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 7,
|
||||
"character": 11
|
||||
},
|
||||
"label": "= 0",
|
||||
"paddingLeft": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 10,
|
||||
"character": 17
|
||||
},
|
||||
"label": "string:",
|
||||
"kind": 2,
|
||||
"paddingRight": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 10,
|
||||
"character": 24
|
||||
},
|
||||
"label": "radix:",
|
||||
"kind": 2,
|
||||
"paddingRight": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 12,
|
||||
"character": 15
|
||||
},
|
||||
"label": ": number",
|
||||
"kind": 1,
|
||||
"paddingLeft": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 15,
|
||||
"character": 11
|
||||
},
|
||||
"label": ": number",
|
||||
"kind": 1,
|
||||
"paddingLeft": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 18,
|
||||
"character": 18
|
||||
},
|
||||
"label": "callbackfn:",
|
||||
"kind": 2,
|
||||
"paddingRight": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 18,
|
||||
"character": 20
|
||||
},
|
||||
"label": ": string",
|
||||
"kind": 1,
|
||||
"paddingLeft": true
|
||||
},
|
||||
{
|
||||
"position": {
|
||||
"line": 18,
|
||||
"character": 21
|
||||
},
|
||||
"label": ": string",
|
||||
"kind": 1,
|
||||
"paddingLeft": true
|
||||
}
|
||||
])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_inlay_hints_not_enabled() {
|
||||
let mut client = init("initialize_params.json");
|
||||
did_open(
|
||||
&mut client,
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts",
|
||||
"languageId": "typescript",
|
||||
"version": 1,
|
||||
"text": r#"function a(b: string) {
|
||||
return b;
|
||||
}
|
||||
|
||||
a("foo");
|
||||
|
||||
enum C {
|
||||
A,
|
||||
}
|
||||
|
||||
parseInt("123", 8);
|
||||
|
||||
const d = Date.now();
|
||||
|
||||
class E {
|
||||
f = Date.now();
|
||||
}
|
||||
|
||||
["a"].map((v) => v + v);
|
||||
"#
|
||||
}
|
||||
}),
|
||||
);
|
||||
let (maybe_res, maybe_err) = client
|
||||
.write_request::<_, _, Value>(
|
||||
"textDocument/inlayHint",
|
||||
json!({
|
||||
"textDocument": {
|
||||
"uri": "file:///a/file.ts",
|
||||
},
|
||||
"range": {
|
||||
"start": {
|
||||
"line": 0,
|
||||
"character": 0
|
||||
},
|
||||
"end": {
|
||||
"line": 19,
|
||||
"character": 0,
|
||||
}
|
||||
}
|
||||
}),
|
||||
)
|
||||
.unwrap();
|
||||
assert!(maybe_err.is_none());
|
||||
assert_eq!(json!(maybe_res), json!(null));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn lsp_workspace_enable_paths() {
|
||||
let mut params: lsp::InitializeParams = serde_json::from_value(load_fixture(
|
||||
|
|
102
cli/tests/testdata/lsp/initialize_params_hints.json
vendored
Normal file
102
cli/tests/testdata/lsp/initialize_params_hints.json
vendored
Normal file
|
@ -0,0 +1,102 @@
|
|||
{
|
||||
"processId": 0,
|
||||
"clientInfo": {
|
||||
"name": "test-harness",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"rootUri": null,
|
||||
"initializationOptions": {
|
||||
"enable": true,
|
||||
"cache": null,
|
||||
"certificateStores": null,
|
||||
"codeLens": {
|
||||
"implementations": true,
|
||||
"references": true,
|
||||
"test": true
|
||||
},
|
||||
"config": null,
|
||||
"importMap": null,
|
||||
"inlayHints": {
|
||||
"parameterNames": {
|
||||
"enabled": "all"
|
||||
},
|
||||
"parameterTypes": {
|
||||
"enabled": true
|
||||
},
|
||||
"variableTypes": {
|
||||
"enabled": true
|
||||
},
|
||||
"propertyDeclarationTypes": {
|
||||
"enabled": true
|
||||
},
|
||||
"functionLikeReturnTypes": {
|
||||
"enabled": true
|
||||
},
|
||||
"enumMemberValues": {
|
||||
"enabled": true
|
||||
}
|
||||
},
|
||||
"lint": true,
|
||||
"suggest": {
|
||||
"autoImports": true,
|
||||
"completeFunctionCalls": false,
|
||||
"names": true,
|
||||
"paths": true,
|
||||
"imports": {
|
||||
"hosts": {}
|
||||
}
|
||||
},
|
||||
"testing": {
|
||||
"args": [
|
||||
"--allow-all"
|
||||
],
|
||||
"enable": true
|
||||
},
|
||||
"tlsCertificate": null,
|
||||
"unsafelyIgnoreCertificateErrors": null,
|
||||
"unstable": false
|
||||
},
|
||||
"capabilities": {
|
||||
"textDocument": {
|
||||
"codeAction": {
|
||||
"codeActionLiteralSupport": {
|
||||
"codeActionKind": {
|
||||
"valueSet": [
|
||||
"quickfix",
|
||||
"refactor"
|
||||
]
|
||||
}
|
||||
},
|
||||
"isPreferredSupport": true,
|
||||
"dataSupport": true,
|
||||
"disabledSupport": true,
|
||||
"resolveSupport": {
|
||||
"properties": [
|
||||
"edit"
|
||||
]
|
||||
}
|
||||
},
|
||||
"completion": {
|
||||
"completionItem": {
|
||||
"snippetSupport": true
|
||||
}
|
||||
},
|
||||
"foldingRange": {
|
||||
"lineFoldingOnly": true
|
||||
},
|
||||
"synchronization": {
|
||||
"dynamicRegistration": true,
|
||||
"willSave": true,
|
||||
"willSaveWaitUntil": true,
|
||||
"didSave": true
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"configuration": true,
|
||||
"workspaceFolders": true
|
||||
},
|
||||
"experimental": {
|
||||
"testingApi": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -898,6 +898,15 @@ delete Object.prototype.__proto__;
|
|||
),
|
||||
);
|
||||
}
|
||||
case "provideInlayHints":
|
||||
return respond(
|
||||
id,
|
||||
languageService.provideInlayHints(
|
||||
request.specifier,
|
||||
request.span,
|
||||
request.preferences,
|
||||
),
|
||||
);
|
||||
default:
|
||||
throw new TypeError(
|
||||
// @ts-ignore exhausted case statement sets type to never
|
||||
|
|
10
cli/tsc/compiler.d.ts
vendored
10
cli/tsc/compiler.d.ts
vendored
|
@ -77,7 +77,8 @@ declare global {
|
|||
| GetTypeDefinitionRequest
|
||||
| PrepareCallHierarchy
|
||||
| ProvideCallHierarchyIncomingCalls
|
||||
| ProvideCallHierarchyOutgoingCalls;
|
||||
| ProvideCallHierarchyOutgoingCalls
|
||||
| ProvideInlayHints;
|
||||
|
||||
interface BaseLanguageServerRequest {
|
||||
id: number;
|
||||
|
@ -255,6 +256,13 @@ declare global {
|
|||
position: number;
|
||||
}
|
||||
|
||||
interface ProvideInlayHints extends BaseLanguageServerRequest {
|
||||
method: "provideInlayHints";
|
||||
specifier: string;
|
||||
span: ts.TextSpan;
|
||||
preferences?: ts.UserPreferences;
|
||||
}
|
||||
|
||||
interface Restart extends BaseLanguageServerRequest {
|
||||
method: "restart";
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue