From 2a7e5d7b574b7759c85f5caf15be0670062e386e Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 13:55:02 +0200 Subject: [PATCH 01/10] use actual function's name and module --- compiler-core/src/analyse.rs | 38 ++++----------------- compiler-core/src/language_server/engine.rs | 5 +++ 2 files changed, 11 insertions(+), 32 deletions(-) diff --git a/compiler-core/src/analyse.rs b/compiler-core/src/analyse.rs index 9c69b8858f1..06b4e676924 100644 --- a/compiler-core/src/analyse.rs +++ b/compiler-core/src/analyse.rs @@ -478,7 +478,6 @@ impl<'a, A> ModuleAnalyzer<'a, A> { // Find the external implementation for the current target, if one has been given. let external = target_function_implementation(target, &external_erlang, &external_javascript); - let (impl_module, impl_function) = implementation_names(external, &self.module_name, &name); // The function must have at least one implementation somewhere. let has_implementation = self.ensure_function_has_an_implementation( @@ -605,9 +604,9 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), - name: impl_function, + name: name.clone(), field_map, - module: impl_module, + module: environment.current_module.clone(), arity: typed_args.len(), location, implementations, @@ -1285,17 +1284,11 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let type_ = fn_(arg_types, return_type); let _ = self.hydrators.insert(name.clone(), hydrator); - let external = target_function_implementation( - environment.target, - external_erlang, - external_javascript, - ); - let (impl_module, impl_function) = implementation_names(external, &self.module_name, name); let variant = ValueConstructorVariant::ModuleFn { documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), - name: impl_function, + name: name.clone(), field_map, - module: impl_module, + module: environment.current_module.clone(), arity: args.len(), location: *location, implementations: *implementations, @@ -1389,21 +1382,6 @@ fn validate_module_name(name: &EcoString) -> Result<(), Error> { Ok(()) } -/// Returns the module name and function name of the implementation of a -/// function. If the function is implemented as a Gleam function then it is the -/// same as the name of the module and function. If the function has an external -/// implementation then it is the name of the external module and function. -fn implementation_names( - external: &Option<(EcoString, EcoString, SrcSpan)>, - module_name: &EcoString, - name: &EcoString, -) -> (EcoString, EcoString) { - match external { - None => (module_name.clone(), name.clone()), - Some((m, f, _)) => (m.clone(), f.clone()), - } -} - fn target_function_implementation<'a>( target: Target, external_erlang: &'a Option<(EcoString, EcoString, SrcSpan)>, @@ -1604,15 +1582,11 @@ fn generalise_function( let type_ = type_::generalise(type_); // Insert the function into the module's interface - let external = - target_function_implementation(environment.target, &external_erlang, &external_javascript); - let (impl_module, impl_function) = implementation_names(external, module_name, &name); - let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), - name: impl_function, + name: name.clone(), field_map, - module: impl_module, + module: module_name.clone(), arity: args.len(), location, implementations, diff --git a/compiler-core/src/language_server/engine.rs b/compiler-core/src/language_server/engine.rs index 2242b9432b6..00f0258c211 100644 --- a/compiler-core/src/language_server/engine.rs +++ b/compiler-core/src/language_server/engine.rs @@ -175,6 +175,11 @@ where None => return Ok(None), }; + let a = + node.definition_location(this.compiler.project_compiler.get_importable_modules()); + tracing::info!("{:#?}", node); + tracing::info!("{:#?}", a); + let location = match node .definition_location(this.compiler.project_compiler.get_importable_modules()) { From 44d1a9a4456502a73aa17025f8dd7d8659abc5a4 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 14:57:12 +0200 Subject: [PATCH 02/10] add external implementations to functions --- compiler-core/generated/schema_capnp.rs | 225 ++++++++++++++++++- compiler-core/schema.capnp | 7 + compiler-core/src/analyse.rs | 6 + compiler-core/src/metadata/module_decoder.rs | 17 ++ compiler-core/src/metadata/module_encoder.rs | 22 ++ compiler-core/src/metadata/tests.rs | 14 ++ compiler-core/src/type_.rs | 2 + compiler-core/src/type_/tests.rs | 8 + 8 files changed, 297 insertions(+), 4 deletions(-) diff --git a/compiler-core/generated/schema_capnp.rs b/compiler-core/generated/schema_capnp.rs index aa2796f532d..6d1958808c4 100644 --- a/compiler-core/generated/schema_capnp.rs +++ b/compiler-core/generated/schema_capnp.rs @@ -3523,6 +3523,8 @@ pub mod value_constructor_variant { self.builder.get_pointer_field(3).clear(); self.builder.get_pointer_field(4).clear(); self.builder.get_pointer_field(5).clear(); + self.builder.get_pointer_field(6).clear(); + self.builder.get_pointer_field(7).clear(); ::capnp::traits::FromStructBuilder::new(self.builder) } #[inline] @@ -3571,7 +3573,7 @@ pub mod value_constructor_variant { } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 8 }; pub const TYPE_ID: u64 = 0xe14c_79e9_2bd0_a81a; } pub enum Which { @@ -3819,7 +3821,7 @@ pub mod value_constructor_variant { } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 8 }; pub const TYPE_ID: u64 = 0x9579_9d69_8196_fbd0; } } @@ -3922,6 +3924,22 @@ pub mod value_constructor_variant { pub fn has_implementations(&self) -> bool { !self.reader.get_pointer_field(5).is_null() } + #[inline] + pub fn get_external_erlang(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(6), ::core::option::Option::None) + } + #[inline] + pub fn has_external_erlang(&self) -> bool { + !self.reader.get_pointer_field(6).is_null() + } + #[inline] + pub fn get_external_javascript(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(7), ::core::option::Option::None) + } + #[inline] + pub fn has_external_javascript(&self) -> bool { + !self.reader.get_pointer_field(7).is_null() + } } pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } @@ -4076,6 +4094,38 @@ pub mod value_constructor_variant { pub fn has_implementations(&self) -> bool { !self.builder.get_pointer_field(5).is_null() } + #[inline] + pub fn get_external_erlang(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(6), ::core::option::Option::None) + } + #[inline] + pub fn set_external_erlang(&mut self, value: crate::schema_capnp::option::Reader<'_,crate::schema_capnp::external::Owned>) -> ::capnp::Result<()> { + as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field(6), value, false) + } + #[inline] + pub fn init_external_erlang(self, ) -> crate::schema_capnp::option::Builder<'a,crate::schema_capnp::external::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(6), 0) + } + #[inline] + pub fn has_external_erlang(&self) -> bool { + !self.builder.get_pointer_field(6).is_null() + } + #[inline] + pub fn get_external_javascript(self) -> ::capnp::Result> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(7), ::core::option::Option::None) + } + #[inline] + pub fn set_external_javascript(&mut self, value: crate::schema_capnp::option::Reader<'_,crate::schema_capnp::external::Owned>) -> ::capnp::Result<()> { + as ::capnp::traits::SetPointerBuilder>::set_pointer_builder(self.builder.get_pointer_field(7), value, false) + } + #[inline] + pub fn init_external_javascript(self, ) -> crate::schema_capnp::option::Builder<'a,crate::schema_capnp::external::Owned> { + ::capnp::traits::FromPointerBuilder::init_pointer(self.builder.get_pointer_field(7), 0) + } + #[inline] + pub fn has_external_javascript(&self) -> bool { + !self.builder.get_pointer_field(7).is_null() + } } pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } @@ -4094,10 +4144,16 @@ pub mod value_constructor_variant { pub fn get_implementations(&self) -> crate::schema_capnp::implementations::Pipeline { ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(5)) } + pub fn get_external_erlang(&self) -> crate::schema_capnp::option::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(6)) + } + pub fn get_external_javascript(&self) -> crate::schema_capnp::option::Pipeline { + ::capnp::capability::FromTypelessPipeline::new(self._typeless.get_pointer_field(7)) + } } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 8 }; pub const TYPE_ID: u64 = 0xaea6_15c5_9871_3779; } } @@ -4372,12 +4428,173 @@ pub mod value_constructor_variant { } mod _private { use capnp::private::layout; - pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 6 }; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 1, pointers: 8 }; pub const TYPE_ID: u64 = 0xf00b_1526_e923_3dd5; } } } +pub mod external { + #[derive(Copy, Clone)] + pub struct Owned(()); + impl <'a> ::capnp::traits::Owned<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl <'a> ::capnp::traits::OwnedStruct<'a> for Owned { type Reader = Reader<'a>; type Builder = Builder<'a>; } + impl ::capnp::traits::Pipelined for Owned { type Pipeline = Pipeline; } + + #[derive(Clone, Copy)] + pub struct Reader<'a> { reader: ::capnp::private::layout::StructReader<'a> } + + impl <'a,> ::capnp::traits::HasTypeId for Reader<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructReader<'a> for Reader<'a,> { + fn new(reader: ::capnp::private::layout::StructReader<'a>) -> Reader<'a,> { + Reader { reader, } + } + } + + impl <'a,> ::capnp::traits::FromPointerReader<'a> for Reader<'a,> { + fn get_from_pointer(reader: &::capnp::private::layout::PointerReader<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructReader::new(reader.get_struct(default)?)) + } + } + + impl <'a,> ::capnp::traits::IntoInternalStructReader<'a> for Reader<'a,> { + fn into_internal_struct_reader(self) -> ::capnp::private::layout::StructReader<'a> { + self.reader + } + } + + impl <'a,> ::capnp::traits::Imbue<'a> for Reader<'a,> { + fn imbue(&mut self, cap_table: &'a ::capnp::private::layout::CapTable) { + self.reader.imbue(::capnp::private::layout::CapTableReader::Plain(cap_table)) + } + } + + impl <'a,> Reader<'a,> { + pub fn reborrow(&self) -> Reader<'_,> { + Reader { .. *self } + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.reader.total_size() + } + #[inline] + pub fn get_module(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn has_module(&self) -> bool { + !self.reader.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_function(self) -> ::capnp::Result<::capnp::text::Reader<'a>> { + ::capnp::traits::FromPointerReader::get_from_pointer(&self.reader.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn has_function(&self) -> bool { + !self.reader.get_pointer_field(1).is_null() + } + } + + pub struct Builder<'a> { builder: ::capnp::private::layout::StructBuilder<'a> } + impl <'a,> ::capnp::traits::HasStructSize for Builder<'a,> { + #[inline] + fn struct_size() -> ::capnp::private::layout::StructSize { _private::STRUCT_SIZE } + } + impl <'a,> ::capnp::traits::HasTypeId for Builder<'a,> { + #[inline] + fn type_id() -> u64 { _private::TYPE_ID } + } + impl <'a,> ::capnp::traits::FromStructBuilder<'a> for Builder<'a,> { + fn new(builder: ::capnp::private::layout::StructBuilder<'a>) -> Builder<'a, > { + Builder { builder, } + } + } + + impl <'a,> ::capnp::traits::ImbueMut<'a> for Builder<'a,> { + fn imbue_mut(&mut self, cap_table: &'a mut ::capnp::private::layout::CapTable) { + self.builder.imbue(::capnp::private::layout::CapTableBuilder::Plain(cap_table)) + } + } + + impl <'a,> ::capnp::traits::FromPointerBuilder<'a> for Builder<'a,> { + fn init_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, _size: u32) -> Builder<'a,> { + ::capnp::traits::FromStructBuilder::new(builder.init_struct(_private::STRUCT_SIZE)) + } + fn get_from_pointer(builder: ::capnp::private::layout::PointerBuilder<'a>, default: ::core::option::Option<&'a [capnp::Word]>) -> ::capnp::Result> { + ::core::result::Result::Ok(::capnp::traits::FromStructBuilder::new(builder.get_struct(_private::STRUCT_SIZE, default)?)) + } + } + + impl <'a,> ::capnp::traits::SetPointerBuilder for Reader<'a,> { + fn set_pointer_builder<'b>(pointer: ::capnp::private::layout::PointerBuilder<'b>, value: Reader<'a,>, canonicalize: bool) -> ::capnp::Result<()> { pointer.set_struct(&value.reader, canonicalize) } + } + + impl <'a,> Builder<'a,> { + pub fn into_reader(self) -> Reader<'a,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + pub fn reborrow(&mut self) -> Builder<'_,> { + Builder { .. *self } + } + pub fn reborrow_as_reader(&self) -> Reader<'_,> { + ::capnp::traits::FromStructReader::new(self.builder.into_reader()) + } + + pub fn total_size(&self) -> ::capnp::Result<::capnp::MessageSize> { + self.builder.into_reader().total_size() + } + #[inline] + pub fn get_module(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(0), ::core::option::Option::None) + } + #[inline] + pub fn set_module(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.get_pointer_field(0).set_text(value); + } + #[inline] + pub fn init_module(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(0).init_text(size) + } + #[inline] + pub fn has_module(&self) -> bool { + !self.builder.get_pointer_field(0).is_null() + } + #[inline] + pub fn get_function(self) -> ::capnp::Result<::capnp::text::Builder<'a>> { + ::capnp::traits::FromPointerBuilder::get_from_pointer(self.builder.get_pointer_field(1), ::core::option::Option::None) + } + #[inline] + pub fn set_function(&mut self, value: ::capnp::text::Reader<'_>) { + self.builder.get_pointer_field(1).set_text(value); + } + #[inline] + pub fn init_function(self, size: u32) -> ::capnp::text::Builder<'a> { + self.builder.get_pointer_field(1).init_text(size) + } + #[inline] + pub fn has_function(&self) -> bool { + !self.builder.get_pointer_field(1).is_null() + } + } + + pub struct Pipeline { _typeless: ::capnp::any_pointer::Pipeline } + impl ::capnp::capability::FromTypelessPipeline for Pipeline { + fn new(typeless: ::capnp::any_pointer::Pipeline) -> Pipeline { + Pipeline { _typeless: typeless, } + } + } + impl Pipeline { + } + mod _private { + use capnp::private::layout; + pub const STRUCT_SIZE: layout::StructSize = layout::StructSize { data: 0, pointers: 2 }; + pub const TYPE_ID: u64 = 0xc65f_3a72_de17_d4ec; + } +} + pub mod src_span { #[derive(Copy, Clone)] pub struct Owned(()); diff --git a/compiler-core/schema.capnp b/compiler-core/schema.capnp index 59589bf8a05..5f143cf06cf 100644 --- a/compiler-core/schema.capnp +++ b/compiler-core/schema.capnp @@ -141,6 +141,8 @@ struct ValueConstructorVariant { location @7 :SrcSpan; documentation @15 :Text; implementations @18 :Implementations; + externalErlang @20 :Option(External); + externalJavascript @21 :Option(External); } record :group { @@ -156,6 +158,11 @@ struct ValueConstructorVariant { } } +struct External { + module @0 :Text; + function @1 :Text; +} + struct SrcSpan { start @0 :UInt32; end @1 :UInt32; diff --git a/compiler-core/src/analyse.rs b/compiler-core/src/analyse.rs index 06b4e676924..86dd6a8a544 100644 --- a/compiler-core/src/analyse.rs +++ b/compiler-core/src/analyse.rs @@ -605,6 +605,8 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), + external_erlang: external_erlang.clone(), + external_javascript: external_javascript.clone(), field_map, module: environment.current_module.clone(), arity: typed_args.len(), @@ -1288,6 +1290,8 @@ impl<'a, A> ModuleAnalyzer<'a, A> { documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), field_map, + external_erlang: external_erlang.clone(), + external_javascript: external_javascript.clone(), module: environment.current_module.clone(), arity: args.len(), location: *location, @@ -1586,6 +1590,8 @@ fn generalise_function( documentation: doc.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), field_map, + external_erlang: external_erlang.clone(), + external_javascript: external_javascript.clone(), module: module_name.clone(), arity: args.len(), location, diff --git a/compiler-core/src/metadata/module_decoder.rs b/compiler-core/src/metadata/module_decoder.rs index 0e6013405ae..e9f2a863622 100755 --- a/compiler-core/src/metadata/module_decoder.rs +++ b/compiler-core/src/metadata/module_decoder.rs @@ -489,6 +489,8 @@ impl ModuleDecoder { location: self.src_span(&reader.get_location()?)?, documentation: self.optional_string(reader.get_documentation()?), implementations: self.implementations(reader.get_implementations()?), + external_erlang: self.optional_external(reader.get_external_erlang()?)?, + external_javascript: self.optional_external(reader.get_external_javascript()?)?, }) } @@ -566,4 +568,19 @@ impl ModuleDecoder { fn version(&self, reader: &version::Reader<'_>) -> hexpm::version::Version { hexpm::version::Version::new(reader.get_major(), reader.get_minor(), reader.get_patch()) } + + fn optional_external( + &self, + reader: option::Reader<'_, external::Owned>, + ) -> Result> { + match reader.which()? { + option::Which::None(()) => Ok(None), + option::Which::Some(reader) => { + let reader = reader?; + let module = EcoString::from(reader.get_module()?); + let function = EcoString::from(reader.get_function()?); + Ok(Some((module, function))) + } + } + } } diff --git a/compiler-core/src/metadata/module_encoder.rs b/compiler-core/src/metadata/module_encoder.rs index 772ad7e478b..2e30090659e 100644 --- a/compiler-core/src/metadata/module_encoder.rs +++ b/compiler-core/src/metadata/module_encoder.rs @@ -308,12 +308,19 @@ impl<'a> ModuleEncoder<'a> { location, documentation: doc, implementations, + external_erlang, + external_javascript, } => { let mut builder = builder.init_module_fn(); builder.set_name(name); builder.set_module(module); builder.set_arity(*arity as u16); builder.set_documentation(doc.as_ref().map(EcoString::as_str).unwrap_or_default()); + self.build_external(builder.reborrow().init_external_erlang(), external_erlang); + self.build_external( + builder.reborrow().init_external_javascript(), + external_javascript, + ); self.build_optional_field_map(builder.reborrow().init_field_map(), field_map); self.build_src_span(builder.reborrow().init_location(), *location); self.build_implementations(builder.init_implementations(), *implementations); @@ -557,4 +564,19 @@ impl<'a> ModuleEncoder<'a> { builder.set_can_run_on_erlang(implementations.can_run_on_erlang); builder.set_can_run_on_javascript(implementations.can_run_on_javascript); } + + fn build_external( + &self, + mut builder: option::Builder<'_, external::Owned>, + external: &Option<(EcoString, EcoString)>, + ) { + match external { + None => builder.set_none(()), + Some((module, function)) => { + let mut builder = builder.init_some(); + builder.set_module(module); + builder.set_function(function); + } + } + } } diff --git a/compiler-core/src/metadata/tests.rs b/compiler-core/src/metadata/tests.rs index 410f5946656..0179ec3d8d4 100644 --- a/compiler-core/src/metadata/tests.rs +++ b/compiler-core/src/metadata/tests.rs @@ -458,6 +458,8 @@ fn module_fn_value() { start: 535, end: 1100, }, + external_erlang: None, + external_javascript: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -505,6 +507,8 @@ fn deprecated_module_fn_value() { start: 535, end: 1100, }, + external_erlang: None, + external_javascript: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -550,6 +554,8 @@ fn private_module_fn_value() { start: 535, end: 1100, }, + external_erlang: None, + external_javascript: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -597,6 +603,8 @@ fn module_fn_value_regression() { start: 52, end: 1100, }, + external_erlang: None, + external_javascript: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -640,6 +648,8 @@ fn module_fn_value_with_field_map() { arity: 20, fields: [("ok".into(), 5), ("ko".into(), 7)].into(), }), + external_erlang: None, + external_javascript: None, module: "a".into(), arity: 5, location: SrcSpan { start: 2, end: 11 }, @@ -1245,6 +1255,8 @@ fn module_fn_value_with_external_implementations() { start: 52, end: 1100, }, + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), implementations: Implementations { gleam: false, uses_erlang_externals: true, @@ -1293,6 +1305,8 @@ fn internal_module_fn() { start: 52, end: 1100, }, + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), implementations: Implementations { gleam: false, uses_erlang_externals: true, diff --git a/compiler-core/src/type_.rs b/compiler-core/src/type_.rs index 53130b70b94..2dcd520198d 100644 --- a/compiler-core/src/type_.rs +++ b/compiler-core/src/type_.rs @@ -396,6 +396,8 @@ pub enum ValueConstructorVariant { location: SrcSpan, documentation: Option, implementations: Implementations, + external_erlang: Option<(EcoString, EcoString)>, + external_javascript: Option<(EcoString, EcoString)>, }, /// A constructor for a custom type diff --git a/compiler-core/src/type_/tests.rs b/compiler-core/src/type_/tests.rs index b65292b447b..eba9b2e02b5 100644 --- a/compiler-core/src/type_/tests.rs +++ b/compiler-core/src/type_/tests.rs @@ -2261,6 +2261,8 @@ fn assert_suitable_main_function_wrong_arity() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: None, + external_javascript: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -2286,6 +2288,8 @@ fn assert_suitable_main_function_ok() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: None, + external_javascript: None, implementations: Implementations { gleam: true, uses_erlang_externals: false, @@ -2311,6 +2315,8 @@ fn assert_suitable_main_function_erlang_not_supported() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), implementations: Implementations { gleam: false, uses_erlang_externals: true, @@ -2336,6 +2342,8 @@ fn assert_suitable_main_function_javascript_not_supported() { documentation: None, location: Default::default(), module: "module".into(), + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), implementations: Implementations { gleam: false, uses_erlang_externals: true, From a8b282dc05ed17680da17dd1bde2a678674b033b Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 15:19:30 +0200 Subject: [PATCH 03/10] fix erlang codegen for external functions --- compiler-core/src/erlang.rs | 36 ++++++++++++++++++++++++------------ 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/compiler-core/src/erlang.rs b/compiler-core/src/erlang.rs index 74d7a4efb86..527b7dd1153 100644 --- a/compiler-core/src/erlang.rs +++ b/compiler-core/src/erlang.rs @@ -1095,27 +1095,39 @@ fn var<'a>(name: &'a str, constructor: &'a ValueConstructor, env: &mut Env<'a>) ValueConstructorVariant::ModuleConstant { literal, .. } | ValueConstructorVariant::LocalConstant { literal } => const_inline(literal, env), + ValueConstructorVariant::ModuleFn { + arity, + external_erlang: Some((module, name)), + .. + } if module == env.module => function_reference(None, name, *arity), + + ValueConstructorVariant::ModuleFn { + arity, + external_erlang: Some((module, name)), + .. + } => function_reference(Some(module), name, *arity), + ValueConstructorVariant::ModuleFn { arity, ref module, .. - } if module == env.module => "fun " - .to_doc() - .append(atom(escape_erlang_existing_name(name))) - .append("/") - .append(*arity), + } if module == env.module => function_reference(None, name, *arity), ValueConstructorVariant::ModuleFn { arity, module, name, .. - } => "fun " - .to_doc() - .append(module_name_atom(module)) - .append(":") - .append(atom(escape_erlang_existing_name(name))) - .append("/") - .append(*arity), + } => function_reference(Some(module), name, *arity), + } +} + +fn function_reference<'a>(module: Option<&'a str>, name: &'a str, arity: usize) -> Document<'a> { + match module { + None => "fun ".to_doc(), + Some(module) => "fun ".to_doc().append(module_name_atom(module)).append(":"), } + .append(atom(escape_erlang_existing_name(name))) + .append("/") + .append(arity) } fn int<'a>(value: &str) -> Document<'a> { From c3f2ebece4594d2c14362aea87af23c20542f1a5 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 17:32:25 +0200 Subject: [PATCH 04/10] make sure to use external definitions and inline the call --- compiler-core/src/ast/tests.rs | 2 ++ compiler-core/src/erlang.rs | 28 ++++++++++++++++++++++++---- compiler-core/src/type_.rs | 23 ++++++++++++++++------- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/compiler-core/src/ast/tests.rs b/compiler-core/src/ast/tests.rs index e7d2b04bcac..1e85b6bbd81 100644 --- a/compiler-core/src/ast/tests.rs +++ b/compiler-core/src/ast/tests.rs @@ -361,6 +361,8 @@ fn find_node_module_select() { constructor: ModuleValueConstructor::Fn { module: "module".into(), name: "function".into(), + external_erlang: None, + external_javascript: None, location: SrcSpan { start: 1, end: 55 }, documentation: None, field_map: None, diff --git a/compiler-core/src/erlang.rs b/compiler-core/src/erlang.rs index 527b7dd1153..fe74810c380 100644 --- a/compiler-core/src/erlang.rs +++ b/compiler-core/src/erlang.rs @@ -1526,7 +1526,12 @@ fn docs_args_call<'a>( TypedExpr::Var { constructor: ValueConstructor { - variant: ValueConstructorVariant::ModuleFn { module, name, .. }, + variant: + ValueConstructorVariant::ModuleFn { + external_erlang: Some((module, name)), + .. + } + | ValueConstructorVariant::ModuleFn { module, name, .. }, .. }, .. @@ -1551,7 +1556,12 @@ fn docs_args_call<'a>( }, .. } if constructor.variant.is_module_fn() => { - if let ValueConstructorVariant::ModuleFn { module, name, .. } = &constructor.variant { + if let ValueConstructorVariant::ModuleFn { + external_erlang: Some((module, name)), + .. + } + | ValueConstructorVariant::ModuleFn { module, name, .. } = &constructor.variant + { module_fn_with_args(module, name, args, env) } else { unreachable!("The above clause guard ensures that this is a module fn") @@ -1559,7 +1569,12 @@ fn docs_args_call<'a>( } TypedExpr::ModuleSelect { - constructor: ModuleValueConstructor::Fn { module, name, .. }, + constructor: + ModuleValueConstructor::Fn { + external_erlang: Some((module, name)), + .. + } + | ModuleValueConstructor::Fn { module, name, .. }, .. } => { let args = wrap_args(args); @@ -1799,7 +1814,12 @@ fn expr<'a>(expression: &'a TypedExpr, env: &mut Env<'a>) -> Document<'a> { TypedExpr::ModuleSelect { type_, - constructor: ModuleValueConstructor::Fn { module, name, .. }, + constructor: + ModuleValueConstructor::Fn { + external_erlang: Some((module, name)), + .. + } + | ModuleValueConstructor::Fn { module, name, .. }, .. } => module_select_fn(type_.clone(), module, name), diff --git a/compiler-core/src/type_.rs b/compiler-core/src/type_.rs index 2dcd520198d..b9ff8983f39 100644 --- a/compiler-core/src/type_.rs +++ b/compiler-core/src/type_.rs @@ -458,6 +458,8 @@ impl ValueConstructorVariant { Self::LocalVariable { location, .. } => ModuleValueConstructor::Fn { name: function_name.clone(), module: module_name.clone(), + external_erlang: None, + external_javascript: None, documentation: None, location: *location, field_map: None, @@ -469,11 +471,15 @@ impl ValueConstructorVariant { location, documentation, field_map, + external_erlang, + external_javascript, .. } => ModuleValueConstructor::Fn { name: name.clone(), module: module.clone(), documentation: documentation.clone(), + external_erlang: external_erlang.clone(), + external_javascript: external_javascript.clone(), location: *location, field_map: field_map.clone(), }, @@ -546,20 +552,23 @@ pub enum ModuleValueConstructor { Fn { location: SrcSpan, /// The name of the module and the function - /// Typically this will be the module that this constructor belongs to - /// and the name that was used for the function. However it could also - /// point to some other module and function when this is an `external` - /// function. + /// This will be the module that this constructor belongs to + /// and the name that was used for the function. + module: EcoString, + name: EcoString, + /// If this is an `external` function, these will hold the name of the + /// external module and function. /// /// This function has module "themodule" and name "wibble" /// pub fn wibble() { Nil } /// - /// This function has module "other" and name "whoop" + /// This function has module "themodule" and name "wibble" + /// and erlang external "other" and "whoop". /// @external(erlang, "other", "whoop") /// pub fn wibble() -> Nil /// - module: EcoString, - name: EcoString, + external_erlang: Option<(EcoString, EcoString)>, + external_javascript: Option<(EcoString, EcoString)>, field_map: Option, documentation: Option, }, From b736011be146d5e17032d7dc662d177098bead58 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 17:45:31 +0200 Subject: [PATCH 05/10] rebase gone wrong --- compiler-core/src/analyse.rs | 12 ++++++------ compiler-core/src/metadata/tests.rs | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler-core/src/analyse.rs b/compiler-core/src/analyse.rs index 86dd6a8a544..f83d8beb390 100644 --- a/compiler-core/src/analyse.rs +++ b/compiler-core/src/analyse.rs @@ -605,8 +605,8 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), - external_erlang: external_erlang.clone(), - external_javascript: external_javascript.clone(), + external_erlang: external_erlang.clone().map(|(m, f, _)| (m, f)), + external_javascript: external_javascript.clone().map(|(m, f, _)| (m, f)), field_map, module: environment.current_module.clone(), arity: typed_args.len(), @@ -1290,8 +1290,8 @@ impl<'a, A> ModuleAnalyzer<'a, A> { documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), field_map, - external_erlang: external_erlang.clone(), - external_javascript: external_javascript.clone(), + external_erlang: external_erlang.clone().map(|(m, f, _)| (m, f)), + external_javascript: external_javascript.clone().map(|(m, f, _)| (m, f)), module: environment.current_module.clone(), arity: args.len(), location: *location, @@ -1590,8 +1590,8 @@ fn generalise_function( documentation: doc.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), field_map, - external_erlang: external_erlang.clone(), - external_javascript: external_javascript.clone(), + external_erlang: external_erlang.clone().map(|(m, f, _)| (m, f)), + external_javascript: external_javascript.clone().map(|(m, f, _)| (m, f)), module: module_name.clone(), arity: args.len(), location, diff --git a/compiler-core/src/metadata/tests.rs b/compiler-core/src/metadata/tests.rs index 0179ec3d8d4..86a03446f8f 100644 --- a/compiler-core/src/metadata/tests.rs +++ b/compiler-core/src/metadata/tests.rs @@ -1358,6 +1358,8 @@ fn internal_annotated_module_fn() { start: 52, end: 1100, }, + external_erlang: Some(("wibble".into(), "wobble".into())), + external_javascript: Some(("wobble".into(), "wibble".into())), implementations: Implementations { gleam: false, uses_erlang_externals: true, From afdefc681a833d6df5656e268d2c31ea34322435 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 17:48:57 +0200 Subject: [PATCH 06/10] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 46a3e872864..b74041bf895 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -402,6 +402,10 @@ prelude. ([Surya Rose](https://github.com/GearsDatapacks)) +- Fixed a bug where the language server wouldn't let you jump to the definition + of a function with an external implementation defined in the same module. + ([Giacomo Cavalieri](https://github.com/giacomocavalieri)) + ## v1.4.1 - 2024-08-04 ### Bug Fixes From 124821c7e6bb138350fce2be66fb3daf37b9229e Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 20:16:00 +0200 Subject: [PATCH 07/10] snapshot test all the things --- compiler-core/src/language_server/tests.rs | 31 +- .../src/language_server/tests/definition.rs | 662 ++++-------------- ...__goto_definition_deep_type_in_module.snap | 26 + ..._definition_external_module_constants.snap | 15 + ...nition_external_module_function_calls.snap | 15 + ...to_definition_external_module_records.snap | 19 + ...s__definition__goto_definition_import.snap | 15 + ...ition__goto_definition_import_aliased.snap | 15 + ...to_definition_import_unqualified_type.snap | 15 + ...o_definition_import_unqualified_value.snap | 15 + ..._definition_imported_module_constants.snap | 15 + ...to_definition_imported_module_records.snap | 19 + ...ition__goto_definition_local_variable.snap | 19 + ...goto_definition_module_function_calls.snap | 15 + ...definition_path_module_function_calls.snap | 15 + ...goto_definition_same_module_constants.snap | 21 + ...goto_definition_same_module_functions.snap | 25 + ...__goto_definition_same_module_records.snap | 29 + ...sts__definition__goto_definition_type.snap | 27 + ...ition__goto_definition_type_in_module.snap | 19 + ...ion__goto_definition_type_in_path_dep.snap | 19 + ..._goto_definition_unqualified_function.snap | 15 + ...unqualified_imported_module_constants.snap | 15 + ...n_unqualified_imported_module_records.snap | 19 + 24 files changed, 568 insertions(+), 532 deletions(-) create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap diff --git a/compiler-core/src/language_server/tests.rs b/compiler-core/src/language_server/tests.rs index fdd84799e55..a379e37703b 100644 --- a/compiler-core/src/language_server/tests.rs +++ b/compiler-core/src/language_server/tests.rs @@ -16,6 +16,7 @@ use ecow::EcoString; use hexpm::version::{Range, Version}; use camino::{Utf8Path, Utf8PathBuf}; +use itertools::Itertools; use lsp_types::{Position, TextDocumentIdentifier, TextDocumentPositionParams, Url}; use crate::{ @@ -392,6 +393,34 @@ impl<'a> TestProject<'a> { } } + pub fn src_from_module_url(&self, url: Url) -> Option<&str> { + let module_name: EcoString = url + .path_segments()? + .skip_while(|segment| *segment != "src") + .skip(1) + .join("/") + .trim_end_matches(".gleam") + .into(); + + if module_name == "app" { + return Some(self.src); + } + + let find_module = |modules: &Vec<(&'a str, &'a str)>| { + modules + .iter() + .find(|(name, _)| *name == module_name) + .map(|(_, src)| *src) + }; + + find_module(&self.root_package_modules) + .or(find_module(&self.dependency_modules)) + .or(find_module(&self.test_modules)) + .or(find_module(&self.hex_modules)) + .or(find_module(&self.dev_hex_modules)) + .or(find_module(&self.indirect_hex_modules)) + } + pub fn add_module(mut self, name: &'a str, src: &'a str) -> Self { self.root_package_modules.push((name, src)); self @@ -565,7 +594,7 @@ impl<'a> TestProject<'a> { } pub fn at( - self, + &self, position: Position, executor: impl FnOnce( &mut LanguageServerEngine, diff --git a/compiler-core/src/language_server/tests/definition.rs b/compiler-core/src/language_server/tests/definition.rs index e35c4258160..5837564ab7e 100644 --- a/compiler-core/src/language_server/tests/definition.rs +++ b/compiler-core/src/language_server/tests/definition.rs @@ -2,7 +2,7 @@ use lsp_types::{GotoDefinitionParams, Location, Position, Range, Url}; use super::*; -fn definition(tester: TestProject<'_>, position: Position) -> Option { +fn definition(tester: &TestProject<'_>, position: Position) -> Option { tester.at(position, |engine, param, _| { let params = GotoDefinitionParams { text_document_position_params: param, @@ -15,106 +15,85 @@ fn definition(tester: TestProject<'_>, position: Position) -> Option { }) } +fn pretty_definition(project: TestProject<'_>, position_finder: PositionFinder) -> String { + let position = position_finder.find_position(project.src); + let location = definition(&project, position).expect("a location to jump to"); + let src = hover::show_hover( + project.src, + Range { + start: position, + end: position, + }, + position, + ); + + let destination = hover::show_hover( + project + .src_from_module_url(location.uri) + .expect("a module to jump to"), + location.range, + location.range.start, + ); + + format!("---------- Jumping from:\n{src}\n---------- Jumped to:\n{destination}") +} + +#[macro_export] +macro_rules! assert_goto { + ($src:literal, $position:expr) => { + let project = TestProject::for_source($src); + assert_goto!(project, $position); + }; + ($project:expr, $position:expr) => { + let output = pretty_definition($project, $position); + insta::assert_snapshot!(insta::internals::AutoName, output); + }; +} + #[test] fn goto_definition_local_variable() { - let code = " + assert_goto!( + " pub fn main() { let x = 1 x -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(3, 2)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 6 - }, - end: Position { - line: 2, - character: 7 - } - } - }) - ) +}", + find_position_of("x").nth_occurrence(2) + ); } #[test] fn goto_definition_same_module_constants() { - let code = " + assert_goto!( + " const x = 1 pub fn main() { x -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(4, 2)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 7 - } - } - }) - ) +}", + find_position_of("x").nth_occurrence(2) + ); } #[test] fn goto_definition_same_module_functions() { - let code = " + assert_goto!( + " fn add_2(x) { x + 2 } pub fn main() { add_2(1) -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(6, 3)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 11 - } - } - }) - ) +}", + find_position_of("add_2(1)") + ); } #[test] fn goto_definition_same_module_records() { - let code = " + assert_goto!( + " pub type Rec { Var1(Int) Var2(Int, Int) @@ -123,29 +102,9 @@ pub type Rec { pub fn main() { let a = Var1(1) let b = Var2(2, 3) -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(7, 11)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) +}", + find_position_of("Var1(1)") + ); } #[test] @@ -157,30 +116,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(3, 19) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("my_num") + ); } #[test] @@ -192,30 +131,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(3, 3) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("my_num").nth_occurrence(2) + ); } #[test] @@ -227,30 +146,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub fn my_fn() { Nil }"), - Position::new(3, 19) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 14 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub fn my_fn() { Nil }"), + find_position_of("my_fn") + ); } #[test] @@ -268,30 +167,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", dep_src), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", dep_src), + find_position_of("Var1(1)") + ); } #[test] @@ -309,30 +188,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", dep_src), - Position::new(3, 3) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", dep_src), + find_position_of("Var1(1)").under_char('a') + ); } #[test] @@ -344,30 +203,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", "pub const my_num = 1"), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", "pub const my_num = 1"), + find_position_of("my_num").under_char('u') + ); } #[test] @@ -379,31 +218,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code) - .add_hex_module("example_module", "pub fn my_fn() { Nil }"), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 14 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", "pub fn my_fn() { Nil }"), + find_position_of("my_fn") + ); } #[test] @@ -571,30 +389,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", hex_src), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 2, - character: 2 - }, - end: Position { - line: 2, - character: 11 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", hex_src), + find_position_of("Var1(1)").under_char('r') + ); } #[test] @@ -606,36 +404,16 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code) - .add_dep_module("example_module", "pub fn my_fn() { Nil }"), - Position::new(3, 20) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\dep\src\example_module.gleam" - } else { - "/dep/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 14 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_dep_module("example_module", "pub fn my_fn() { Nil }"), + find_position_of("my_fn").under_char('y') + ); } #[test] fn goto_definition_type() { - let code = " + assert_goto!( + " pub type Rec { Var1(Int) Var2(Int, Int) @@ -643,29 +421,9 @@ pub type Rec { pub fn make_var() -> Rec { Var1(1) -}"; - - assert_eq!( - definition(TestProject::for_source(code), Position::new(6, 22)), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\app.gleam" - } else { - "/src/app.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 12 - } - } - }) - ) +}", + find_position_of("Rec").nth_occurrence(2) + ); } #[test] @@ -684,30 +442,10 @@ fn make_var() -> example_module.Rec { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", hex_src), - Position::new(2, 33) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 12 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", hex_src), + find_position_of("Rec") + ); } #[test] @@ -726,30 +464,10 @@ fn make_var() -> example_module.Rec { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_dep_module("example_module", dep), - Position::new(2, 33) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\dep\src\example_module.gleam" - } else { - "/dep/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 12 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_dep_module("example_module", dep), + find_position_of("Rec") + ); } #[test] @@ -775,30 +493,10 @@ fn make_var() -> example_module.Wabble(example_module.Wibble(example_module.Wobb } "; - assert_eq!( - definition( - TestProject::for_source(code).add_hex_module("example_module", hex_src), - Position::new(2, 80) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\build\packages\hex\src\example_module.gleam" - } else { - "/build/packages/hex/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 1, - character: 0 - }, - end: Position { - line: 1, - character: 15 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_hex_module("example_module", hex_src), + find_position_of("Wobble").under_char('o') + ); } #[test] @@ -810,30 +508,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(1, 13) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 0 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("example_module").under_char('p') + ); } #[test] @@ -845,30 +523,12 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(1, 29) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 0 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("example") + .nth_occurrence(2) + .under_char('x') + ); } #[test] @@ -880,30 +540,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), - Position::new(1, 26) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 16 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub const my_num = 1"), + find_position_of("my_num").under_char('_') + ); } #[test] @@ -915,30 +555,10 @@ fn main() { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("wibble", "pub fn wobble() {}"), - Position::new(3, 5) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\wibble.gleam" - } else { - "/src/wibble.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 15 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("wibble", "pub fn wobble() {}"), + find_position_of("wobble").nth_occurrence(2).under_char('o') + ); } #[test] @@ -950,28 +570,8 @@ fn main() -> MyType { } "; - assert_eq!( - definition( - TestProject::for_source(code).add_module("example_module", "pub type MyType = Int"), - Position::new(1, 33) - ), - Some(Location { - uri: Url::from_file_path(Utf8PathBuf::from(if cfg!(target_family = "windows") { - r"\\?\C:\src\example_module.gleam" - } else { - "/src/example_module.gleam" - })) - .unwrap(), - range: Range { - start: Position { - line: 0, - character: 0 - }, - end: Position { - line: 0, - character: 21 - } - } - }) - ) + assert_goto!( + TestProject::for_source(code).add_module("example_module", "pub type MyType = Int"), + find_position_of("MyType").under_char('T') + ); } diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap new file mode 100644 index 00000000000..83c0e969f72 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap @@ -0,0 +1,26 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn make_var() -> example_module.Wabble(example_module.Wibble(example_module.Wobble)) { + ↑ + example_module.Wabble(example_module.Wibble(example_module.Wobble(1))) +} + +---------- Jumped to: + +pub type Wobble { +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + Wobble(Int) +} + +pub type Wibble(a) { + Wibble(a) +} + +pub type Wabble(a) { + Wabble(a) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap new file mode 100644 index 00000000000..6f555feb1d7 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.my_num + ↑ +} + +---------- Jumped to: +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap new file mode 100644 index 00000000000..70780126236 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.my_fn + ↑ +} + +---------- Jumped to: +pub fn my_fn() { Nil } +↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap new file mode 100644 index 00000000000..61b001e75b4 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.Var1(1) + ↑ +} + +---------- Jumped to: + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap new file mode 100644 index 00000000000..7eb0b0703ae --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module + ↑ +fn main() { + example_module.my_num +} + +---------- Jumped to: +pub const my_num = 1 +↑ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap new file mode 100644 index 00000000000..d9366224813 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module as example + ↑ +fn main() { + example.my_num +} + +---------- Jumped to: +pub const my_num = 1 +↑ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap new file mode 100644 index 00000000000..9e28d628c9b --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module.{type MyType} + ↑ +fn main() -> MyType { + 0 +} + +---------- Jumped to: +pub type MyType = Int +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap new file mode 100644 index 00000000000..a6410ad260d --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module.{my_num} + ↑ +fn main() { + my_num +} + +---------- Jumped to: +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap new file mode 100644 index 00000000000..3b9cec0e874 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.my_num + ↑ +} + +---------- Jumped to: +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap new file mode 100644 index 00000000000..da72df92d52 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.Var1(1) + ↑ +} + +---------- Jumped to: + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap new file mode 100644 index 00000000000..561eea19333 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +pub fn main() { + let x = 1 + x + ↑ +} + +---------- Jumped to: + +pub fn main() { + let x = 1 + ↑ + x +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap new file mode 100644 index 00000000000..70780126236 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.my_fn + ↑ +} + +---------- Jumped to: +pub fn my_fn() { Nil } +↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap new file mode 100644 index 00000000000..9e1529b7c11 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn main() { + example_module.my_fn + ↑ +} + +---------- Jumped to: +pub fn my_fn() { Nil } +↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap new file mode 100644 index 00000000000..ee3fd3c6434 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap @@ -0,0 +1,21 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +const x = 1 + +pub fn main() { + x + ↑ +} + +---------- Jumped to: + +const x = 1 +↑▔▔▔▔▔▔ + +pub fn main() { + x +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap new file mode 100644 index 00000000000..9c25b264609 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap @@ -0,0 +1,25 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +fn add_2(x) { + x + 2 +} + +pub fn main() { + add_2(1) + ↑ +} + +---------- Jumped to: + +fn add_2(x) { +↑▔▔▔▔▔▔▔▔▔▔ + x + 2 +} + +pub fn main() { + add_2(1) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap new file mode 100644 index 00000000000..f63d5685ec2 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap @@ -0,0 +1,29 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +pub type Rec { + Var1(Int) + Var2(Int, Int) +} + +pub fn main() { + let a = Var1(1) + ↑ + let b = Var2(2, 3) +} + +---------- Jumped to: + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} + +pub fn main() { + let a = Var1(1) + let b = Var2(2, 3) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap new file mode 100644 index 00000000000..750e004c514 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap @@ -0,0 +1,27 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +pub type Rec { + Var1(Int) + Var2(Int, Int) +} + +pub fn make_var() -> Rec { + ↑ + Var1(1) +} + +---------- Jumped to: + +pub type Rec { +↑▔▔▔▔▔▔▔▔▔▔▔ + Var1(Int) + Var2(Int, Int) +} + +pub fn make_var() -> Rec { + Var1(1) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap new file mode 100644 index 00000000000..7e13dfcc7c2 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn make_var() -> example_module.Rec { + ↑ + example_module.Var1(1) +} + +---------- Jumped to: + +pub type Rec { +↑▔▔▔▔▔▔▔▔▔▔▔ + Var1(Int) + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap new file mode 100644 index 00000000000..7e13dfcc7c2 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module +fn make_var() -> example_module.Rec { + ↑ + example_module.Var1(1) +} + +---------- Jumped to: + +pub type Rec { +↑▔▔▔▔▔▔▔▔▔▔▔ + Var1(Int) + Var2(Int, Int) +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap new file mode 100644 index 00000000000..3921084d83c --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import wibble.{wobble} +fn main() { + wobble() + ↑ +} + +---------- Jumped to: +pub fn wobble() {} +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap new file mode 100644 index 00000000000..c7795a1004f --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap @@ -0,0 +1,15 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module.{my_num} +fn main() { + my_num + ↑ +} + +---------- Jumped to: +pub const my_num = 1 +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap new file mode 100644 index 00000000000..2adeef84610 --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap @@ -0,0 +1,19 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +---------- Jumping from: + +import example_module.{Var1} +fn main() { + Var1(1) + ↑ +} + +---------- Jumped to: + +pub type Rec { + Var1(Int) + ↑▔▔▔▔▔▔▔▔ + Var2(Int, Int) +} From 88e268718087798a847bc4a4efff034cfd5853d3 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Wed, 11 Sep 2024 22:54:38 +0200 Subject: [PATCH 08/10] include file names in snapshot --- compiler-core/src/language_server/tests.rs | 2 +- .../src/language_server/tests/definition.rs | 35 +++++++++++++++++-- ...__goto_definition_deep_type_in_module.snap | 4 +-- ..._definition_external_module_constants.snap | 4 +-- ...nition_external_module_function_calls.snap | 4 +-- ...to_definition_external_module_records.snap | 4 +-- ...s__definition__goto_definition_import.snap | 4 +-- ...ition__goto_definition_import_aliased.snap | 4 +-- ...to_definition_import_unqualified_type.snap | 4 +-- ...o_definition_import_unqualified_value.snap | 4 +-- ..._definition_imported_module_constants.snap | 4 +-- ...to_definition_imported_module_records.snap | 4 +-- ...ition__goto_definition_local_variable.snap | 4 +-- ...goto_definition_module_function_calls.snap | 4 +-- ...n_of_external_function_in_same_module.snap | 23 ++++++++++++ ...definition_path_module_function_calls.snap | 4 +-- ...goto_definition_same_module_constants.snap | 4 +-- ...goto_definition_same_module_functions.snap | 4 +-- ...__goto_definition_same_module_records.snap | 4 +-- ...sts__definition__goto_definition_type.snap | 4 +-- ...ition__goto_definition_type_in_module.snap | 4 +-- ...ion__goto_definition_type_in_path_dep.snap | 4 +-- ..._goto_definition_unqualified_function.snap | 4 +-- ...unqualified_imported_module_constants.snap | 4 +-- ...n_unqualified_imported_module_records.snap | 4 +-- 25 files changed, 101 insertions(+), 47 deletions(-) create mode 100644 compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap diff --git a/compiler-core/src/language_server/tests.rs b/compiler-core/src/language_server/tests.rs index a379e37703b..bee4b8b02e4 100644 --- a/compiler-core/src/language_server/tests.rs +++ b/compiler-core/src/language_server/tests.rs @@ -393,7 +393,7 @@ impl<'a> TestProject<'a> { } } - pub fn src_from_module_url(&self, url: Url) -> Option<&str> { + pub fn src_from_module_url(&self, url: &Url) -> Option<&str> { let module_name: EcoString = url .path_segments()? .skip_while(|segment| *segment != "src") diff --git a/compiler-core/src/language_server/tests/definition.rs b/compiler-core/src/language_server/tests/definition.rs index 5837564ab7e..5e581f4b32a 100644 --- a/compiler-core/src/language_server/tests/definition.rs +++ b/compiler-core/src/language_server/tests/definition.rs @@ -18,6 +18,12 @@ fn definition(tester: &TestProject<'_>, position: Position) -> Option fn pretty_definition(project: TestProject<'_>, position_finder: PositionFinder) -> String { let position = position_finder.find_position(project.src); let location = definition(&project, position).expect("a location to jump to"); + let pretty_destination = location + .uri + .path_segments() + .expect("a location to jump to") + .join("/"); + let src = hover::show_hover( project.src, Range { @@ -29,13 +35,18 @@ fn pretty_definition(project: TestProject<'_>, position_finder: PositionFinder) let destination = hover::show_hover( project - .src_from_module_url(location.uri) + .src_from_module_url(&location.uri) .expect("a module to jump to"), location.range, location.range.start, ); - format!("---------- Jumping from:\n{src}\n---------- Jumped to:\n{destination}") + format!( + "----- Jumping from `src/app.gleam` +{src} +----- Jumped to `{pretty_destination}` +{destination}", + ) } #[macro_export] @@ -575,3 +586,23 @@ fn main() -> MyType { find_position_of("MyType").under_char('T') ); } + +// https://github.com/gleam-lang/gleam/issues/3610 +#[test] +fn goto_definition_of_external_function_in_same_module() { + let code = " +@external(erlang, \"wibble\", \"wobble\") +fn external_function() -> Nil + +fn main() { + external_function() +} +"; + + assert_goto!( + TestProject::for_source(code), + find_position_of("external_function") + .nth_occurrence(2) + .under_char('l') + ); +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap index 83c0e969f72..eeff688316c 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_deep_type_in_module.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn make_var() -> example_module.Wabble(example_module.Wibble(example_module.Wobble)) { @@ -10,7 +10,7 @@ fn make_var() -> example_module.Wabble(example_module.Wibble(example_module.Wobb example_module.Wabble(example_module.Wibble(example_module.Wobble(1))) } ----------- Jumped to: +----- Jumped to `build/packages/hex/src/example_module.gleam` pub type Wobble { ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap index 6f555feb1d7..768b204f15a 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_constants.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `build/packages/hex/src/example_module.gleam` pub const my_num = 1 ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap index 70780126236..ca785245bf2 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_function_calls.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `build/packages/hex/src/example_module.gleam` pub fn my_fn() { Nil } ↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap index 61b001e75b4..e22ca7f18a5 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_external_module_records.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,7 +10,7 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `build/packages/hex/src/example_module.gleam` pub type Rec { Var1(Int) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap index 7eb0b0703ae..b3255800a5e 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module ↑ @@ -10,6 +10,6 @@ fn main() { example_module.my_num } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub const my_num = 1 ↑ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap index d9366224813..088be713538 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_aliased.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module as example ↑ @@ -10,6 +10,6 @@ fn main() { example.my_num } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub const my_num = 1 ↑ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap index 9e28d628c9b..c78933b4a24 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_type.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module.{type MyType} ↑ @@ -10,6 +10,6 @@ fn main() -> MyType { 0 } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub type MyType = Int ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap index a6410ad260d..51117c87691 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_import_unqualified_value.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module.{my_num} ↑ @@ -10,6 +10,6 @@ fn main() { my_num } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub const my_num = 1 ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap index 3b9cec0e874..8d9af570ae3 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_constants.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub const my_num = 1 ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap index da72df92d52..e09b35ce42b 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_imported_module_records.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,7 +10,7 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub type Rec { Var1(Int) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap index 561eea19333..2cd597845b4 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_local_variable.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` pub fn main() { let x = 1 @@ -10,7 +10,7 @@ pub fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/app.gleam` pub fn main() { let x = 1 diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap index 70780126236..616fdc4b9a3 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_module_function_calls.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub fn my_fn() { Nil } ↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap new file mode 100644 index 00000000000..6f67945ac0b --- /dev/null +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_of_external_function_in_same_module.snap @@ -0,0 +1,23 @@ +--- +source: compiler-core/src/language_server/tests/definition.rs +expression: output +--- +----- Jumping from `src/app.gleam` + +@external(erlang, "wibble", "wobble") +fn external_function() -> Nil + +fn main() { + external_function() + ↑ +} + +----- Jumped to `src/app.gleam` + +@external(erlang, "wibble", "wobble") +fn external_function() -> Nil +↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ + +fn main() { + external_function() +} diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap index 9e1529b7c11..f4519ff9548 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_path_module_function_calls.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `dep/src/example_module.gleam` pub fn my_fn() { Nil } ↑▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap index ee3fd3c6434..c441a00279f 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_constants.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` const x = 1 @@ -11,7 +11,7 @@ pub fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/app.gleam` const x = 1 ↑▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap index 9c25b264609..fb60e5f191f 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_functions.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` fn add_2(x) { x + 2 @@ -13,7 +13,7 @@ pub fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/app.gleam` fn add_2(x) { ↑▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap index f63d5685ec2..b0729f2b3a0 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_same_module_records.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` pub type Rec { Var1(Int) @@ -15,7 +15,7 @@ pub fn main() { let b = Var2(2, 3) } ----------- Jumped to: +----- Jumped to `src/app.gleam` pub type Rec { Var1(Int) diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap index 750e004c514..52dd9c73e8a 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` pub type Rec { Var1(Int) @@ -14,7 +14,7 @@ pub fn make_var() -> Rec { Var1(1) } ----------- Jumped to: +----- Jumped to `src/app.gleam` pub type Rec { ↑▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap index 7e13dfcc7c2..82a7ed298fa 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_module.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn make_var() -> example_module.Rec { @@ -10,7 +10,7 @@ fn make_var() -> example_module.Rec { example_module.Var1(1) } ----------- Jumped to: +----- Jumped to `build/packages/hex/src/example_module.gleam` pub type Rec { ↑▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap index 7e13dfcc7c2..3b662604d31 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_type_in_path_dep.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module fn make_var() -> example_module.Rec { @@ -10,7 +10,7 @@ fn make_var() -> example_module.Rec { example_module.Var1(1) } ----------- Jumped to: +----- Jumped to `dep/src/example_module.gleam` pub type Rec { ↑▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap index 3921084d83c..e64b711e8ae 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_function.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import wibble.{wobble} fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/wibble.gleam` pub fn wobble() {} ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap index c7795a1004f..c66c63d39f7 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_constants.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module.{my_num} fn main() { @@ -10,6 +10,6 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub const my_num = 1 ↑▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔ diff --git a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap index 2adeef84610..04bc4e9376a 100644 --- a/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap +++ b/compiler-core/src/language_server/tests/snapshots/gleam_core__language_server__tests__definition__goto_definition_unqualified_imported_module_records.snap @@ -2,7 +2,7 @@ source: compiler-core/src/language_server/tests/definition.rs expression: output --- ----------- Jumping from: +----- Jumping from `src/app.gleam` import example_module.{Var1} fn main() { @@ -10,7 +10,7 @@ fn main() { ↑ } ----------- Jumped to: +----- Jumped to `src/example_module.gleam` pub type Rec { Var1(Int) From f9547d62388e1b75c3993489a055e5bce77f9c3e Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Thu, 12 Sep 2024 14:21:47 +0200 Subject: [PATCH 09/10] fix tests on windows --- compiler-core/src/language_server/tests/definition.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler-core/src/language_server/tests/definition.rs b/compiler-core/src/language_server/tests/definition.rs index 5e581f4b32a..42dfba05d4c 100644 --- a/compiler-core/src/language_server/tests/definition.rs +++ b/compiler-core/src/language_server/tests/definition.rs @@ -22,6 +22,9 @@ fn pretty_definition(project: TestProject<'_>, position_finder: PositionFinder) .uri .path_segments() .expect("a location to jump to") + // To make snapshots the same both on windows and unix systems we need + // to discard windows' `C:` path segment at the beginning of a uri. + .skip_while(|segment| *segment == "C:") .join("/"); let src = hover::show_hover( From 6ad93979b86c87a32c688ef54ff279e7d34470c4 Mon Sep 17 00:00:00 2001 From: Giacomo Cavalieri Date: Thu, 12 Sep 2024 17:48:27 +0200 Subject: [PATCH 10/10] review comments --- compiler-core/schema.capnp | 14 ++++++------ compiler-core/src/analyse.rs | 24 +++++++++++++++------ compiler-core/src/language_server/engine.rs | 5 ----- compiler-core/src/language_server/tests.rs | 10 ++++----- 4 files changed, 30 insertions(+), 23 deletions(-) diff --git a/compiler-core/schema.capnp b/compiler-core/schema.capnp index 5f143cf06cf..4a349e6877c 100644 --- a/compiler-core/schema.capnp +++ b/compiler-core/schema.capnp @@ -108,11 +108,11 @@ struct ValueConstructor { } struct Publicity { - union { - public @0 :Void; - private @1 :Void; - internal @2 :Option(SrcSpan); - } + union { + public @0 :Void; + private @1 :Void; + internal @2 :Option(SrcSpan); + } } struct Implementations { @@ -159,8 +159,8 @@ struct ValueConstructorVariant { } struct External { - module @0 :Text; - function @1 :Text; + module @0 :Text; + function @1 :Text; } struct SrcSpan { diff --git a/compiler-core/src/analyse.rs b/compiler-core/src/analyse.rs index f83d8beb390..40343dcdecd 100644 --- a/compiler-core/src/analyse.rs +++ b/compiler-core/src/analyse.rs @@ -605,8 +605,12 @@ impl<'a, A> ModuleAnalyzer<'a, A> { let variant = ValueConstructorVariant::ModuleFn { documentation: doc.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), - external_erlang: external_erlang.clone().map(|(m, f, _)| (m, f)), - external_javascript: external_javascript.clone().map(|(m, f, _)| (m, f)), + external_erlang: external_erlang + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_javascript: external_javascript + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), field_map, module: environment.current_module.clone(), arity: typed_args.len(), @@ -1290,8 +1294,12 @@ impl<'a, A> ModuleAnalyzer<'a, A> { documentation: documentation.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), field_map, - external_erlang: external_erlang.clone().map(|(m, f, _)| (m, f)), - external_javascript: external_javascript.clone().map(|(m, f, _)| (m, f)), + external_erlang: external_erlang + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_javascript: external_javascript + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), module: environment.current_module.clone(), arity: args.len(), location: *location, @@ -1590,8 +1598,12 @@ fn generalise_function( documentation: doc.as_ref().map(|(_, doc)| doc.clone()), name: name.clone(), field_map, - external_erlang: external_erlang.clone().map(|(m, f, _)| (m, f)), - external_javascript: external_javascript.clone().map(|(m, f, _)| (m, f)), + external_erlang: external_erlang + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), + external_javascript: external_javascript + .as_ref() + .map(|(m, f, _)| (m.clone(), f.clone())), module: module_name.clone(), arity: args.len(), location, diff --git a/compiler-core/src/language_server/engine.rs b/compiler-core/src/language_server/engine.rs index 00f0258c211..2242b9432b6 100644 --- a/compiler-core/src/language_server/engine.rs +++ b/compiler-core/src/language_server/engine.rs @@ -175,11 +175,6 @@ where None => return Ok(None), }; - let a = - node.definition_location(this.compiler.project_compiler.get_importable_modules()); - tracing::info!("{:#?}", node); - tracing::info!("{:#?}", a); - let location = match node .definition_location(this.compiler.project_compiler.get_importable_modules()) { diff --git a/compiler-core/src/language_server/tests.rs b/compiler-core/src/language_server/tests.rs index bee4b8b02e4..92076e8ed21 100644 --- a/compiler-core/src/language_server/tests.rs +++ b/compiler-core/src/language_server/tests.rs @@ -414,11 +414,11 @@ impl<'a> TestProject<'a> { }; find_module(&self.root_package_modules) - .or(find_module(&self.dependency_modules)) - .or(find_module(&self.test_modules)) - .or(find_module(&self.hex_modules)) - .or(find_module(&self.dev_hex_modules)) - .or(find_module(&self.indirect_hex_modules)) + .or_else(|| find_module(&self.dependency_modules)) + .or_else(|| find_module(&self.test_modules)) + .or_else(|| find_module(&self.hex_modules)) + .or_else(|| find_module(&self.dev_hex_modules)) + .or_else(|| find_module(&self.indirect_hex_modules)) } pub fn add_module(mut self, name: &'a str, src: &'a str) -> Self {