solargraph icon indicating copy to clipboard operation
solargraph copied to clipboard

What options exist for creating metadata with references to source in different files?

Open iftheshoefritz opened this issue 3 years ago • 6 comments

I have YARD files outside of my source to document attributes that are created at runtime by some metaprogramming. This is great for autocomplete, but go-to-definition takes me to the YARD file instead of to the actual code.

I have some half-baked ideas and I'm not sure if they would work / which if any has the most merit:

  • a lens would give a clickable action that could take me to the source, but that's not going to be linked to the normal go-to-definition flow of clients (I'd be sad if this was the best option)
  • a custom YARD directive that can take a reference location in another file
  • or is there some existing YARD thing that can accomplish this?
  • a solargraph plugin

Which of these seems like a good match for what I'm trying to achieve? If there's a clear winner, any hints about what to read up on next would be appreciated.

iftheshoefritz avatar Oct 02 '20 06:10 iftheshoefritz

The best option is probably to add a custom Convention through a plugin. I'm currently working on a similar solution to improve Rails support.

The bad news is that proper convention support won't be released until version 0.40.0. The good news is that it's available in the master branch, and I hope to release 0.40.0 sometime next week.

Here's a simple example of a convention that adds a Foo class to the API map:

require 'solargraph'

class MyConvention < Solargraph::Convention::Base
  def global yard_map
    Solargraph::Environ.new(pins: parse_pins)
  end

  private

  def parse_pins
    Solargraph::SourceMap.load_string(%(
      class Foo; end
    )).pins
  end
end

Solargraph::Convention.register MyConvention

The Foo pin is generated without a filename, so it doesn't get included in go-to-definition results. That fixes half the problem. The other half is resolving a "virtual" method to a concrete class/module definition. For example, if you have Foo defined in your code and Foo#bar defined in a convention, you probably want Foo#bar's go-to-defintion to find Foo. I'm not sure of the best way to handle it. If you have any thoughts, please let me know.

You can find more examples of conventions in the lib/solargraph/convention directory.

castwide avatar Oct 02 '20 09:10 castwide

I'm currently working on a similar solution to improve Rails support.

That is my exact use case, the YARD I'm generating is based on ActiveModel attributes, and slowly working on an annotate style gem that updates Solargraph's knowledge every time rake db:migrate runs.

Will give the second part of the problem some thought!

iftheshoefritz avatar Oct 02 '20 14:10 iftheshoefritz

@castwide ~(since I assume the pins returned from parse_pins are stored in the same map as everything else in the workspace) would it be terrible if Solargraph::Location was mutable? Then we could update the location of each pin generated for a class with the actual file that defines the class?~ never mind, ignore my misunderstandings 😄

Related: what is the lifecycle of the convention? Will it be bad for startup times if the reflection to find dynamic attributes is done every time the workspace is loaded? Or is this cached by Solargraph?

iftheshoefritz avatar Oct 15 '20 06:10 iftheshoefritz

~@castwide what about something like this:~

... obsolete code deleted

This is obsolete with my latest efforts at parsing Annotate instead of loading Rails.

iftheshoefritz avatar Oct 31 '20 05:10 iftheshoefritz

I'm now thinking that it's going to be easier to parse annotate gem comments than to try load all of activerecord and establish a DB connection in a plugin. This looks pretty easy since annotate is essentially just outputting column.type or column.sql_type. And it's pretty popular in rails projects.

iftheshoefritz avatar Nov 07 '20 07:11 iftheshoefritz

Update: I have autocomplete and go-to-definition working for simple cases from a plugin that parses annotate. Soon to be released as solargraph_rails. https://github.com/iftheshoefritz/solargraph_rails

iftheshoefritz avatar Nov 09 '20 06:11 iftheshoefritz

This issue is super obsolete.

iftheshoefritz avatar Jan 06 '23 04:01 iftheshoefritz