From 61d3743bd4025aa24f4cdaa9ec80947eb66e115c Mon Sep 17 00:00:00 2001 From: GearsDatapacks Date: Sun, 2 Mar 2025 13:10:54 +0000 Subject: [PATCH] Allow hovering over cached modules --- compiler-core/src/build/package_compiler.rs | 24 ++++++------ compiler-core/src/language_server/engine.rs | 39 +++++++++++++------ .../src/language_server/tests/hover.rs | 24 ++++++++++-- ...ts__hover__hover_over_imported_module.snap | 2 +- ..._tests__hover__hover_over_module_name.snap | 2 +- ..._hover_over_module_name_in_annotation.snap | 2 +- ...s__hover__hover_over_module_with_path.snap | 2 +- ..._link_when_hovering_over_local_module.snap | 14 +++++++ 8 files changed, 78 insertions(+), 31 deletions(-) create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__no_hexdocs_link_when_hovering_over_local_module.snap diff --git a/compiler-core/src/build/package_compiler.rs b/compiler-core/src/build/package_compiler.rs index cbbe7755fa8..865bd206d4c 100644 --- a/compiler-core/src/build/package_compiler.rs +++ b/compiler-core/src/build/package_compiler.rs @@ -193,7 +193,7 @@ where incomplete_modules, ); - let mut modules = match outcome { + let modules = match outcome { Outcome::Ok(modules) => modules, Outcome::PartialFailure(modules, error) => { return Outcome::PartialFailure( @@ -207,10 +207,6 @@ where Outcome::TotalFailure(error) => return Outcome::TotalFailure(error), }; - for mut module in modules.iter_mut() { - module.attach_doc_and_module_comments(); - } - tracing::debug!("performing_code_generation"); if let Err(error) = self.perform_codegen(&modules) { @@ -515,12 +511,8 @@ fn analyse( Outcome::Ok(ast) => { // Module has compiled successfully. Make sure it isn't marked as incomplete. let _ = incomplete_modules.remove(&name.clone()); - // Register the types from this module so they can be imported into - // other modules. - let _ = module_types.insert(name.clone(), ast.type_info.clone()); - // Register the successfully type checked module data so that it can be - // used for code generation and in the language server. - modules.push(Module { + + let mut module = Module { dependencies, origin, extra, @@ -529,7 +521,15 @@ fn analyse( code, ast, input_path: path, - }); + }; + module.attach_doc_and_module_comments(); + + // Register the types from this module so they can be imported into + // other modules. + let _ = module_types.insert(module.name.clone(), module.ast.type_info.clone()); + // Register the successfully type checked module data so that it can be + // used for code generation and in the language server. + modules.push(module); } Outcome::PartialFailure(ast, errors) => { diff --git a/compiler-core/src/language_server/engine.rs b/compiler-core/src/language_server/engine.rs index da7f806da53..277089ede64 100644 --- a/compiler-core/src/language_server/engine.rs +++ b/compiler-core/src/language_server/engine.rs @@ -27,7 +27,7 @@ use lsp_types::{ PrepareRenameResponse, Range, SignatureHelp, SymbolKind, SymbolTag, TextEdit, Url, WorkspaceEdit, }; -use std::sync::Arc; +use std::{collections::HashSet, sync::Arc}; use super::{ DownloadDependencies, MakeLocker, @@ -81,7 +81,7 @@ pub struct LanguageServerEngine { /// Used to know if to show the "View on HexDocs" link /// when hovering on an imported value - hex_deps: std::collections::HashSet, + hex_deps: HashSet, } impl<'a, IO, Reporter> LanguageServerEngine @@ -739,10 +739,15 @@ where Some(hover_for_module_constant(constant, lines, module)) } Located::ModuleStatement(Definition::Import(import)) => { - let Some(module) = this.compiler.modules.get(&import.module) else { + let Some(module) = this.compiler.get_module_interface(&import.module) else { return Ok(None); }; - Some(hover_for_module(module, import.location, &lines)) + Some(hover_for_module( + module, + import.location, + &lines, + &this.hex_deps, + )) } Located::ModuleStatement(_) => None, Located::UnqualifiedImport(UnqualifiedImport { @@ -844,10 +849,10 @@ Unused labelled fields: Some(hover_for_label(location, type_, lines, module)) } Located::ModuleName { location, name, .. } => { - let Some(module) = this.compiler.modules.get(name) else { + let Some(module) = this.compiler.get_module_interface(name) else { return Ok(None); }; - Some(hover_for_module(module, location, &lines)) + Some(hover_for_module(module, location, &lines, &this.hex_deps)) } }) }) @@ -1155,7 +1160,7 @@ fn hover_for_expression( expression: &TypedExpr, line_numbers: LineNumbers, module: &Module, - hex_deps: &std::collections::HashSet, + hex_deps: &HashSet, ) -> Hover { let documentation = expression.get_documentation().unwrap_or_default(); @@ -1207,17 +1212,27 @@ fn hover_for_imported_value( } } -fn hover_for_module(module: &Module, location: SrcSpan, line_numbers: &LineNumbers) -> Hover { - let documentation = module.ast.documentation.join("\n"); +fn hover_for_module( + module: &ModuleInterface, + location: SrcSpan, + line_numbers: &LineNumbers, + hex_deps: &HashSet, +) -> Hover { + let documentation = module.documentation.join("\n"); let name = &module.name; - let link_section = format_hexdocs_link_section(&module.ast.type_info.package, name, None); + let link_section = if hex_deps.contains(&module.package) { + format_hexdocs_link_section(&module.package, name, None) + } else { + String::new() + }; let contents = format!( "```gleam {name} ``` -{documentation}{link_section}", +{documentation} +{link_section}", ); Hover { contents: HoverContents::Scalar(MarkedString::String(contents)), @@ -1472,7 +1487,7 @@ fn get_hexdocs_link_section( module_name: &str, name: &str, ast: &TypedModule, - hex_deps: &std::collections::HashSet, + hex_deps: &HashSet, ) -> Option { let package_name = ast.definitions.iter().find_map(|def| match def { Definition::Import(p) if p.module == module_name && hex_deps.contains(&p.package) => { diff --git a/compiler-core/src/language_server/tests/hover.rs b/compiler-core/src/language_server/tests/hover.rs index 02f3bc74b3c..084200d75f4 100644 --- a/compiler-core/src/language_server/tests/hover.rs +++ b/compiler-core/src/language_server/tests/hover.rs @@ -1490,7 +1490,7 @@ pub fn main() { } "; assert_hover!( - TestProject::for_source(src).add_module( + TestProject::for_source(src).add_hex_module( "wibble", " //// This is the wibble module. @@ -1516,7 +1516,7 @@ pub fn main() { } "; assert_hover!( - TestProject::for_source(src).add_module( + TestProject::for_source(src).add_hex_module( "wibble/wobble", " //// The module documentation @@ -1540,7 +1540,7 @@ pub fn main(w: wibble.Wibble) { } "; assert_hover!( - TestProject::for_source(src).add_module( + TestProject::for_source(src).add_hex_module( "wibble", " //// This is the wibble module. @@ -1558,6 +1558,24 @@ pub type Wibble fn hover_over_imported_module() { let src = " import wibble +"; + assert_hover!( + TestProject::for_source(src).add_hex_module( + "wibble", + " +//// This is the wibble module. +//// Here is some documentation about it. +//// This module does stuff +" + ), + find_position_of("wibble") + ); +} + +#[test] +fn no_hexdocs_link_when_hovering_over_local_module() { + let src = " +import wibble "; assert_hover!( TestProject::for_source(src).add_module( diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_imported_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_imported_module.snap index 918600b25ad..099d9d91abd 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_imported_module.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_imported_module.snap @@ -9,6 +9,6 @@ import wibble ----- Hover content ----- Scalar( String( - "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\nView on [HexDocs](https://hexdocs.pm/app/wibble.html)", + "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\n\nView on [HexDocs](https://hexdocs.pm/hex/wibble.html)", ), ) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name.snap index 578107b7a2a..ea91f5451e7 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name.snap @@ -13,6 +13,6 @@ pub fn main() { ----- Hover content ----- Scalar( String( - "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\nView on [HexDocs](https://hexdocs.pm/app/wibble.html)", + "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\n\nView on [HexDocs](https://hexdocs.pm/hex/wibble.html)", ), ) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name_in_annotation.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name_in_annotation.snap index aa0bdc2241e..da84b6d16ff 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name_in_annotation.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_name_in_annotation.snap @@ -13,6 +13,6 @@ pub fn main(w: wibble.Wibble) { ----- Hover content ----- Scalar( String( - "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\nView on [HexDocs](https://hexdocs.pm/app/wibble.html)", + "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\n\nView on [HexDocs](https://hexdocs.pm/hex/wibble.html)", ), ) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_with_path.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_with_path.snap index 06c67c6c37c..98e85d8aa4a 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_with_path.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__hover_over_module_with_path.snap @@ -13,6 +13,6 @@ pub fn main() { ----- Hover content ----- Scalar( String( - "```gleam\nwibble/wobble\n```\n The module documentation\nView on [HexDocs](https://hexdocs.pm/app/wibble/wobble.html)", + "```gleam\nwibble/wobble\n```\n The module documentation\n\nView on [HexDocs](https://hexdocs.pm/hex/wibble/wobble.html)", ), ) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__no_hexdocs_link_when_hovering_over_local_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__no_hexdocs_link_when_hovering_over_local_module.snap new file mode 100644 index 00000000000..b8834ee3434 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__hover__no_hexdocs_link_when_hovering_over_local_module.snap @@ -0,0 +1,14 @@ +--- +source: compiler-core/src/language_server/tests/hover.rs +expression: "\nimport wibble\n" +--- +import wibble +▔▔▔▔▔▔▔↑▔▔▔▔▔ + + +----- Hover content ----- +Scalar( + String( + "```gleam\nwibble\n```\n This is the wibble module.\n Here is some documentation about it.\n This module does stuff\n", + ), +)