diff --git a/compiler-core/src/ast/inlay_hints.rs b/compiler-core/src/ast/inlay_hints.rs index b15583fb286..32c0dbc28e1 100644 --- a/compiler-core/src/ast/inlay_hints.rs +++ b/compiler-core/src/ast/inlay_hints.rs @@ -13,6 +13,8 @@ pub struct InlayHint { pub offset: u32, } +/// Determines if the expression is a simple literal whose inlayHints must not be showed +/// in a pipeline chain fn is_simple_lit(expr: &TypedExpr) -> bool { matches!( expr, @@ -44,13 +46,12 @@ impl<'a, 'ast> Visit<'ast> for InlayHintsVisitor<'a> { assignments: &'ast [TypedAssignment], finally: &'ast TypedExpr, ) { - fn get_this_line(this: &InlayHintsVisitor<'_>, span: &SrcSpan) -> u32 { - this.line_numbers.line_and_column_number(span.end).line - } - let mut prev_hint: Option<(u32, Option)> = None; for assign in assignments { - let this_line = get_this_line(self, &assign.location); + let this_line: u32 = self + .line_numbers + .line_and_column_number(assign.location.end) + .line; if let Some((prev_line, prev_hint)) = prev_hint { if prev_line != this_line { @@ -77,7 +78,10 @@ impl<'a, 'ast> Visit<'ast> for InlayHintsVisitor<'a> { } if let Some((prev_line, prev_hint)) = prev_hint { - let this_line = get_this_line(self, &finally.location()); + let this_line = self + .line_numbers + .line_and_column_number(finally.location().end) + .line; if this_line != prev_line { if let Some(prev_hint) = prev_hint { self.hints.push(prev_hint); @@ -88,6 +92,8 @@ impl<'a, 'ast> Visit<'ast> for InlayHintsVisitor<'a> { }); } } + + visit::visit_typed_expr(self, &finally); } } diff --git a/compiler-core/src/language_server.rs b/compiler-core/src/language_server.rs index 9dacae0f2cf..227c8b71161 100644 --- a/compiler-core/src/language_server.rs +++ b/compiler-core/src/language_server.rs @@ -44,12 +44,9 @@ pub fn src_offset_to_lsp_position(offset: u32, line_numbers: &LineNumbers) -> Po } pub fn src_span_to_lsp_range(location: SrcSpan, line_numbers: &LineNumbers) -> Range { - let start = line_numbers.line_and_column_number(location.start); - let end = line_numbers.line_and_column_number(location.end); - Range::new( - Position::new(start.line - 1, start.column - 1), - Position::new(end.line - 1, end.column - 1), + src_offset_to_lsp_position(location.start, line_numbers), + src_offset_to_lsp_position(location.end, line_numbers), ) } diff --git a/compiler-core/src/language_server/configuration.rs b/compiler-core/src/language_server/configuration.rs index 269fcb949d3..00942d78cc3 100644 --- a/compiler-core/src/language_server/configuration.rs +++ b/compiler-core/src/language_server/configuration.rs @@ -13,6 +13,7 @@ pub struct Configuration { #[derive(Debug, Clone, Deserialize)] #[serde(rename_all = "camelCase")] pub struct InlayHintsConfig { + /// Whether to show type inlay hints of multiline pipelines #[serde(default = "InlayHintsConfig::default_pipelines")] pub pipelines: bool, } diff --git a/compiler-core/src/language_server/engine.rs b/compiler-core/src/language_server/engine.rs index 9de52f94964..be7fc1508c5 100644 --- a/compiler-core/src/language_server/engine.rs +++ b/compiler-core/src/language_server/engine.rs @@ -278,7 +278,6 @@ where pub fn inlay_hints(&mut self, params: lsp::InlayHintParams) -> Response> { self.respond(|this| { let Ok(config) = this.user_config.read() else { - // TODO trace? return Ok(vec![]); }; @@ -293,10 +292,10 @@ where let line_numbers = LineNumbers::new(&module.code); let hints = ast::inlay_hints::get_inlay_hints(module.ast.clone(), &line_numbers) - .iter() + .into_iter() .map(|hint| InlayHint { position: src_offset_to_lsp_position(hint.offset, &line_numbers), - label: InlayHintLabel::String(hint.label.to_string()), + label: InlayHintLabel::String(hint.label), kind: Some(InlayHintKind::TYPE), text_edits: None, tooltip: None, diff --git a/compiler-core/src/language_server/tests.rs b/compiler-core/src/language_server/tests.rs index 2da8037fa1f..d1fe806d0cb 100644 --- a/compiler-core/src/language_server/tests.rs +++ b/compiler-core/src/language_server/tests.rs @@ -5,18 +5,7 @@ mod definition; mod hover; mod inlay_hints; -use std::{ - collections::HashMap, - sync::{Arc, Mutex, RwLock}, - time::SystemTime, -}; - -use ecow::EcoString; -use hexpm::version::{Range, Version}; - -use camino::{Utf8Path, Utf8PathBuf}; -use lsp_types::{Position, TextDocumentIdentifier, TextDocumentPositionParams, Url}; - +use super::configuration::{Configuration, InlayHintsConfig}; use crate::{ config::PackageConfig, io::{ @@ -32,8 +21,15 @@ use crate::{ requirement::Requirement, Result, }; - -use super::configuration::{Configuration, InlayHintsConfig}; +use camino::{Utf8Path, Utf8PathBuf}; +use ecow::EcoString; +use hexpm::version::{Range, Version}; +use lsp_types::{Position, TextDocumentIdentifier, TextDocumentPositionParams, Url}; +use std::{ + collections::HashMap, + sync::{Arc, Mutex, RwLock}, + time::SystemTime, +}; pub const LSP_TEST_ROOT_PACKAGE_NAME: &str = "app"; @@ -356,6 +352,7 @@ fn add_path_dep(engine: &mut LanguageServerEngine, n ) } +/// For testing purposes, turn all the flags on fn default_test_config() -> Configuration { Configuration { inlay_hints: InlayHintsConfig { pipelines: true }, @@ -502,16 +499,16 @@ impl<'a> TestProject<'a> { engine } - pub fn build_path(&self, position: Position) -> TextDocumentPositionParams { + fn build_path() -> TextDocumentIdentifier { let path = Utf8PathBuf::from(if cfg!(target_family = "windows") { r"\\?\C:\src\app.gleam" } else { "/src/app.gleam" }); - let url = Url::from_file_path(path).unwrap(); + let url = Url::from_file_path(path).expect("valid path"); - TextDocumentPositionParams::new(TextDocumentIdentifier::new(url), position) + TextDocumentIdentifier::new(url) } pub fn build_test_path( @@ -545,7 +542,7 @@ impl<'a> TestProject<'a> { let _response = engine.compile_please(); - let param = self.build_path(position); + let param = TextDocumentPositionParams::new(Self::build_path(), position); (engine, param) } diff --git a/compiler-core/src/language_server/tests/inlay_hints.rs b/compiler-core/src/language_server/tests/inlay_hints.rs index e71ea1047c0..7cfd7663144 100644 --- a/compiler-core/src/language_server/tests/inlay_hints.rs +++ b/compiler-core/src/language_server/tests/inlay_hints.rs @@ -1,9 +1,5 @@ use crate::language_server::tests::{setup_engine, LanguageServerTestIO}; -use camino::Utf8PathBuf; -use lsp_types::{ - InlayHint, InlayHintKind, InlayHintLabel, InlayHintParams, Position, Range, - TextDocumentIdentifier, Url, -}; +use lsp_types::{InlayHint, InlayHintKind, InlayHintLabel, InlayHintParams, Position, Range}; #[test] fn render_inlay_hints() { @@ -57,16 +53,8 @@ fn inlay_hints(src: &str) -> Vec { let response = engine.compile_please(); assert!(response.result.is_ok()); - let path = Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - }); - - let url = Url::from_file_path(path).expect("should be valid path for url"); - let params = InlayHintParams { - text_document: TextDocumentIdentifier::new(url), + text_document: super::TestProject::build_path(), work_done_progress_params: Default::default(), range: Range::new( Position::new(0, 0), @@ -76,7 +64,9 @@ fn inlay_hints(src: &str) -> Vec { ), ), }; - let response = engine.inlay_hints(params); - response.result.expect("inlay hint request should not fail") + engine + .inlay_hints(params) + .result + .expect("inlay hint request should not fail") }