Is your feature request related to a problem? Please describe.
Go-to-definition on a code interface function (MyApp.Chat.get_room_by_slug!) lands on the defmodule line of the domain or resource, not on its define :get_room_by_slug line. Language servers read a generated function's location from the module's debug info, and every code interface function records the same one:
line: 1, file: {"deps/ash/lib/ash/code_interface.ex", N}
line is where define_interface/3 expands (the module's defmodule line, usually 1) and file is the generator (location: :keep), so nothing points at the define. Reported in remoteoss/dexter#108; Dexter's side is remoteoss/dexter#110, which uses a generated function's recorded line once it is more precise than the module's.
Describe the solution you'd like
Record the define line (from Spark.Dsl.Entity.anno/1) as the def's line, and leave everything else as it is:
line: 18, file: {"deps/ash/lib/ash/code_interface.ex", N}
The file and every line in the body stay code_interface.ex, so stacktraces don't change. Dexter #110 already reads :line when file is another module's source, so it needs no change for this.
Describe alternatives you've considered
@file {define_file, define_line} before each generated def, as suggested in dexter#108. It makes the debug info point at the define too, but it also moves the function's file for stacktraces while the body's line numbers still come from code_interface.ex (location: :keep). A crash in a generated function would then report lib/my_app/chat.ex:1150, a line in the user's domain file that has nothing to do with it, instead of today's accurate deps/ash/lib/ash/code_interface.ex:1150.
Additional context
I have a PR ready with a test: a small define_at macro wraps each generated def and evaluates it with the environment's line set to the define line. Verified end to end: with it and Dexter #110, go-to-definition on get_room_by_slug!/list_rooms! goes to chat_ash.ex:18/:16 instead of :1. The full test suite passes. Happy to adjust the approach if you'd rather have it done differently.
Is your feature request related to a problem? Please describe.
Go-to-definition on a code interface function (
MyApp.Chat.get_room_by_slug!) lands on thedefmoduleline of the domain or resource, not on itsdefine :get_room_by_slugline. Language servers read a generated function's location from the module's debug info, and every code interface function records the same one:lineis wheredefine_interface/3expands (the module'sdefmoduleline, usually 1) andfileis the generator (location: :keep), so nothing points at thedefine. Reported in remoteoss/dexter#108; Dexter's side is remoteoss/dexter#110, which uses a generated function's recorded line once it is more precise than the module's.Describe the solution you'd like
Record the
defineline (fromSpark.Dsl.Entity.anno/1) as the def's line, and leave everything else as it is:The file and every line in the body stay
code_interface.ex, so stacktraces don't change. Dexter #110 already reads:linewhenfileis another module's source, so it needs no change for this.Describe alternatives you've considered
@file {define_file, define_line}before each generated def, as suggested in dexter#108. It makes the debug info point at thedefinetoo, but it also moves the function's file for stacktraces while the body's line numbers still come fromcode_interface.ex(location: :keep). A crash in a generated function would then reportlib/my_app/chat.ex:1150, a line in the user's domain file that has nothing to do with it, instead of today's accuratedeps/ash/lib/ash/code_interface.ex:1150.Additional context
I have a PR ready with a test: a small
define_atmacro wraps each generateddefand evaluates it with the environment's line set to thedefineline. Verified end to end: with it and Dexter #110, go-to-definition onget_room_by_slug!/list_rooms!goes tochat_ash.ex:18/:16instead of:1. The full test suite passes. Happy to adjust the approach if you'd rather have it done differently.