castwide / solargraph

A Ruby language server.
https://solargraph.org
MIT License
1.89k stars 158 forks source link

Support for "TypeAliases" #630

Open noctux opened 1 year ago

noctux commented 1 year ago

Hello,

first off: thank you for this language-server, it makes developing in ruby a lot more bearable!

In various languages, there is the concept of TypeAliases, whereby a new, more descriptive name is attached to an prexisting type (e.g.: Yes, this is an Array, but we want to signal, that this is our ProcessList, so we give it that name; more so, if we need a more specialized list later on, we can always define ProcessList as a regular subclass to Array with custom methods - without modifying any of the constructor calls or type annotations).

The variation that seems to be occasionally used in Ruby for this seems to be to simply assign the Type to a global constant (sorry for the not super descriptive example, but I hope it suffices as a MWE):

module Foo
  class Bar
    def initialize(a)
      @a = a
    end
  end
end

module Baz
  TypeAlias = Foo::Bar

  class Booq
    def initialize
      @baz = TypeAlias.new(a)
    end

    # @return [TypeAlias]
    def method
      @baz
    end
  end
end

Unfortunately, as of now, solargraph is not happy with it:

bundle exec solargraph typecheck ./foo.rb 
<snip>/foo.rb:19 - Unresolved return type TypeAlias for Baz::Booq#method

I'm not sure whether this feature is too exotic, but I wanted to ask whether you see any value in supporting those. I hope I've not missed any preexisting issues on the topic.

Thank you for taking the time to read this issue Simon

P.S.: I know that this could be worked around by always creating the inheritance:

module Baz
    class TypeAlias < Foo::Bar end
end

But somehow, this feels a bit unelegant.

noctux commented 1 year ago

Thinking about it a tiny bit more, the explicit subclass would also not be equivalent: in that case externally provided Foo::Bar instances would not register as a "kind_of(TypeAlias)"... so support for actual aliases (aka Constants pointing to Types) would probably be required for certain usecases anyways.

castwide commented 1 year ago

Solargraph does support type aliases, but it looks like you found a bug in the type checker. The language server correctly infers Foo::Bar from TypeAlias.new:

image

...but the type checker is not making the same inference. I'll look into a solution for the next release.

noctux commented 1 year ago

Oh, nice! Thanks for looking into it!

nanachi-code commented 1 year ago

while you are at it how about adding a custom yard tag like @type_alias?